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] Đếm số liên kết tĩnh qua các khung hàm lồng nhau

    Trong các ngôn ngữ cho phép định nghĩa HÀM LỒNG NHAU (nested functions, như Pascal), khi một hàm bên trong tham chiếu tới biến của một hàm bao ngoài, trình biên dịch phải phát sinh mã truy cập qua CHUỖI LIÊN KẾT TĨNH (static link) — mỗi liên kết dẫn tới bản ghi kích hoạt (activation record) của một hàm bao ngoài. Số liên kết cần đi qua phụ thuộc vào số HÀM (không phải số khối lệnh thường) mà ta phải "thoát ra" để đến được nơi biến đó được khai báo.

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

    • FUNC <ten>: mở một phạm vi HÀM mới lồng vào phạm vi hiện tại (<ten> chỉ mang tính minh hoạ, không ảnh hưởng xử lý). Đây LÀ một khung (frame) hàm mới.
    • BLOCK: mở một phạm vi KHỐI thường (ví dụ thân một câu lệnh if/for) lồng vào phạm vi hiện tại. Khối này KHÔNG tạo khung hàm mới — nó dùng chung khung hàm với phạm vi bao trực tiếp nó.
    • END: đóng phạm vi trong cùng hiện tại (dù là FUNC hay BLOCK), quay về phạm vi bao ngoài.
    • DECL <ten>: khai báo biến <ten> trong phạm vi hiện tại (dù đó là phạm vi hàm hay phạm vi khối).
    • LINK <ten>: truy vấn — coi như đang thực thi tại vị trí này, cần tìm biến <ten> bằng cách tìm trong phạm vi hiện tại, rồi lần lượt ra các phạm vi bao ngoài (theo đúng quy tắc phạm vi tĩnh, không phân biệt khối hay hàm khi tìm kiếm). Gọi FFF là số khung HÀM (không tính khối) tính từ phạm vi hiện tại ra đến phạm vi chứa khai báo tìm được (phạm vi toàn cục được coi là khung hàm gốc, mức 000; mỗi lần vào FUNC mức khung tăng thêm 111, BLOCK giữ nguyên mức khung của phạm vi bao nó). In ra FFF — chính là số liên kết tĩnh cần đi qua. Nếu không tìm thấy <ten> ở bất kỳ phạm vi bao nào, in UNDECLARED.

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

    7
    DECL g
    FUNC f1
    DECL a
    FUNC f2
    LINK a
    LINK g
    LINK z
    

    Biến g ở phạm vi toàn cục (mức khung 000). Hàm f1 là khung mức 111, khai báo a. Hàm f2 lồng trong f1 là khung mức 222. Từ trong f2: LINK a tìm thấy a ở khung mức 111 ⟹ cần vượt qua 2−1=12-1=12−1=1 liên kết; LINK g tìm thấy g ở khung mức 000 ⟹ cần 2−0=22-0=22−0=2 liên kết; LINK z không tìm thấy đâu cả. Kết quả:

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

      Dòng đầu chứa số nguyên nnn (0≤n≤30000 \le n \le 30000≤n≤3000) — số lệnh. nnn dòng tiếp theo, mỗi dòng là một trong năm dạng: FUNC <ten>, BLOCK, END, DECL <ten>, LINK <ten>. Dữ liệu đảm bảo số lệnh END không vượt quá số phạm vi (FUNC/BLOCK) chưa đóng tương ứng, và luôn có sẵn phạm vi toàn cục (mức khung 000) không cần mở bằng lệnh nào.

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

      Với mỗi lệnh LINK, in một dòng chứa số nguyên FFF hoặc chuỗi UNDECLARED, theo đúng thứ tự các lệnh LINK xuất hiện. Nếu không có lệnh LINK nào, không in gì.

    Ví dụ:

    Đầu vào:

    0
    

    Đầu ra:

    Đầu vào:

    4
    DECL x
    FUNC f1
    LINK x
    END
    

    Đầu ra:

    1
    

    Đang tải editor...