Các lượt nộp
    Danh sách bài
    Trang chủ
    Báo lỗi

    solution

    Đề bài: [Trình biên dịch] Kiểm tra kiểu biểu thức hậu tố với ép kiểu ngầm định

    Một trong những nhiệm vụ chính của phân tích ngữ nghĩa là kiểm tra và suy diễn kiểu (type checking) cho các biểu thức, áp dụng quy tắc ép kiểu ngầm định (implicit type promotion) khi các toán hạng có kiểu khác nhau.

    Cho một tập biến đã khai báo, mỗi biến có kiểu int hoặc float. Cho một biểu thức viết dưới dạng hậu tố (postfix / Reverse Polish Notation), các token cách nhau bởi khoảng trắng, gồm:

    • hằng số nguyên: chỉ gồm chữ số (có thể có dấu - ở đầu), ví dụ 3, -7;
    • hằng số thực: chứa dấu chấm ., ví dụ 2.5, -0.5;
    • tên biến đã khai báo;
    • toán tử hai ngôi thuộc {+,−,∗,/}\{+, -, *, /\}{+,−,∗,/}.

    Quy tắc suy diễn kiểu cho một toán tử hai ngôi với hai toán hạng có kiểu t1,t2t_1, t_2t1​,t2​: nếu t1=floatt_1 = \text{float}t1​=float hoặc t2=floatt_2 = \text{float}t2​=float thì kết quả có kiểu float; ngược lại (cả hai đều int) kết quả có kiểu int (kể cả với phép chia — chia hai số int vẫn cho kiểu int, tương tự phép chia lấy phần nguyên trong C/C++).

    Ví dụ

    Input:

    2
    a:int b:float
    a b +
    

    Output:

    float
    

    Giải thích: a kiểu int, b kiểu float; a + b cho kết quả kiểu float do quy tắc ép kiểu.

    • Định dạng đầu vào:

      Dòng 1: số nguyên kkk (0≤k≤1000 \le k \le 1000≤k≤100) — số biến được khai báo. Dòng 2: nếu k>0k>0k>0, gồm kkk cặp name:type cách nhau bởi khoảng trắng (type là int hoặc float); nếu k=0k=0k=0 đây là dòng rỗng. Dòng 3: biểu thức hậu tố, các token cách nhau bởi khoảng trắng. Dữ liệu vào đảm bảo biểu thức có cấu trúc hậu tố hợp lệ (đủ toán hạng cho mỗi toán tử).

    • Định dạng đầu ra:

      Nếu trong quá trình duyệt gặp một token là tên biến chưa được khai báo, in ra đúng một dòng ERROR: bien <name> chua khai bao (dừng ngay khi gặp lỗi đầu tiên, không xét tiếp các token sau) và không in gì khác. Ngược lại, in ra đúng một dòng là kiểu của kết quả cuối cùng: int hoặc float.

    Ví dụ:

    Đầu vào:

    2
    a:int b:float
    a b +
    

    Đầu ra:

    float
    

    Đầu vào:

    2
    a:int b:int
    a b + a b - *
    

    Đầu ra:

    int
    

    Đang tải editor...