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) và đồng thời cấp phát địa chỉ (offset) cho từng biến trong bộ nhớ. Xét một phạm vi (scope) toàn cục duy nhất, các biến được cấp phát địa chỉ liên tiếp, không có phần đệm căn lề (packed layout): biến khai báo đầu tiên có địa chỉ 0; biến khai báo kế tiếp có địa chỉ bằng địa chỉ của biến trước đó cộng với kích thước (byte) của biến trước đó.
Kích thước các kiểu dữ liệu: int = 4 byte, char = 1 byte, double = 8 byte, bool = 1 byte.
Bạn cần mô phỏng một trình xử lý lệnh trên bảng ký hiệu, hỗ trợ hai loại lệnh:
DECL <name> <type>: khai báo biến name kiểu type. Nếu name đã được khai báo trước đó, đây là lỗi khai báo trùng.ADDR <name>: truy vấn địa chỉ hiện tại của biến name.Ví dụ
Input:
5
DECL x int
DECL y char
ADDR x
ADDR y
ADDR z
Output:
x 0
y 4
ERROR: z chua duoc khai bao
Giải thích: x kiểu int được cấp địa chỉ 0 (kích thước 4 byte); y kiểu char được cấp địa chỉ 0+4=4; biến z chưa từng được khai báo nên lệnh ADDR z báo lỗi.
Dòng đầu tiên chứa số nguyên n (0≤n≤1000) là số lệnh. n dòng tiếp theo, mỗi dòng là một lệnh có một trong hai dạng:
DECL <name> <type> với type ∈ {int, char, double, bool}ADDR <name>
<name> là một chuỗi không chứa khoảng trắng.Với mỗi lệnh DECL: nếu name đã tồn tại trong bảng ký hiệu, in ra đúng dòng ERROR: <name> da duoc khai bao; nếu khai báo thành công thì KHÔNG in gì.
Với mỗi lệnh ADDR: nếu name đã được khai báo, in ra <name> <address> (cách nhau một khoảng trắng); nếu chưa được khai báo, in ra ERROR: <name> chua duoc khai bao.
Các dòng output được in theo đúng thứ tự các lệnh tương ứng xuất hiện trong input.
Ví dụ:
Đầu vào:
0
Đầu ra:
Đầu vào:
5
DECL x int
DECL y char
ADDR x
ADDR y
ADDR z
Đầu ra:
x 0
y 4
ERROR: z chua duoc khai bao
Đang tải editor...