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] Hợp nhất trạng thái LALR(1) và phát hiện xung đột reduce/reduce

    Automat LALR(1) được xây dựng từ automat LR(1) chính tắc bằng cách hợp nhất (merge) các trạng thái có cùng "lõi" (core) — tức cùng tập mục LR(0) khi bỏ qua lookahead — thành một trạng thái duy nhất, với tập lookahead của mỗi mục là hợp các tập lookahead tương ứng từ các trạng thái được hợp nhất.

    Việc hợp nhất này đôi khi làm xuất hiện xung đột reduce/reduce mới vốn không tồn tại ở từng trạng thái LR(1) riêng lẻ: nếu sau khi hợp nhất, có hai mục đầy đủ (dạng A→α⋅A \to \alpha \cdotA→α⋅) thuộc hai sản xuất khác nhau mà tập lookahead (đã hợp) của chúng giao nhau khác rỗng, đó là một xung đột reduce/reduce của automat LALR(1) (dù trước khi hợp nhất, tại mỗi trạng thái LR(1) gốc có thể hoàn toàn không có xung đột).

    Cho một tập các trạng thái LR(1) (mỗi trạng thái là một tập mục kèm lookahead, cho sẵn — không cần tính đóng), hãy:

    1. Nhóm các trạng thái có cùng lõi (cùng tập mục LR(0), bỏ qua lookahead) lại với nhau — đây chính là cách LALR(1) hợp nhất trạng thái.
    2. Với mỗi nhóm, hợp các tập lookahead theo từng mục lõi.
    3. Kiểm tra xem trạng thái đã hợp nhất có xung đột reduce/reduce hay không (xét mọi cặp mục đầy đủ khác sản xuất trong nhóm).

    Ví dụ kinh điển: với văn phạm S→aAd∣bAe∣aBe∣bBdS \to aAd \mid bAe \mid aBe \mid bBdS→aAd∣bAe∣aBe∣bBd, A→cA \to cA→c, B→cB \to cB→c, hai trạng thái LR(1) chính tắc chứa cùng lõi {A→c⋅, B→c⋅}\{A \to c\cdot,\ B \to c\cdot\}{A→c⋅, B→c⋅} nhưng với lookahead {d}/{e}\{d\}/\{e\}{d}/{e} ở trạng thái này và {e}/{d}\{e\}/\{d\}{e}/{d} ở trạng thái kia (không xung đột ở từng trạng thái riêng). Khi LALR(1) hợp nhất hai trạng thái đó, cả hai mục đều nhận lookahead {d,e}\{d, e\}{d,e} — sinh ra xung đột reduce/reduce trên {d,e}\{d, e\}{d,e}.

    • Định dạng đầu vào:
      • Dòng 1: số nguyên sss (1≤s≤1001 \le s \le 1001≤s≤100) — số trạng thái LR(1) cho sẵn, đánh số thứ tự 1,…,s1, \ldots, s1,…,s theo thứ tự xuất hiện trong input.
      • Với mỗi trạng thái (sss lần, theo thứ tự):
        • Một dòng chứa số nguyên mim_imi​ — số mục của trạng thái đó.
        • mim_imi​ dòng tiếp theo: mỗi dòng một mục LR(1) dạng A -> β . γ | a1 a2 ... (định dạng giống hệt bài tính closure LR(1) ở trên: mục LR(0) rồi tới dấu | rồi tới danh sách lookahead cách nhau khoảng trắng). Nếu cùng một mục lõi xuất hiện nhiều lần trong cùng một trạng thái, lookahead của chúng được hợp lại.
    • Định dạng đầu ra:
      • Dòng 1: số nguyên ggg — số nhóm (trạng thái LALR sau khi hợp nhất).
      • Với mỗi nhóm, theo thứ tự tăng dần của chỉ số nhỏ nhất (1-based) trong nhóm:
        • Một dòng Nhom: i1,i2,... — danh sách chỉ số (1-based, tăng dần, cách nhau dấu phẩy không khoảng trắng) của các trạng thái gốc thuộc nhóm này.
        • Nếu nhóm (sau khi hợp lookahead) có xung đột reduce/reduce: với mỗi cặp mục đầy đủ khác sản xuất có lookahead giao nhau khác rỗng, in một dòng REDUCE-REDUCE: <mục A> // <mục B> | t1 t2 ... trong đó <mục A> và <mục B> là hai mục dạng A -> β . (mục A đứng trước theo thứ tự so sánh chuỗi), và t1 t2 ... là các ký hiệu giao nhau, sắp xếp tăng dần theo thứ tự từ điển (mã ASCII), cách nhau khoảng trắng. Các dòng xung đột được sắp xếp tăng dần theo <mục A> rồi <mục B>.
        • Nếu nhóm không có xung đột nào, in một dòng duy nhất OK.

    Ví dụ:

    Đầu vào:

    14
    5
    S -> . a A d | $
    S -> . a B e | $
    S -> . b A e | $
    S -> . b B d | $
    S' -> . S | $
    1
    S' -> S . | $
    4
    A -> . c | d
    B -> . c | e
    S -> a . A d | $
    S -> a . B e | $
    4
    A -> . c | e
    B -> . c | d
    S -> b . A e | $
    S -> b . B d | $
    2
    A -> c . | d
    B -> c . | e
    1
    S -> a B . e | $
    1
    S -> a A . d | $
    2
    A -> c . | e
    B -> c . | d
    1
    S -> b B . d | $
    1
    S -> b A . e | $
    1
    S -> a B e . | $
    1
    S -> a A d . | $
    1
    S -> b B d . | $
    1
    S -> b A e . | $
    

    Đầu ra:

    13
    Nhom: 1
    OK
    Nhom: 2
    OK
    Nhom: 3
    OK
    Nhom: 4
    OK
    Nhom: 5,8
    REDUCE-REDUCE: A -> c . // B -> c . | d e
    Nhom: 6
    OK
    Nhom: 7
    OK
    Nhom: 9
    OK
    Nhom: 10
    OK
    Nhom: 11
    OK
    Nhom: 12
    OK
    Nhom: 13
    OK
    Nhom: 14
    OK
    

    Đầu vào:

    2
    2
    X -> p . | a
    Y -> q . | b
    2
    X -> p . | a
    Y -> q . | c
    

    Đầu ra:

    1
    Nhom: 1,2
    OK
    

    Đang tải editor...