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] Tra cứu biến theo phạm vi tĩnh

    Trình biên dịch xử lý tuần tự các lệnh:

    • BEGIN: mở một phạm vi mới lồng vào phạm vi hiện tại (phạm vi toàn cục có độ sâu 000; mỗi lệnh BEGIN làm độ sâu tăng thêm 111).
    • END: đóng phạm vi trong cùng hiện tại, quay về phạm vi cha (độ sâu giảm đi 111).
    • DECL <ten> <kieu>: khai báo biến <ten> với kiểu dữ liệu <kieu> (một chuỗi không chứa khoảng trắng, ví dụ int, float, bool, string) trong phạm vi hiện tại. Nếu <ten> đã tồn tại trong CHÍNH phạm vi hiện tại, khai báo mới sẽ GHI ĐÈ kiểu cũ (khai báo sau có hiệu lực).
    • USE <ten>: tham chiếu tới biến <ten>. Trình biên dịch tìm <ten> bắt đầu từ phạm vi hiện tại, nếu không thấy thì tìm dần ra các phạm vi cha, ông, ... cho tới phạm vi toàn cục (đây chính là quy tắc phạm vi tĩnh — static/lexical scoping: biến ở phạm vi gần nhất được ưu tiên, có thể che khuất biến cùng tên ở phạm vi ngoài).

    Với mỗi lệnh USE <ten>, hãy in ra kết quả tra cứu:

    • Nếu tìm thấy biến ở phạm vi có độ sâu ddd với kiểu <kieu>, in ra chuỗi <kieu>@<d> (không có khoảng trắng, nối trực tiếp bằng ký tự @).
    • Nếu không tìm thấy ở bất kỳ phạm vi nào, in ra UNDEFINED.

    Ví dụ: với dữ liệu

    6
    DECL x int
    BEGIN
    USE x
    DECL x string
    USE x
    END
    

    Kết quả là:

    int@0
    string@1
    

    (lệnh USE x đầu tiên ở độ sâu 111 chưa có x cục bộ nên tìm ra x ở phạm vi toàn cục — độ sâu 000, kiểu int; lệnh USE x thứ hai tìm thấy ngay x vừa khai báo cục bộ ở độ sâu 111, kiểu string, che khuất biến x toàn cục).

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

      Dòng đầu chứa số nguyên nnn (0≤n≤20000 \le n \le 20000≤n≤2000) — số lệnh. nnn dòng tiếp theo, mỗi dòng là một trong bốn dạng lệnh: BEGIN, END, DECL <ten> <kieu>, USE <ten>. Dữ liệu đảm bảo số lệnh END không vượt quá số BEGIN chưa đóng tương ứng.

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

      Với mỗi lệnh USE, in ra một dòng kết quả tra cứu theo định dạng <kieu>@<do_sau> hoặc UNDEFINED, theo đúng thứ tự xuất hiện của các lệnh USE trong dữ liệu vào. Nếu không có lệnh USE nào, không in gì.

    Ví dụ:

    Đầu vào:

    0
    

    Đầu ra:

    Đầu vào:

    3
    USE x
    DECL x int
    USE x
    

    Đầu ra:

    UNDEFINED
    int@0
    

    Đang tải editor...