FOLLOW集合求解
-
follow集合的作用
Follow(A)的作用是标示那些可以出现在A之后的字符,语法分析程序根据这个,在A可以被替换为 ε 的时候来进行判断,看当前的文法是否是合法的。 -
follow集合的定义
(1)若 A 是开始符号,则#就在 Follow (A) 中。
(2)若存在产生式B →aAg ,则First (g) - {ε }在 Follow (A) 中。
(3)若存在产生式B →aAg ,且ε在 First (g) 中,则 Follow (A)包括 Follow (B)。
#必须总是要增加到开始符号的 Follow 集合中。 -
求 Follow 集合的意思就是
求非终结符右边所有终结符的集合
-
follow集合求解过程
紧跟随其后面的终结符号或#。但文法的识别符号包含#,在求的时候还要考虑到ε。 具体做法是把所有包含你要求的符号的产生式都找出来,再看哪个有用。
Follow集合是针对非终结符而言的,Follow(U)所表达的是句型中非终结符U所有可能的后随终结符号的集合。特别地,“#”是识别符号的后随符或者说是输入串的结束符。注意Follow集合是从开始符号S开始推导。
对文法中的每个A属于V n,计算FOLLOW(A):
(1)、对文法的开始符号S,将“$”加到FOLLOW(S)中;
(2)、若A->aBb是一条规则,则把FIRST(b)中的非ε元素加到FOLLOW(B)中;
(3)、若A->aB或A->aBb是一条规则且b=>ε,则把FOLLOW(A)加到FOLLOW(B)中;
(4)、反复使用(2)、(3),直到每个非终结符的FOLLOW集不再增大为止。
或者
- 直接收取:
1.1 注意产生式右部的每一个形如“…Ua…”的组合,把a直接收入到Follow(U)中。因a是紧跟在U后的终结符。
1.2 对形如“…UP…”(P是非终结符)的组合,把First§直接收入到Follow(U)中【在这里,如果First(P)中有空字符,那么就要把左(假设是S)的Follow(S)送入到Follow(U)中。还有就是Follow集中是没有空字符的】。
1.3 直接收取:若S->…U,即以U结尾,则 # ∈ Follow(U)- *反复传送:对形如U->…P的产生式(其中P是非终结符),应把Follow(U)中的全部内容传送到Follow( P )中。
如求follow(A)的,产生式:
S→ABc
A→a|ε
但只有S→ABc 有用。跟随在A后年的终结符号是FIRST(B)={b,ε},当FIRST(B)的元素为ε时,跟随在A后的符号就是c,所以 Follow(A)={b,c} 同理Follow(B)={c}
-
技巧:Follow一般从上往下找。
如果要找A的Follow,要从式子的右边找到A,然后来找A的Follow,这与First是不同的。 -
例题
设有文法G[A]:
A→BCc | gDB
B→bCDE |ε
C→DaB | ca
D→dD |ε
E→gAf | c
计算该文法的每一个非终结符的FIRST集和FOLLOW集。
解:(1)、FIRST集的求解:
FIRST(A) = FIRST(BCc) ∪ FIRST(gDB)
= {a,b,c,d,g}
同理:
FIRST(B) = {b,ε} FIRST(C ) = {a,c,d}
FIRST(D) = {d,ε} FIRST(E) = {g,c}
(2)接下来求解FOLLOW集:
由于A是文法的开始符号,所以#属于FOLLOW(A),由E→gAf | c l利用规则可知f属于FOLLOW(A),所以FOLLOW(A)={f,#}
FOLLOW( C)={c,d,g,#}
FOLLOW(B)={a,c,d,f,g,#}
FOLLOW(D)={a,b,c,g,f,#}
FOLLOW(E)={a,c,d,f,g,#}