如何求First集与Follow集
已知文法如下,求First集与Follow集
G[E]:E→TE′E′→+TE′∣εT→FT′T′→∗FT′∣εF→(E)∣i
G[E]:
E{\rightarrow} TE' \\
{\quad\quad\quad\quad\quad}E'{\rightarrow}+TE'|\varepsilon \\
{\quad\quad\quad}T{\rightarrow}FT'\\
{\quad\quad\quad\quad\quad}T'{\rightarrow}*FT'|\varepsilon\\
{\quad\quad\quad}F{\rightarrow}(E)|i\\
G[E]:E→TE′E′→+TE′∣εT→FT′T′→∗FT′∣εF→(E)∣i
First集:
-
第一次查看所有式子
-
首先看第一个式子:E→TE′E{\rightarrow} TE'E→TE′,候选式中未包含终结符,暂时无法得出结果
当前First集:
First(E) = { }
First(E′'′) = { }
First(T) = { }
First(T′'′) = { }
First(F) = { } -
第二个式子:E′→+TE′∣εE'{\rightarrow}+TE'|\varepsilonE′→+TE′∣ε,可以得到其所有候选式的串首终结符: +、ε{\varepsilon}ε,将其加入到First(E′'′)中
当前First集:
First(E) = { }
First(E′'′) = {+,ε{\varepsilon}ε}
First(T) = { }
First(T′'′) = { }
First(F) = { } -
第三个式子同 1,First集无变化
-
第四个式子同 2,将 *、ε{\varepsilon}ε加入到First(T′'′)中
当前First集:
First(E) = { }
First(E′'′) = {+,ε{\varepsilon}ε}
First(T) = { }
First(T′'′) = { *,ε{\varepsilon}ε}
First(F) = { } -
第五个式子:F→(E)∣iF{\rightarrow}(E)|iF→(E)∣i,将 (、i 加入到First(F)中
当前First集:
First(E) = { }
First(E′'′) = {+,ε{\varepsilon}ε}
First(T) = { }
First(T′'′) = { *,ε{\varepsilon}ε}
First(F) = { (,i} -
第二次查看所有式子
-
第一个式子可得,First(T) 是First(E) ,但First(T)是空的,故无变化
[注:参照书本58页第三行②,若有X→YX{\rightarrow}YX→Y,YYY是非终结符,就把First(Y)中非ε{\varepsilon}ε元素加入到First(X)中]
-
第二个式子不能得到新的结果,下一步
-
第三个式子可得,First(F)是First(T),故将 ( ,i 加入到First(T)
当前First集:First(E) = { }
First(E′'′) = {+,ε{\varepsilon}ε}
First(T) = { (,i }
First(T′'′) = { *,ε{\varepsilon}ε}
First(F) = { (,i } -
后续式子均不能得到新的结果,下一步
-
第三次查看所有式子
-
第一个式子得,First(T) 是First(E),故First集产生变化
当前First集:
First(E) = {(,i }
First(E′'′) = {+,ε{\varepsilon}ε}
First(T) = { (,i }
First(T′'′) = { *,ε{\varepsilon}ε}
First(F) = { (,i } -
后续式子均无法得到新的结果,求First集完毕
-
注:理论上每次First集产生变化就要重新查看一遍所有式子,这里为了方便进行了简写,实际做题时可以按照变化一次重新求一次
Follow集:
求Follow集是在已经求出First集的基础上进行
-
将#置入Follow(文法开始符号),即Follow(E)
当前Follow集:
Follow(E) = { # }
Follow(E′'′) = { }
Follow(T) = { }
Follow(T′'′) = { }
Follow(F) = { } -
第一次查看所有式子
-
从E→TE′E{\rightarrow} TE'E→TE′可得
-
Follow(E)可以加入到Follow(E′'′),将 # 置入Follow(E′'′)
-
Follow(E)可以加入到Follow(T),将 # 置入Follow(T)
[注:因为E′'′可能为ε{\varepsilon}ε],
-
First(E′'′)中非ε{\varepsilon}ε元素可以加入到Follow(T)中,将 + 置入Follow(T)
当前Follow集:
Follow(E) = { # }
Follow(E′'′) = { # }
Follow(T) = { #,+ }
Follow(T′'′) = { }
Follow(F) = { }
-
-
从E′→+TE′∣εE'{\rightarrow}+TE'|\varepsilonE′→+TE′∣ε 可得
- Follow(E′'′)可以加入到Follow(T),无变化
-
从T→FT′T{\rightarrow}FT'T→FT′可得
-
Follow(T)可以加入到Follow(T′'′),将 #、+ 置入Follow(T′'′)
-
Follow(T)可以加入到Follow(F),将 #、+ 置入Follow(F)
-
First(T′'′)中非ε{\varepsilon}ε元素可以加入到Follow(F)中,将 * 置入Follow(F)
当前Follow集:
Follow(E) = { # }
Follow(E′'′) = { # }
Follow(T) = { #,+ }
Follow(T′'′) = { #,+ }
Follow(F) = {#,+ ,* }
-
-
从T′→∗FT′∣εT'{\rightarrow}*FT'|\varepsilonT′→∗FT′∣ε 可得
- Follow(T′'′)可以加入到Follow(F),无变化
-
从F→(E)∣iF{\rightarrow}(E)|iF→(E)∣i 可得
-
非终结符E后有一个终结符 ),故将 ) 置入Follow(E)
当前Follow集:
Follow(E) = { #,) }
Follow(E′'′) = { # }
Follow(T) = { #,+ }
Follow(T′'′) = { #,+ }
Follow(F) = {#,+ ,* }
-
-
第二次查看所有式子
-
从E→TE′E{\rightarrow} TE'E→TE′可得
-
Follow(E)可以加入到Follow(E′'′),将 ) 置入Follow(E′'′)
-
Follow(E)可以加入到Follow(T),将 ) 置入Follow(T)
-
First(E′'′)中非ε{\varepsilon}ε元素可以加入到Follow(T)中,已有+,Follow(T)无变化
当前Follow集:
Follow(E) = { #,) }
Follow(E′'′) = { # ,) }
Follow(T) = { #,+ ,) }
Follow(T′'′) = { #,+ }
Follow(F) = {#,+ ,* }
-
-
从E′→+TE′∣εE'{\rightarrow}+TE'|\varepsilonE′→+TE′∣ε 可得
- Follow(E′'′)可以加入到Follow(T),无变化
- 从T→FT′T{\rightarrow}FT'T→FT′可以得到
-
Follow(T)可以加入到Follow(T′'′),将 ) 置入Follow(T′'′)
-
Follow(T)可以加入到Follow(F),将 )置入Follow(F)
-
First(T′'′)中非ε{\varepsilon}ε元素可以加入到Follow(F)中,已有*,Follow(F)无变化
当前Follow集:
Follow(E) = { #,) }
Follow(E′'′) = { # ,) }
Follow(T) = { #,+ ,) }
Follow(T′'′) = { #,+,) }
Follow(F) = {#,+ ,*,) }
- 从T′→∗FT′∣εT'{\rightarrow}*FT'|\varepsilonT′→∗FT′∣ε 可得
- Follow(T′'′)可以加入到Follow(F),无变化
- 从F→(E)∣iF{\rightarrow}(E)|iF→(E)∣i 并不能得到新的结果
- 再次查看所有式子,均不能产生新的变化,求Follow集完毕
- 注:理论上每次Follow集产生变化就要重新查看一遍所有式子,这里为了方便进行了简写,实际做题时可以按照变化一次重新求一次
那么在已知First集和Follow集的情况下如何构造LL1分析表呢
First集与Follow集:
First(E) = {(,i }
First(E′'′) = {+,ε{\varepsilon}ε}
First(T) = { (,i }
First(T′'′) = { *,ε{\varepsilon}ε}
First(F) = { (,i }
Follow(E) = { #,) }
Follow(E′'′) = { # ,) }
Follow(T) = { #,+ ,) }
Follow(T′'′) = { #,+,) }
Follow(F) = {#,+ ,*,) }
LL1分析表:
第一列为非终结符,第一行为终结符
| i | + | * | ( | ) | # | |
|---|---|---|---|---|---|---|
| E | E遇到 i,i ϵ{ \epsilon}ϵ First(E),且E只有一个候选式,填入E→TE′E{\rightarrow} TE'E→TE′ | E遇到(,( ϵ{ \epsilon}ϵ First(E),且E只有一个候选式,填入E→TE′E{\rightarrow} TE'E→TE′ | ||||
| E’ | + ϵ{ \epsilon}ϵ First(E′'′),在E’的候选式中选择+开头的, 填入E′→+TE′E'{\rightarrow}+TE'E′→+TE′ | First(E′'′)中含有ε{\varepsilon}ε,故E’遇到Follow(E′'′)中的终结符时均填入E′→εE'{\rightarrow} {\varepsilon}E′→ε | E′→εE'{\rightarrow} {\varepsilon}E′→ε | |||
| T | T→FT′T{\rightarrow}FT'T→FT′ | T→FT′T{\rightarrow}FT'T→FT′ | ||||
| T’ | T′→εT'{\rightarrow} {\varepsilon}T′→ε | T′→∗FT′T'{\rightarrow}*FT'T′→∗FT′ | T′→εT'{\rightarrow} {\varepsilon}T′→ε | T′→εT'{\rightarrow} {\varepsilon}T′→ε | ||
| F | F→iF{\rightarrow}iF→i | F→(E)F{\rightarrow}(E)F→(E) |
注:大写字母表示非终结符,小写字母与符号表示终结符
总结:
- 当非终结符遇到其First集中的终结符时填入相应候选式
- 当非终结符的First集中含有ε{\varepsilon}ε 元素时,遇到其Follow集中的终结符时填入
非终结符→ε{\rightarrow} {\varepsilon}→ε
如有错误欢迎指正

1万+

被折叠的 条评论
为什么被折叠?



