Khi sinh mã cho một khung ngăn xếp (stack frame), trình biên dịch cấp cho mỗi biến cục bộ một offset (độ lệch bộ nhớ so với đáy khung), và khi một khối lệnh kết thúc, vùng nhớ dành cho các biến khai báo trực tiếp bên trong khối đó (và các khối con của nó) có thể được thu hồi để tái sử dụng cho các khối anh em mở ra sau này — đây là kỹ thuật tiết kiệm bộ nhớ khung ngăn xếp dựa trên phạm vi tĩnh.
Gọi offset là một con trỏ (ban đầu bằng 0) theo dõi vị trí cấp phát tiếp theo. Cho n lệnh thuộc ba dạng:
BEGIN: mở một khối con; lưu lại giá trị offset hiện tại để khôi phục khi khối này đóng lại;END: đóng khối con đang mở gần nhất; khôi phục offset về đúng giá trị đã lưu khi khối đó được mở (giải phóng toàn bộ bộ nhớ đã cấp bên trong khối vừa đóng); dữ liệu vào đảm bảo không đóng khối gốc;DECL x s: khai báo biến x có kích thước s byte (s nguyên dương) tại khối đang mở; biến này được cấp phát tại vị trí offset hiện tại, sau đó offset tăng thêm s.Với mỗi lệnh DECL, hãy in ra offset được cấp cho biến đó (theo đúng thứ tự các lệnh DECL xuất hiện trong input). Sau tất cả, in thêm một dòng cuối cùng là kích thước khung ngăn xếp lớn nhất từng đạt tới trong suốt quá trình thực hiện, tức giá trị lớn nhất mà offset từng nhận được (peak) sau bất kỳ lệnh DECL nào; nếu không có lệnh DECL nào, giá trị này bằng 0.
Ví dụ: với các lệnh DECL a 4, BEGIN, DECL b 8, DECL c 4, END, DECL d 4, DECL e 8: a nhận offset 0 (offset→4); b nhận 4 (offset→12); c nhận 12 (offset→16, peak=16); END khôi phục offset về 4; d nhận 4 (offset→8); e nhận 8 (offset→16). Kết quả in ra 6 dòng: 0 4 12 4 8 16.
Dòng đầu tiên chứa số nguyên n (0≤n≤2000). n dòng tiếp theo là các lệnh BEGIN, END, hoặc DECL x s (với x là tên biến, s là số nguyên dương).
Mỗi lệnh DECL in ra một dòng chứa offset được cấp (theo đúng thứ tự xuất hiện), sau đó in thêm một dòng cuối cùng là kích thước khung ngăn xếp lớn nhất (peak offset).
Ví dụ:
Đầu vào:
0
Đầu ra:
0
Đầu vào:
7
DECL a 4
BEGIN
DECL b 8
DECL c 4
END
DECL d 4
DECL e 8
Đầu ra:
0
4
12
4
8
16
Đang tải editor...