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] Xung đột mới phát sinh khi gộp trạng thái LALR(1)

    Bộ phân tích LALR(1) được xây dựng bằng cách gộp các trạng thái của tự động hóa LR(1) chính tắc có cùng lõi (core — tập mục bỏ qua ký hiệu nhìn trước), rồi hợp (union) các tập ký hiệu nhìn trước tương ứng với từng mục. Việc gộp này giúp giảm đáng kể số trạng thái so với LR(1) chính tắc, nhưng có thể sinh ra xung đột reduce-reduce mới — xung đột không tồn tại ở bất kỳ trạng thái LR(1) gốc nào trước khi gộp, mà chỉ xuất hiện sau khi hợp các tập nhìn trước lại với nhau. Đây là điểm yếu kinh điển của LALR(1) so với LR(1).

    Đề bài cho sẵn (không cần xây dựng từ văn phạm) một số trạng thái LR(1), mỗi trạng thái gồm một số mục rút gọn (reduce item), mỗi mục xác định bởi số hiệu luật sinh và tập ký hiệu nhìn trước hợp lệ để rút gọn theo luật đó tại trạng thái này. Mỗi trạng thái có kèm một mã lõi (core) — hai trạng thái có cùng mã lõi sẽ được gộp lại thành một trạng thái LALR(1).

    Tại một trạng thái (LR(1) gốc hoặc LALR(1) sau gộp), có xung đột reduce-reduce nếu tồn tại một ký hiệu nhìn trước được "đòi" rút gọn bởi từ hai luật sinh khác nhau.

    Hãy xác định: (1) tổng số trạng thái LALR(1) sau khi gộp (số mã lõi phân biệt); (2) trong số đó, có bao nhiêu trạng thái LALR(1) có xung đột reduce-reduce; (3) trong số các trạng thái có xung đột đó, có bao nhiêu trạng thái mà xung đột này là mới hoàn toàn — tức là không một trạng thái LR(1) gốc nào (thuộc nhóm được gộp vào đó) tự nó đã có xung đột reduce-reduce từ trước.

    Ví dụ kinh điển: hai trạng thái LR(1) cùng lõi, trạng thái thứ nhất có mục rút gọn theo luật 10 với nhìn trước {d} và luật 11 với nhìn trước {e} (không xung đột); trạng thái thứ hai có luật 10 với nhìn trước {e} và luật 11 với nhìn trước {d} (cũng không xung đột). Sau khi gộp, luật 10 và luật 11 đều có nhìn trước {d, e} ⇒\Rightarrow⇒ xung đột reduce-reduce mới phát sinh. Kết quả: 1 trạng thái LALR(1), 1 trạng thái có xung đột, 1 xung đột mới.

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

      Dòng 1: số nguyên kkk — số trạng thái LR(1) cho trước. Với mỗi trạng thái (kkk nhóm dữ liệu liên tiếp):

      • Một dòng core m: core là mã lõi (số nguyên), m là số mục rút gọn trong trạng thái này.
      • mmm dòng tiếp theo, mỗi dòng dạng prod L t1 t2 ... tL: prod là số hiệu luật sinh, LLL là số ký hiệu nhìn trước, và t1…tLt_1 \ldots t_Lt1​…tL​ là các ký hiệu nhìn trước đó (có thể xem như một tập hợp, không có phần tử trùng lặp trong cùng một mục).
    • Định dạng đầu ra:

      In ra đúng 3 dòng số nguyên: Dòng 1: tổng số trạng thái LALR(1) (số mã lõi phân biệt). Dòng 2: số trạng thái LALR(1) có xung đột reduce-reduce. Dòng 3: số trạng thái LALR(1) có xung đột reduce-reduce mới hoàn toàn phát sinh do gộp (không tồn tại ở bất kỳ trạng thái LR(1) gốc riêng lẻ nào của nhóm đó).

    Ví dụ:

    Đầu vào:

    2
    1 2
    1 2 a b
    2 1 b
    1 2
    1 1 c
    2 1 d

    Đầu ra:

    1
    1
    0
    

    Đầu vào:

    2
    5 2
    10 1 d
    11 1 e
    5 2
    10 1 e
    11 1 d

    Đầu ra:

    1
    1
    1
    

    Đang tải editor...