Follow英文意为“跟随”, Follow集其实就是求非终结符右边所有终结符的集合。
以这个经典例题为例:
若要 求T的后跟非终结符集合(即Follow(T)),先看第一条产生式: E→TE' [1],T的后跟终结符集合则为first(E');但当我们将E按照第8条产生式进行规约,得F→(TE'),此时 “)” 也是T的后跟终结符。故当求Follow(T)时,要 求T所有后跟(包括规约后的)终结符。
所以求Follow(S)原则如下(S是一个非终结符):当有产生式 Q→RST,
T是非终结符时:Follow(S)=Follow(Q)∪(First(T)-ε);
T是终结符时:Follow(S)=First(T)
T是ε时:Follow(S)=Follow(Q)
其中Q是非终结符,R是符号的集合(R可以是ε)
所以我们做这道题时先列个表,非终结符不一定非要按着顺序写,但开始符最好放在第一行。对输入文法的符号串(比如i*i#),需要一个符号#,代表结束符号串的输入,所以先往开始符的Follow集加结束标记符#(或$,视教材版本而定):
Follow(E) | # |
Follow(E') | |
Follow(T) | |
Follow(T') | |
Follow(F) |
给出First集:
First(E) | i,( |
First(E') | +,ε |
First(T) | i,( |
First(T') | *,ε |
First(F) | i,( |
对产生式[1] E→TE',遍历箭头右边的非终结符:
Follow(T)=(First(E')-ε)∪Follow(E) = {+}∪Follow(E)
Follow(E')=(First(ε)-ε)∪Follow(E) = Follow(E)
现在还不知道Follow(E)是什么,所以最后再处理,
填表:
Follow(E) | {#} |
Follow(E') | Follow(E) |
Follow(T) | {+}∪Follow(E) |
Follow(T') | |
Follow(F) |
对产生式[2]E'→+TE':
Follow(T)=(First(E')-ε)∪Follow(E') ={+}∪Follow(E')
Follow(E')=(First(ε)-ε)∪Follow(E') = Follow(E')(等于自身)
填表:
Follow(E) | {#} |
Follow(E') | Follow(E) |
Follow(T) | {+}∪Follow(E)∪Follow(E') |
Follow(T') | |
Follow(F) |
对产生式[4]T→FT' :
Follow(F)=(First(T')-ε)∪Follow(T) = {*}∪Follow(T)
Follow(T')=(First(ε)-ε)∪Follow(T) = Follow(T)
填表:
Follow(E) | {#} |
Follow(E') | Follow(E) |
Follow(T) | {+}∪Follow(E)∪Follow(E') |
Follow(T') | Follow(T) |
Follow(F) | {*}∪Follow(T) |
对产生式[5]T'→*FT' :
Follow(F)=(First(T')-ε)∪Follow(T') = {*}∪Follow(T')
Follow(T')=(First(ε)-ε)∪Follow(T') = Follow(T')
填表:
Follow(E) | {#} |
Follow(E') | Follow(E) |
Follow(T) | {+}∪Follow(E)∪Follow(E') |
Follow(T') | Follow(T) |
Follow(F) | {*}∪Follow(T)∪Follow(T') |
对产生式[8]F→(E) :
Follow(E)=(First( ) )) = {)}: ")"已经是E右边的最左终结符,所以不需要添加Follow(E)
填表:
Follow(E) | {#}∪{)} |
Follow(E') | Follow(E) |
Follow(T) | {+}∪Follow(E)∪Follow(E') |
Follow(T') | Follow(T) |
Follow(F) | {*}∪Follow(T)∪Follow(T') |
这时根据已知Follow集Follow(E)={#,)},逐个求出其他的Follow集:
Follow(E) | {#}∪{)} |
Follow(E') | Follow(E) = {#.)} 第①步 |
Follow(T) | {+}∪Follow(E)∪Follow(E') ={+.#.)} ② |
Follow(T') | Follow(T)={+.#.)} ③ |
Follow(F) | {*}∪Follow(T)∪Follow(T') = {*,+,#,)} ④ |
这样就求出了所有非终结符的Follow集。
值得注意的是,(举一个与题目关系不大的例子)对产生式E→TaE',Follow(T) = Follow(E)∪First(aE')=Follow(E)∪{a},而不是对a,E'分别求first后加入Follow(T).