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] Phân giải tên qua cây phạm vi tĩnh

    Khác với việc mô phỏng một chương trình đang chạy tuần tự qua các lệnh BEGIN/END, bài này cho trước TRỰC TIẾP cấu trúc cây phạm vi (scope tree) mà trình biên dịch đã dựng sẵn khi phân tích cú pháp — giống như cách một trình biên dịch thực sự gắn một bảng ký hiệu cho mỗi nút trong cây cú pháp trừu tượng (AST).

    Có mmm phạm vi, đánh số từ 111 đến mmm. Phạm vi 111 là phạm vi TOÀN CỤC (không có phạm vi cha). Với mỗi phạm vi iii từ 222 đến mmm, cho biết pip_ipi​ (1≤pi<i1 \le p_i < i1≤pi​<i) là phạm vi CHA trực tiếp của phạm vi iii (một phạm vi có thể có nhiều phạm vi con — ví dụ hai khối if và else cùng lồng trong một khối cha sẽ là hai phạm vi con, không phải cha con của nhau).

    Cho kkk khai báo biến, mỗi khai báo có dạng <scope_id> <ten> <kieu> nghĩa là trong phạm vi <scope_id>, biến <ten> được khai báo với kiểu <kieu>. Dữ liệu đảm bảo trong cùng một phạm vi, mỗi tên biến chỉ được khai báo tối đa một lần.

    Cho qqq truy vấn, mỗi truy vấn có dạng <scope_id> <ten>: hãy phân giải tên <ten> NHÌN TỪ phạm vi <scope_id> — tìm <ten> trong chính phạm vi đó, nếu không có thì tìm tiếp ở phạm vi cha, ông, ... lên đến phạm vi toàn cục. In ra kiểu <kieu> tìm được, hoặc UNDECLARED nếu không tìm thấy ở bất kỳ phạm vi nào trên đường đi lên gốc.

    Ví dụ: với m=4m = 4m=4, dãy cha p2 p3 p4=1 1 3p_2\ p_3\ p_4 = 1\ 1\ 3p2​ p3​ p4​=1 1 3 (phạm vi 222 và 333 đều con của 111; phạm vi 444 là con của 333), khai báo 1 g int và 3 a bool, truy vấn 3 g (đi lên 3→13 \to 13→1, tìm thấy g ở gốc) trả về int; truy vấn 2 a (đi lên 2→12 \to 12→1, không có phạm vi 333 trên đường đi) trả về UNDECLARED vì a chỉ tồn tại trong phạm vi 333, không phải tổ tiên của phạm vi 222.

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

      Dòng 1: số nguyên mmm (1≤m≤20001 \le m \le 20001≤m≤2000). Dòng 2: m−1m-1m−1 số nguyên p2,p3,…,pmp_2, p_3, \ldots, p_mp2​,p3​,…,pm​ cách nhau bởi khoảng trắng (dòng này có thể trống nếu m=1m = 1m=1). Dòng 3: số nguyên kkk (0≤k≤50000 \le k \le 50000≤k≤5000). kkk dòng tiếp theo, mỗi dòng <scope_id> <ten> <kieu>. Dòng tiếp theo: số nguyên qqq (0≤q≤50000 \le q \le 50000≤q≤5000). qqq dòng tiếp theo, mỗi dòng <scope_id> <ten>.

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

      Với mỗi truy vấn, in một dòng là kiểu dữ liệu tìm được hoặc UNDECLARED, theo đúng thứ tự truy vấn. Nếu q=0q = 0q=0, không in gì.

    Ví dụ:

    Đầu vào:

    3
    1 1
    2
    1 x int
    2 y float
    2
    2 x
    1 y
    

    Đầu ra:

    int
    UNDECLARED
    

    Đầu vào:

    1
    
    0
    0
    

    Đầu ra:

    Đang tải editor...