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] Đếm số trạng thái của ôtômat LR(0) chính tắc

    Cho văn phạm phi ngữ cảnh GGG với ký hiệu bắt đầu SSS. Văn phạm mở rộng (augmented grammar) G′G'G′ được tạo bằng cách thêm luật sinh mới S′→SS' \to SS′→S với S′S'S′ là ký hiệu bắt đầu mới (không trùng với bất kỳ ký hiệu nào đã có trong GGG).

    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).

    Mục LR(0) có dạng [A→α⋅β][A \to \alpha \cdot \beta][A→α⋅β] (một luật sinh với một dấu chấm . đặt ở một vị trí nào đó trong vế phải). Phép closure(I)(I)(I): với mỗi mục [A→α⋅Bβ]∈I[A \to \alpha \cdot B \beta] \in I[A→α⋅Bβ]∈I mà BBB là non-terminal, thêm mọi mục [B→⋅γ][B \to \cdot \gamma][B→⋅γ] (với B→γB \to \gammaB→γ là luật sinh của BBB) vào III, lặp lại đến khi không còn gì thay đổi. Phép goto(I,X)(I, X)(I,X) (với XXX là một ký hiệu bất kỳ): tập hợp mọi mục [A→αX⋅β][A \to \alpha X \cdot \beta][A→αX⋅β] sao cho [A→α⋅Xβ]∈I[A \to \alpha \cdot X \beta] \in I[A→α⋅Xβ]∈I, sau đó lấy closure của tập đó.

    Họ tập mục chính tắc (canonical collection): bắt đầu từ I0=closure({[S′→⋅S]})I_0 = \mathrm{closure}(\{[S' \to \cdot S]\})I0​=closure({[S′→⋅S]}), lặp đi lặp lại việc tính goto(I,X)\mathrm{goto}(I, X)goto(I,X) cho mọi trạng thái III đã có và mọi ký hiệu XXX của văn phạm, thêm các trạng thái mới (tập mục khác với mọi tập mục đã có) cho tới khi không phát sinh thêm trạng thái nào — đây chính là các trạng thái của ôtômat LR(0), nền tảng để xây bảng SLR(1)/LALR(1).

    Hãy xác định: (1) tổng số trạng thái (tập mục) phân biệt trong họ tập mục chính tắc, và (2) tổng số cạnh chuyển phân biệt của ôtômat, trong đó một cạnh được tính là một cặp (trạng thái nguồn, ký hiệu chuyển) (I,X)(I, X)(I,X) mà goto(I,X)\mathrm{goto}(I,X)goto(I,X) khác rỗng (nếu từ cùng một trạng thái III có cạnh nhãn XXX đi tới đúng một trạng thái đích duy nhất theo định nghĩa goto, mỗi cặp (I,X)(I,X)(I,X) hợp lệ chỉ tính 1 cạnh, kể cả khi đích trùng với một trạng thái đã tồn tại hoặc trùng với chính III — tự vòng lặp cũng tính là 1 cạnh).

    Ví dụ: văn phạm S -> a với ký hiệu bắt đầu S có I0={[S′→⋅S],[S→⋅a]}I_0 = \{[S' \to \cdot S],[S \to \cdot a]\}I0​={[S′→⋅S],[S→⋅a]}, goto(I0,S)={[S′→S⋅]}\mathrm{goto}(I_0,S)=\{[S' \to S \cdot]\}goto(I0​,S)={[S′→S⋅]}, goto(I0,a)={[S→a⋅]}\mathrm{goto}(I_0,a)=\{[S \to a \cdot]\}goto(I0​,a)={[S→a⋅]} — có 3 trạng thái, 2 cạnh.

    • Đị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 của văn phạm gốc (chưa mở rộng). 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 của văn phạm gốc.

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

      In ra hai dòng: dòng thứ nhất là tổng số trạng thái của họ tập mục chính tắc LR(0) (đã tính cả trạng thái ban đầu I0I_0I0​); dòng thứ hai là tổng số cạnh chuyển phân biệt (theo định nghĩa ở đề bài).

    Ví dụ:

    Đầu vào:

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

    Đầu ra:

    12
    22
    

    Đầu vào:

    1
    S -> a
    S
    

    Đầu ra:

    3
    2
    

    Đang tải editor...