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 F 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 0; mỗi lần vào FUNC mức khung tăng thêm 1, BLOCK giữ nguyên mức khung của phạm vi bao nó). In ra F — 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 0). Hàm f1 là khung mức 1, khai báo a. Hàm f2 lồng trong f1 là khung mức 2. Từ trong f2: LINK a tìm thấy a ở khung mức 1 ⟹ cần vượt qua 2−1=1 liên kết; LINK g tìm thấy g ở khung mức 0 ⟹ cần 2−0=2 liên kết; LINK z không tìm thấy đâu cả. Kết quả:
1
2
UNDECLARED
Dòng đầu chứa số nguyên n (0≤n≤3000) — số lệnh. n 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 0) không cần mở bằng lệnh nào.
Với mỗi lệnh LINK, in một dòng chứa số nguyên F 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...