Trong giai đoạn phân tích ngữ nghĩa, trình biên dịch xây dựng bảng ký hiệu (Symbol Table) cho các biến cục bộ của một hàm và tính offset (địa chỉ tương đối trong khung ngăn xếp — stack frame) cho từng biến.
Cho một dãy khai báo biến theo đúng thứ tự xuất hiện trong mã nguồn. Mỗi biến có một kiểu dữ liệu xác định kích thước (byte) và độ căn lề (alignment) như sau:
| Kiểu | size (byte) | alignment |
|---|---|---|
| char | 1 | 1 |
| bool | 1 | 1 |
| int | 4 | 4 |
| double | 8 | 8 |
Bộ cấp phát offset hoạt động tuần tự: bắt đầu tại vị trí trống off=0. Với mỗi biến theo đúng thứ tự khai báo, gọi a là alignment của kiểu biến đó — offset thực sự gán cho biến là bội số nhỏ nhất của a mà không nhỏ hơn off hiện tại (nếu cần, chèn phần đệm — padding). Sau khi gán, cập nhật off←offset_gaˊn+size.
Sau khi cấp phát xong toàn bộ n biến, kích thước khung (frame size) là bội số nhỏ nhất của max(alignment) trong số tất cả các biến, không nhỏ hơn off cuối cùng. Nếu n=0, frame size bằng 0.
Ví dụ: với 3 biến a char, b int, c double theo thứ tự: a được offset 0 (size 1, next=1); b cần bội của 4 không nhỏ hơn 1 → offset 4 (size 4, next=8); c cần bội của 8 không nhỏ hơn 8 → offset 8 (size 8, next=16); alignment lớn nhất là 8, và 16 đã là bội của 8 nên frame size = 16.
Dòng đầu tiên chứa số nguyên n (0≤n≤1000) — số biến.
n dòng tiếp theo, mỗi dòng có dạng name type với type ∈ {char, bool, int, double}. Tên biến là chuỗi gồm chữ cái/số/_, không bắt đầu bằng số, độ dài không quá 30, các tên là duy nhất.
In n dòng theo đúng thứ tự khai báo, mỗi dòng name offset.
Dòng cuối cùng in TOTAL total_size — kích thước khung ngăn xếp.
Ví dụ với input ở trên, output là:
a 0
b 4
c 8
TOTAL 16
Ví dụ:
Đầu vào:
3
a char
b int
c double
Đầu ra:
a 0
b 4
c 8
TOTAL 16
Đầu vào:
0
Đầu ra:
TOTAL 0
Đang tải editor...