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] Kiểm tra văn phạm có phải là SLR(1)

    Với ôtômat LR(0) chính tắc của văn phạm mở rộng G′G'G′ (xây dựng như mô tả ở bài toán dựng tập mục LR(0): closure, goto, họ tập mục chính tắc bắt đầu từ I0=closure({[S′→⋅S]})I_0 = \mathrm{closure}(\{[S' \to \cdot S]\})I0​=closure({[S′→⋅S]})), phương pháp SLR(1) xây dựng bảng phân tích bằng cách, tại mỗi trạng thái III:

    • Với mỗi mục [A→α⋅aβ]∈I[A \to \alpha \cdot a \beta] \in I[A→α⋅aβ]∈I (aaa là terminal): thêm hành động shift trên aaa.
    • Với mỗi mục hoàn chỉnh [A→α⋅]∈I[A \to \alpha \cdot] \in I[A→α⋅]∈I (với A≠S′A \ne S'A=S′): với mọi a∈FOLLOW(A)a \in \mathrm{FOLLOW}(A)a∈FOLLOW(A), thêm hành động reduce theo luật A→αA \to \alphaA→α trên aaa.

    Nếu tại một ô (I,a)(I, a)(I,a) nào đó tồn tại nhiều hơn một hành động được đề xuất, văn phạm có xung đột và không phải SLR(1). Có hai loại xung đột: shift-reduce (vừa có shift vừa có reduce trên cùng aaa) và reduce-reduce (có từ hai luật sinh khác nhau trở lên cùng muốn reduce trên aaa).

    Quy ước ký hiệu văn phạm (áp dụng cho toàn bộ đề bài này): mỗi luật sinh được cho ở dạng A -> X1 X2 ... Xk (các ký hiệu cách nhau bởi dấu cách); nếu vế phải là rỗng thì ghi A -> eps. Một ký hiệu được coi là ký hiệu chưa kết thúc (non-terminal) nếu và chỉ nếu ký tự đầu tiên của nó là một chữ cái in hoa (A-Z); mọi ký hiệu còn lại (chữ thường, chữ số, dấu (, ), +, id, ... ) đều là ký hiệu kết thúc (terminal). Ký hiệu đặc biệt eps chỉ dùng để biểu diễn xâu rỗng ε\varepsilonε và không phải là một terminal thật sự. Ký hiệu $ là ký hiệu kết thúc xâu vào (end-marker).

    Cho văn phạm phi ngữ cảnh GGG với ký hiệu bắt đầu SSS, hãy xác định văn phạm (mở rộng) có phải SLR(1) hay không. Nếu có xung đột, đếm: số trạng thái có ít nhất một xung đột, tổng số xung đột shift-reduce (mỗi cặp (I,a)(I,a)(I,a) tính 1), và tổng số xung đột reduce-reduce (mỗi cặp (I,a)(I,a)(I,a) có từ 2 luật sinh muốn reduce trở lên cũng chỉ tính 1, bất kể có bao nhiêu luật).

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

      Dòng đầu tiên là số nguyên nnn (1≤n≤601 \le n \le 601≤n≤60) — số luật sinh. nnn dòng tiếp theo, mỗi dòng một luật sinh dạng A -> X1 X2 ... Xk hoặc A -> eps. Dòng cuối cùng là ký hiệu bắt đầu SSS.

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

      Nếu văn phạm là SLR(1) (không xung đột), in ra đúng một dòng SLR(1). Ngược lại, in ra hai dòng: dòng đầu NOT SLR(1); dòng thứ hai gồm ba số nguyên cách nhau bởi dấu cách: số trạng thái có xung đột, tổng số xung đột shift-reduce, tổng số xung đột reduce-reduce.

    Ví dụ:

    Đầu vào:

    1
    S -> a
    S
    

    Đầu ra:

    SLR(1)
    

    Đầu vào:

    6
    E -> E + T
    E -> T
    T -> T * F
    T -> F
    F -> ( E )
    F -> id
    E
    

    Đầu ra:

    SLR(1)
    

    Đang tải editor...