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] Tính bao đóng (closure) của tập mục LR(1) có lookahead

    Một mục LR(1) là một cặp ([A→α⋅γ], L)([A \to \alpha \cdot \gamma],\ L)([A→α⋅γ], L) gồm một mục LR(0) và một tập lookahead LLL (tập ký hiệu kết thúc). Phép đóng (closure) LR(1) của một tập mục III được tính theo quy tắc điểm bất động:

    Nếu ([A→α⋅B β], L)∈I([A \to \alpha \cdot B\,\beta],\ L) \in I([A→α⋅Bβ], L)∈I với BBB là phi kết thúc, thì với mọi sản xuất B→δB \to \deltaB→δ, thêm mục ([B→⋅ δ], L′)([B \to \cdot\,\delta],\ L')([B→⋅δ], L′) vào III, trong đó L′=FIRST(β a)L' = FIRST(\beta\,a)L′=FIRST(βa) hợp trên mọi a∈La \in La∈L; cụ thể L′=FIRST(β)∖{ε}L' = FIRST(\beta) \setminus \{\varepsilon\}L′=FIRST(β)∖{ε}, và nếu ε∈FIRST(β)\varepsilon \in FIRST(\beta)ε∈FIRST(β) (hoặc β\betaβ rỗng) thì L′=L′∪LL' = L' \cup LL′=L′∪L. Nếu mục [B→⋅ δ][B \to \cdot\,\delta][B→⋅δ] đã có trong III (với lookahead khác), hợp thêm L′L'L′ vào tập lookahead hiện có của nó thay vì tạo mục mới. Lặp lại đến khi không còn thay đổi.

    FIRST(β)FIRST(\beta)FIRST(β) được tính từ các tập FIRSTFIRSTFIRST của từng ký hiệu phi kết thúc cho sẵn (ký hiệu kết thúc có FIRSTFIRSTFIRST là chính nó); nếu β\betaβ rỗng thì FIRST(β)={ε}FIRST(\beta) = \{\varepsilon\}FIRST(β)={ε}.

    Cho văn phạm, tập FIRSTFIRSTFIRST của các phi kết thúc, và tập mục hạt nhân LR(1) (mỗi mục kèm một tập lookahead), hãy tính tập đóng LR(1) đầy đủ.

    Ví dụ: văn phạm S→A BS \to A\,BS→AB, A→a ∣ εA \to a\,|\,\varepsilonA→a∣ε, B→bB \to bB→b; hạt nhân (S \to \cdot\,A\,B,\ \{\}).Vıˋsau. Vì sau .VıˋsauAcoˋncòncoˋnBvớivớivớiFIRST(B) = {b}(kho^ngnullable),lookaheadtruye^ˋnchocaˊcsảnxua^ˊtcủa(không nullable), lookahead truyền cho các sản xuất của(kho^ngnullable),lookaheadtruye^ˋnchocaˊcsảnxua^ˊtcủaAlaˋlàlaˋ{b}(kho^nghợpthe^m(không hợp thêm(kho^nghợpthe^m{$}).Đoˊng:the^m). Đóng: thêm ).Đoˊng:the^m(A \to \cdot,a,\ {b})vaˋvàvaˋ(A \to \cdot,\ {b})$.

    • Định dạng đầu vào:
      • Dòng 1: số nguyên nnn — số sản xuất, định dạng A -> X1 ... Xk hoặc A -> # như các bài trước.
      • Dòng tiếp theo: số nguyên fff — số phi kết thúc có tập FIRST cho sẵn.
      • fff dòng tiếp theo: A: t1 t2 ... [EPS] — các phần tử của FIRST(A)FIRST(A)FIRST(A) (token EPS nếu ε∈FIRST(A)\varepsilon \in FIRST(A)ε∈FIRST(A)), giống định dạng bài FIRST đã mô tả trước đó.
      • Dòng tiếp theo: số nguyên kkk — số mục trong tập hạt nhân LR(1) ban đầu.
      • kkk dòng tiếp theo: mỗi dòng một mục LR(1) dạng A -> β . γ | a1 a2 ... — phần trước dấu | là mục LR(0) (định dạng dấu chấm như các bài trước), phần sau dấu | là các ký hiệu lookahead cách nhau khoảng trắng (có đúng một khoảng trắng trước và sau dấu |). Nếu cùng một mục lõi xuất hiện ở nhiều dòng hạt nhân, lookahead của chúng được hợp lại.
    • Định dạng đầu ra:
      • Dòng 1: số lượng mục (lõi khác nhau) trong tập đóng LR(1).
      • Các dòng tiếp theo: mỗi dòng một mục dạng A -> β . γ | a1 a2 ..., trong đó các lookahead được sắp xếp tăng dần theo thứ tự từ điển (mã ASCII) và cách nhau đúng một khoảng trắng; các mục được liệt kê theo thứ tự tăng dần khi so sánh chuỗi phần trước dấu | (thứ tự từ điển theo mã ASCII).

    Ví dụ:

    Đầu vào:

    4
    S -> A B
    A -> a
    A -> #
    B -> b
    2
    A: a EPS
    B: b
    1
    S -> . A B | $
    

    Đầu ra:

    3
    A -> . | b
    A -> . a | b
    S -> . A B | $
    

    Đầu vào:

    7
    S -> A B C
    A -> a
    A -> #
    B -> b
    B -> #
    C -> c
    S -> x
    3
    A: a EPS
    B: b EPS
    C: c
    1
    S -> . A B C | $
    

    Đầu ra:

    3
    A -> . | b c
    A -> . a | b c
    S -> . A B C | $
    

    Đang tải editor...