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] Xây dựng bảng SLR(1) và mô phỏng phân tích

    Cho một văn phạm phi ngữ cảnh với kkk luật sinh và ký hiệu bắt đầu SSS (định dạng như các bài trên). Hãy tự động xây dựng bảng phân tích SLR(1) rồi dùng bảng đó để mô phỏng phân tích cú pháp (shift-reduce) một chuỗi token cho trước.

    Các bước xây dựng (tương tự lý thuyết SLR chuẩn, thực hiện tự động, không cho sẵn trong input):

    1. Mở rộng văn phạm với luật 000: S′→SS' \to SS′→S.
    2. Ký hiệu là non-terminal nếu nó xuất hiện ở vế trái của một luật sinh (kể cả S′S'S′); ngược lại là terminal.
    3. Tính tập FIRST\text{FIRST}FIRST và FOLLOW\text{FOLLOW}FOLLOW theo thuật toán chuẩn (\text{FOLLOW}(S') = \{\}$).
    4. Xây dựng tập mục chính tắc LR(0) (như bài trước) và từ đó suy ra bảng ACTION\text{ACTION}ACTION/GOTO\text{GOTO}GOTO theo quy tắc SLR:
      • Mục [A→α . aβ][A \to \alpha \,.\, a\beta][A→α.aβ] với aaa là terminal: ACTION[I,a]=\text{ACTION}[I,a] = ACTION[I,a]= shift đến GOTO(I,a)\text{GOTO}(I,a)GOTO(I,a).
      • Mục [A→α .][A \to \alpha \,.][A→α.] với A≠S′A \ne S'A=S′: với mọi b∈FOLLOW(A)b \in \text{FOLLOW}(A)b∈FOLLOW(A), ACTION[I,b]=\text{ACTION}[I,b] = ACTION[I,b]= reduce theo luật đó.
      • Mục [S′→S .][S' \to S\,.][S′→S.]: \text{ACTION}[I, \] = $ accept.
      • Nếu một ô của bảng nhận từ 2 giá trị khác nhau trở lên → văn phạm không phải SLR(1).

    Mô phỏng phân tích: dùng ngăn xếp trạng thái, bắt đầu [0][0][0], đọc chuỗi input nối thêm $ ở cuối, áp dụng ACTION/GOTO theo đúng thuật toán LR chuẩn (shift, reduce dùng GOTO trên đỉnh stack sau khi pop, accept khi gặp hành động accept). Nếu tại một bước không có hành động nào trong bảng ứng với (trạng thái hiện tại, ký hiệu input hiện tại) → chuỗi bị từ chối (REJECT).

    Yêu cầu: nếu văn phạm không phải SLR(1) thì báo ngay; nếu là SLR(1), mô phỏng phân tích chuỗi input đã cho và cho biết kết quả.

    • Định dạng đầu vào:
      • Dòng 1: số nguyên kkk (1≤k≤151 \le k \le 151≤k≤15) và ký hiệu bắt đầu SSS.
      • kkk dòng tiếp theo: luật sinh dạng A -> X1 X2 ... Xm (nếu rỗng: A -> ε).
      • Dòng tiếp theo: số nguyên nnn (0≤n≤10000 \le n \le 10000≤n≤1000) — số token của input.
      • Dòng tiếp theo: nnn token cách nhau bởi khoảng trắng (dòng trống nếu n=0n=0n=0, vẫn phải đọc dòng này). Các token này chỉ gồm các ký hiệu terminal của văn phạm; ký hiệu $ không xuất hiện trong dòng này (được chương trình tự thêm vào cuối).
    • Định dạng đầu ra:

      Nếu văn phạm không phải SLR(1) (có xung đột khi xây bảng): in đúng một dòng NOT-SLR.

      Ngược lại, mô phỏng phân tích chuỗi input:

      • Nếu bị từ chối: in đúng một dòng REJECT.
      • Nếu được chấp nhận: in dòng đầu ACCEPT, dòng thứ hai là dãy số hiệu các luật sinh đã được reduce, theo đúng thứ tự thực hiện, cách nhau bởi 1 khoảng trắng; nếu không có reduce nào (dãy rỗng) thì in NONE.

    Ví dụ:

    Đầu vào:

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

    Đầu ra:

    ACCEPT
    6 4 2 6 4 1
    

    Đầu vào:

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

    Đầu ra:

    ACCEPT
    6 4 2 6 4 6 3 1
    

    Đang tải editor...