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 địa chỉ theo khung ngăn xếp phạm vi

    Nhiều trình biên dịch cho ngôn ngữ có cấu trúc khối (block-structured) như Pascal cấp phát bộ nhớ cho biến cục bộ theo nguyên tắc NGĂN XẾP: các phạm vi (khối) không hoạt động đồng thời có thể DÙNG CHUNG cùng một vùng địa chỉ, vì tại một thời điểm chỉ có tối đa một trong số các khối anh em (sibling) đó đang thực thi.

    Cho một dãy lệnh:

    • BEGIN: mở một phạm vi con mới; phạm vi con này BẮT ĐẦU cấp phát từ đúng vị trí (offset) hiện tại của phạm vi cha (tức là dùng lại phần bộ nhớ "còn trống" phía sau những gì phạm vi cha đã cấp phát tính đến thời điểm này).
    • END: đóng phạm vi con hiện tại. Bộ đếm offset của phạm vi cha KHÔNG bị ảnh hưởng bởi những gì phạm vi con vừa đóng đã cấp phát (toàn bộ vùng nhớ mà phạm vi con dùng được giải phóng, sẵn sàng cho phạm vi anh em tiếp theo tái sử dụng).
    • DECL <ten> <size>: khai báo biến <ten> cần <size> byte (1≤size≤1061 \le \text{size} \le 10^61≤size≤106) trong phạm vi hiện tại. Biến được cấp phát tại địa chỉ (offset) bằng giá trị bộ đếm hiện tại của phạm vi đó, sau đó bộ đếm của phạm vi đó tăng thêm <size>.

    Phạm vi toàn cục có bộ đếm offset khởi tạo bằng 000 và không bao giờ bị đóng.

    Với mỗi lệnh DECL, hãy in ra tên biến và địa chỉ (offset) mà nó được cấp phát, theo đúng thứ tự các lệnh DECL xuất hiện.

    Ví dụ: với dữ liệu

    5
    DECL x 4
    BEGIN
    DECL y 8
    END
    DECL z 4
    

    x được cấp phát ở offset 0 (chiếm 4 byte, offset toàn cục tăng lên 4). Sau đó một phạm vi con mở ra, KẾ THỪA offset hiện tại của phạm vi cha là 4, nên y được cấp phát ở offset 4. Khi phạm vi con đóng lại, offset của phạm vi toàn cục KHÔNG đổi (vẫn là 4, không cộng dồn phần mà y đã dùng), nên z — khai báo sau đó ở phạm vi toàn cục — được cấp phát lại đúng ở offset 4 (tái sử dụng vùng nhớ mà y từng chiếm). Kết quả:

    x 0
    y 4
    z 4
    
    • Định dạng đầu vào:

      Dòng đầu chứa số nguyên nnn (0≤n≤20000 \le n \le 20000≤n≤2000) — số lệnh. nnn dòng tiếp theo, mỗi dòng là BEGIN, END, hoặc DECL <ten> <size> (<ten> là chuỗi chữ cái thường/số bắt đầu bằng chữ cái, <size> là số nguyên dương). Dữ liệu đảm bảo số lệnh END không vượt quá số BEGIN chưa đóng tương ứng.

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

      Với mỗi lệnh DECL, in một dòng <ten> <offset> (cách nhau đúng một khoảng trắng), theo đúng thứ tự xuất hiện. Nếu không có lệnh DECL nào, không in gì.

    Ví dụ:

    Đầu vào:

    0
    

    Đầu ra:

    Đầu vào:

    3
    DECL a 4
    DECL b 8
    DECL c 4
    

    Đầu ra:

    a 0
    b 4
    c 12
    

    Đang tải editor...