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] Tính offset bản ghi qua thuộc tính kế thừa và tổng hợp

    Trình biên dịch cấp phát bộ nhớ cho một bản ghi (struct) bằng một SDD (syntax-directed definition) trong đó mỗi trường có một thuộc tính tổng hợp (synthesized) width (kích thước) và nhận một thuộc tính kế thừa (inherited) offset (vị trí bắt đầu của trường, tính từ đầu bản ghi), được cập nhật tuần tự: offset của trường sau bằng offset của trường trước cộng width của nó, có làm tròn lên theo yêu cầu căn lề (alignment).

    Cho nnn trường theo đúng thứ tự khai báo, mỗi trường có kiểu cơ sở thuộc {char,short,int,long}\{\text{char}, \text{short}, \text{int}, \text{long}\}{char,short,int,long} với (kích thước, căn lề) tương ứng là (1,1),(2,2),(4,4),(8,8)(1,1), (2,2), (4,4), (8,8)(1,1),(2,2),(4,4),(8,8) byte, hoặc là một mảng của kiểu cơ sở gồm kkk phần tử liên tiếp (kích thước =k×= k \times=k× kích thước phần tử, căn lề === căn lề phần tử, không đổi).

    Quy tắc cấp phát: gọi ppp là con trỏ cấp phát hiện tại (khởi đầu p=0p=0p=0). Trường có yêu cầu căn lề aaa được đặt tại offset =⌈p/a⌉×a= \lceil p / a \rceil \times a=⌈p/a⌉×a (chèn padding nếu cần), sau đó p←offset+widthp \leftarrow \text{offset} + \text{width}p←offset+width. Sau khi cấp phát hết nnn trường, tổng kích thước bản ghi (bao gồm tail padding) được làm tròn lên theo bội số của căn lề lớn nhất trong toàn bộ bản ghi: SIZE=⌈p/amax⁡⌉×amax⁡\text{SIZE} = \lceil p / a_{\max} \rceil \times a_{\max}SIZE=⌈p/amax​⌉×amax​.

    Ví dụ với 4 trường a:char, b:int, c:char[3], d:long: a tại offset 0 (p=1); b cần căn lề 4 nên offset 4 (p=8); c (kích thước 3, căn lề 1) tại offset 8 (p=11); d cần căn lề 8 nên offset 16 (p=24); căn lề lớn nhất là 8 nên SIZE =24=24=24.

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

      Dòng đầu chứa nnn (1≤n≤5001 \le n \le 5001≤n≤500). nnn dòng tiếp theo, mỗi dòng dạng <name> <basetype> hoặc <name> <basetype>[<k>] (1≤k≤10001 \le k \le 10001≤k≤1000), basetype ∈{\in \{∈{char, short, int, long}\}}.

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

      In nnn dòng <name> <offset> theo đúng thứ tự khai báo, sau đó một dòng cuối SIZE <total> là tổng kích thước bản ghi đã gồm tail padding.

    Ví dụ:

    Đầu vào:

    4
    a char
    b int
    c char[3]
    d long
    

    Đầu ra:

    a 0
    b 4
    c 8
    d 16
    SIZE 24
    

    Đầu vào:

    1
    x char
    

    Đầu ra:

    x 0
    SIZE 1
    

    Đang tải editor...