Cho văn phạm gồm các luật sinh: epsilon; epsilon; S → A; A → BC hoặc A-> DBC; B → bBʼ hoặc B-> epsilon; B’→ bB’ hoặc B’- > C → c hoặc C-> D → a hoặc D-> d, FOLLOW (D) =?
Đáp án đúng: B
Để tìm FOLLOW(D), ta cần xem xét các luật sinh có D ở vế phải.
Trong văn phạm đã cho, ta có luật: A → DBC.
Theo định nghĩa của FOLLOW, FOLLOW(D) là tập hợp các terminal có thể xuất hiện ngay sau D trong một số dẫn xuất.
Trong luật A → DBC, ký hiệu theo sau D là C. Do đó, FIRST(C) sẽ thuộc FOLLOW(D).
Vì C → c, nên c thuộc FOLLOW(D).
Ngoài ra, nếu C có thể dẫn xuất ra ε (epsilon), thì FOLLOW(A) sẽ thuộc FOLLOW(D).
Trong trường hợp này, C không thể dẫn xuất ra ε.
Tuy nhiên, ta cần xem xét các trường hợp khác mà D có thể ở cuối chuỗi dẫn xuất.
Trong luật A → DBC, nếu C -> epsilon, thì FOLLOW(D) sẽ chứa FOLLOW(A).
Vì S -> A nên FOLLOW(A) sẽ chứa FOLLOW(S) = {$}, trong đó $ là ký hiệu kết thúc chuỗi.
Nhưng do C -> c, C không thể dẫn xuất ra epsilon. Do đó, FOLLOW(D) chỉ chứa FIRST(C).
FIRST(C) = {c}.
Nhưng D-> a hoặc D-> d nên cần xem xét thêm các luật khác.
Vì D → a hoặc D → d, thì FIRST(D) = {a, d}.
Theo luật A → DBC, FIRST(C) sẽ nằm trong FOLLOW(D), vậy {c} ∈ FOLLOW(D).
Nếu C có thể dẫn tới ε, thì FOLLOW(A) sẽ nằm trong FOLLOW(D).
Mà S → A, nên FOLLOW(A) chứa dấu $ (kết thúc chuỗi).
Nhưng C → c, nên C không thể dẫn tới ε.
Vậy FOLLOW(D) = {c, $}. Nhưng vì D -> a hoặc D -> d nên {a, d} cũng phải nằm trong tập FOLLOW(D).
Vậy FOLLOW(D) = {a, d, $}.