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 kích thước tập FIRST của từng ký hiệu chưa kết thúc

    Cho một văn phạm phi ngữ cảnh (CFG) dùng trong bộ phân tích cú pháp LL(1).

    Quy ước biểu diễn văn phạm phi ngữ cảnh (CFG) dùng chung cho đề này:

    • Mỗi ký hiệu chưa kết thúc (non-terminal) là một chữ cái in hoa (A-Z).
    • Mọi token khác (chữ thường, số, hoặc ký hiệu như (, ), +, *, id, num, ...) là ký hiệu kết thúc (terminal); terminal có thể dài nhiều ký tự nhưng không chứa khoảng trắng.
    • Token đặc biệt e ở vế phải nghĩa là luật sinh sinh ra chuỗi rỗng ε\varepsilonε (ví dụ A -> e).
    • Ký hiệu kết thúc đầu vào (end-of-input) được ký hiệu là $ khi cần dùng tới FOLLOW.
    • Đảm bảo mọi ký hiệu chưa kết thúc xuất hiện ở vế phải của bất kỳ luật sinh nào cũng đều có ít nhất một luật sinh định nghĩa nó (văn phạm "đóng", không có non-terminal mồ côi).

    Với mỗi ký hiệu chưa kết thúc AAA, tập FIRST(A)FIRST(A)FIRST(A) được định nghĩa như thường lệ (tập các ký hiệu kết thúc có thể xuất hiện đầu tiên trong một chuỗi mà AAA dẫn xuất ra, cùng với việc đánh dấu riêng liệu A⇒∗εA \Rightarrow^{*} \varepsilonA⇒∗ε hay không).

    Thay vì liệt kê toàn bộ tập FIRST(A)FIRST(A)FIRST(A), với mỗi ký hiệu chưa kết thúc AAA (theo đúng thứ tự nó xuất hiện lần đầu ở vế trái một luật sinh trong dữ liệu vào), hãy in ra:

    • Tên AAA,
    • Số lượng ký hiệu kết thúc (không tính ε\varepsilonε) có trong FIRST(A)FIRST(A)FIRST(A),
    • 111 nếu ε∈FIRST(A)\varepsilon \in FIRST(A)ε∈FIRST(A), ngược lại 000.

    Ví dụ

    Với văn phạm biểu thức số học kinh điển:

    E -> T X
    X -> + T X
    X -> e
    T -> F Y
    Y -> * F Y
    Y -> e
    F -> ( E )
    F -> id
    

    FIRST(E)={(,id}FIRST(E)=\{(, id\}FIRST(E)={(,id} (2 terminal, không có ε\varepsilonε) nên dòng đầu ra cho EEE là E 2 0. FIRST(X)={+,ε}FIRST(X)=\{+, \varepsilon\}FIRST(X)={+,ε} (1 terminal, có ε\varepsilonε) nên dòng cho XXX là X 1 1.

    • Định dạng đầu vào:
      • Dòng 1: ký hiệu bắt đầu SSS (không ảnh hưởng tới kết quả bài này, chỉ để thống nhất định dạng chung).
      • Dòng 2: số luật sinh nnn (1≤n≤301 \le n \le 301≤n≤30).
      • nnn dòng tiếp theo: mỗi dòng một luật sinh dạng A -> X1 X2 ... Xk (các ký hiệu vế phải cách nhau đúng một khoảng trắng), hoặc A -> e nếu vế phải rỗng.

      Quy ước biểu diễn văn phạm phi ngữ cảnh (CFG) dùng chung cho đề này:

      • Mỗi ký hiệu chưa kết thúc (non-terminal) là một chữ cái in hoa (A-Z).
      • Mọi token khác (chữ thường, số, hoặc ký hiệu như (, ), +, *, id, num, ...) là ký hiệu kết thúc (terminal); terminal có thể dài nhiều ký tự nhưng không chứa khoảng trắng.
      • Token đặc biệt e ở vế phải nghĩa là luật sinh sinh ra chuỗi rỗng ε\varepsilonε (ví dụ A -> e).
      • Ký hiệu kết thúc đầu vào (end-of-input) được ký hiệu là $ khi cần dùng tới FOLLOW.
      • Đảm bảo mọi ký hiệu chưa kết thúc xuất hiện ở vế phải của bất kỳ luật sinh nào cũng đều có ít nhất một luật sinh định nghĩa nó (văn phạm "đóng", không có non-terminal mồ côi).
    • Định dạng đầu ra:

      In ra đúng mmm dòng, với mmm là số ký hiệu chưa kết thúc phân biệt xuất hiện ở vế trái (theo thứ tự xuất hiện lần đầu trong dữ liệu vào). Mỗi dòng có dạng A k b — trong đó A là tên ký hiệu, k là số terminal (không tính ε\varepsilonε) thuộc FIRST(A)FIRST(A)FIRST(A), và b là 1 nếu ε∈FIRST(A)\varepsilon \in FIRST(A)ε∈FIRST(A) hoặc 0 nếu ngược lại. Các giá trị trên một dòng cách nhau đúng một khoảng trắng.

    Ví dụ:

    Đầu vào:

    S
    1
    S -> a

    Đầu ra:

    S 1 0
    

    Đầu vào:

    E
    8
    E -> T X
    X -> + T X
    X -> e
    T -> F Y
    Y -> * F Y
    Y -> e
    F -> ( E )
    F -> id

    Đầu ra:

    E 2 0
    X 1 1
    T 2 0
    Y 1 1
    F 2 0
    

    Đang tải editor...