花了點時間弄了個大概,希望對和我一樣的人有所幫助。
文法如下:
E -> TE'
E' -> +TE'|ε
T -> FT'
T' -> *FT'|ε
F -> (E)|id
----------------------------------------------------------------------------------------------------------------------------------------------------
FIRST集:由非終結符號推出的所有的開頭符號或ε
規則:終結符的FIRST集,即是他本身。
所以,FIRST(+) = {+}, FIRST(*) = {*}, FIRST(id) = {id}, FIRST(() = {(}, FIRST()) = {)}
FIRST(E): 列出與E相關的產生式: E->TE' T -> FT' F -> (E)|id,
顯然,F->( / id, T-> ( / id, 所以,FIRST(F) = {(,id}, FIRST(T) = {(,id}, FIRST(E) = {(,id}
FIRST(E') = {+,ε}
FIRST(T') = {*,ε}
FOLLOW集:緊跟隨其后面的終結符號或#
和FIRST集不同的是:FOLLOW集只是針對非終結符而言,因為FIRST集和FOLLOW集設計的初衷就是
根據當前句型的最左語法變量A和當前輸入符號a可以唯一的選擇A的候選式αi來替換A,
從而實現對G的句子進行確定的自頂向下分析。所以終結符可以直接與輸入符號進行匹配,不需要FOLLOW集。
實現:把所有包含你要求的符號的產生式都找出來。
FOLLOW(E): F -> (E)|id, E后面就是),其他包含E的都沒有,所以FOLLOW(E)={),#}
FOLLOW(E'): 由 E -> TE' 和 F -> (E)|id 推出 F -> (TE')|id ,所以FOLLOW(E)={),#}
FOLLOW(T): 由 E -> TE' 和 E' -> +TE'|ε ,T后面是E' (即:+TE'|ε),所以,T有+,
再根據F -> (E)|id E -> TE' 推出 F -> (TE')|id,當 E' -> ε時,T后面是),所以,T有 ).
故FOLLOW(T) = {+,),#}
FOLLOW(T'): 由 E -> TE' 和 F -> (E)|id 推出 F -> (TE')|id,且 T -> FT',所以 F -> (FT'E')|id
T' 后面緊跟 E',E' -> +TE'|ε,當E' -> +TE'時,T' 有 +。當E' -> ε 時,T' 有 )
故FOLLOW(T') = {+,),#}
FOLLOW(F): 由 E -> TE' 和 F -> (E)|id 推出 F -> (TE')|id,且 T -> FT' ,T' -> *FT'|ε,所以 F -> (FT'E')|id
當 T' -> *FT'時,F有 *,當T' -> ε時,F后緊跟E',當E' -> +TE'時,F有 +,當E' -> ε時,F 有 )
故FOLLOW(F) = {*,+,),#}
另一個例子:
文法:
S --> aA
S --> d
A --> bAS
A --> ε
求出該文法的First集 和 Follow集。
嚴謹的說 First集 是針對候選式而說的。在此把書上的求候選式First集的算法寫一下:
--------------------------------------------------------------------------------------------------------------------------------
輸入:文法G = (V,P,T,S),α = (v ∪ T)*,α = X1.....Xn
輸出:First(α)
步驟:
1、計算First(X1);
2、First(α) = First(X1) - {ε}
3、k = 1
4、while(ε ∈ First(Xk) and k < n) do begin
First(α) = First(α)
∪ (First(Xk+1) - {ε})
k = k +1 end
5、if(k = n and ε ∈
First(Xk)) then First(α) =
First(α) ∪ {ε}
--------------------------------------------------------------------------------------------------------------------------------
First(S) = {a,d}
First(A) = {b,ε}
First(aA) = {a}
First(d) = {d}
First(bAS) = {b}
First(ε) = {ε}
咋看之下 Follow(S) = {#} 實則不然
(1)S --> aA (2)A --> bAS
由2得: Follow(A) = First(S) = {a,d, #}
又因為 1 式:S --> aA,Follow(S) = Follow(A) = {a,d, #}