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] Ngữ nghĩa mảng: cấp phát offset và kiểm tra chỉ số biên dịch

    Chương trình (một phạm vi duy nhất, không lồng nhau) được biểu diễn bằng dãy mmm lệnh xử lý tuần tự theo đúng thứ tự dòng, mỗi lệnh thuộc một trong hai dạng:

    • DECL type name len: khai báo mảng name gồm len phần tử kiểu type (type∈type \intype∈ {char, int, double}, kích thước phần tử tương ứng 1, 4, 8 byte). Bộ cấp phát offset hoạt động tuần tự dùng một con trỏ offoffoff dùng chung cho toàn bộ chương trình (bắt đầu off=0off=0off=0): gọi sss là kích thước phần tử của type; offset gán cho mảng là bội số nhỏ nhất của sss không nhỏ hơn offoffoff hiện tại (chèn đệm nếu cần); sau đó cập nhật off←offset_gaˊn+s×lenoff \leftarrow \text{offset\_gán} + s \times \text{len}off←offset_gaˊn+s×len. Giả thiết tên mảng khi khai báo luôn khác các tên đã khai báo trước đó (không cần xử lý trùng tên).
    • INDEX name idx: kiểm tra ngữ nghĩa của việc truy cập phần tử name[idx] tại đúng thời điểm này (dùng trạng thái bảng ký hiệu hiện có, tức chỉ các DECL đã xử lý trước đó theo thứ tự dòng mới có hiệu lực):
      • nếu name chưa từng được DECL tính đến dòng này → báo UNDECLARED;
      • ngược lại, nếu idx (số nguyên, có thể âm) nằm ngoài đoạn [0,len−1][0, len-1][0,len−1] của mảng đó → báo OUT_OF_BOUNDS;
      • ngược lại, hợp lệ: địa chỉ tuyệt đối của phần tử là offset_mảng+idx×s\text{offset\_mảng} + idx \times soffset_mảng+idx×s (với sss là kích thước phần tử) → báo OK addr.

    Ví dụ: DECL int a 3 (offset 0, size 4×3=124\times3=124×3=12, off=12off=12off=12); INDEX a 0 → hợp lệ, addr =0+0×4=0=0+0 \times 4=0=0+0×4=0 → a OK 0; INDEX a 5 → 5∉[0,2]5 \notin [0,2]5∈/[0,2] → a OUT_OF_BOUNDS; INDEX b 0 — b chưa được khai báo tại thời điểm này → b UNDECLARED; DECL double b 2 (yêu cầu offset là bội của 8 không nhỏ hơn 12, tức 16; offoffoff mới =16+16=32=16+16=32=16+16=32).

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

      Dòng đầu tiên chứa số nguyên mmm (0≤m≤20000 \le m \le 20000≤m≤2000) — số lệnh. mmm dòng tiếp theo, mỗi dòng là một trong hai dạng lệnh trên (các tham số cách nhau đúng một khoảng trắng); len và idx là số nguyên (1≤len≤1061 \le len \le 10^61≤len≤106, −106≤idx≤106-10^6 \le idx \le 10^6−106≤idx≤106).

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

      In đúng số dòng bằng số lệnh INDEX xuất hiện trong input, theo thứ tự xuất hiện, mỗi dòng là một trong ba dạng: name OK addr, name OUT_OF_BOUNDS, name UNDECLARED.

      Ví dụ với input nêu trên (5 lệnh, 3 lệnh INDEX), output là:

      a OK 0
      a OUT_OF_BOUNDS
      b UNDECLARED
      

    Ví dụ:

    Đầu vào:

    0

    Đầu ra:

    
    

    Đầu vào:

    5
    DECL int a 3
    INDEX a 0
    INDEX a 5
    INDEX b 0
    DECL double b 2

    Đầu ra:

    a OK 0
    a OUT_OF_BOUNDS
    b UNDECLARED
    

    Đang tải editor...