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] Cấp phát offset trong bảng ký hiệu có căn lề

    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=0off = 0off=0. Với mỗi biến theo đúng thứ tự khai báo, gọi aaa 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 aaa mà không nhỏ hơn offoffoff 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+sizeoff \leftarrow offset\_gán + sizeoff←offset_gaˊn+size.

    Sau khi cấp phát xong toàn bộ nnn biến, kích thước khung (frame size) là bội số nhỏ nhất của max⁡(alignment)\max(\text{alignment})max(alignment) trong số tất cả các biến, không nhỏ hơn offoffoff cuối cùng. Nếu n=0n=0n=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.

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

      Dòng đầu tiên chứa số nguyên nnn (0≤n≤10000 \le n \le 10000≤n≤1000) — số biến. nnn dòng tiếp theo, mỗi dòng có dạng name type với type ∈\in∈ {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.

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

      In nnn 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...