如何求First集与Follow集
已知文法如下,求First集与Follow集
G
[
E
]
:
E
→
T
E
′
E
′
→
+
T
E
′
∣
ε
T
→
F
T
′
T
′
→
∗
F
T
′
∣
ε
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 → T E ′ E{\rightarrow} TE' E→TE′,候选式中未包含终结符,暂时无法得出结果
当前First集:
First(E) = { }
First(E ′ ' ′) = { }
First(T) = { }
First(T ′ ' ′) = { }
First(F) = { } -
第二个式子: E ′ → + T E ′ ∣ ε E'{\rightarrow}+TE'|\varepsilon E′→+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 ) ∣ i F{\rightarrow}(E)|i F→(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 → Y X{\rightarrow}Y X→Y, Y Y Y是非终结符,就把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 → T E ′ 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 ′ → + T E ′ ∣ ε E'{\rightarrow}+TE'|\varepsilon E′→+TE′∣ε 可得
- Follow(E ′ ' ′)可以加入到Follow(T),无变化
-
从 T → F T ′ 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 ′ → ∗ F T ′ ∣ ε T'{\rightarrow}*FT'|\varepsilon T′→∗FT′∣ε 可得
- Follow(T ′ ' ′)可以加入到Follow(F),无变化
-
从 F → ( E ) ∣ i F{\rightarrow}(E)|i F→(E)∣i 可得
-
非终结符E后有一个终结符 ),故将 ) 置入Follow(E)
当前Follow集:
Follow(E) = { #,) }
Follow(E ′ ' ′) = { # }
Follow(T) = { #,+ }
Follow(T ′ ' ′) = { #,+ }
Follow(F) = {#,+ ,* }
-
-
第二次查看所有式子
-
从 E → T E ′ 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 ′ → + T E ′ ∣ ε E'{\rightarrow}+TE'|\varepsilon E′→+TE′∣ε 可得
- Follow(E ′ ' ′)可以加入到Follow(T),无变化
- 从 T → F T ′ 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 ′ → ∗ F T ′ ∣ ε T'{\rightarrow}*FT'|\varepsilon T′→∗FT′∣ε 可得
- Follow(T ′ ' ′)可以加入到Follow(F),无变化
- 从 F → ( E ) ∣ i F{\rightarrow}(E)|i F→(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 → T E ′ E{\rightarrow} TE' E→TE′ | E遇到(,( ϵ { \epsilon} ϵ First(E),且E只有一个候选式,填入 E → T E ′ E{\rightarrow} TE' E→TE′ | ||||
E’ | + ϵ { \epsilon} ϵ First(E ′ ' ′),在E’的候选式中选择+开头的, 填入 E ′ → + T E ′ E'{\rightarrow}+TE' E′→+TE′ | First(E ′ ' ′)中含有 ε {\varepsilon} ε,故E’遇到Follow(E ′ ' ′)中的终结符时均填入 E ′ → ε E'{\rightarrow} {\varepsilon} E′→ε | E ′ → ε E'{\rightarrow} {\varepsilon} E′→ε | |||
T | T → F T ′ T{\rightarrow}FT' T→FT′ | T → F T ′ T{\rightarrow}FT' T→FT′ | ||||
T’ | T ′ → ε T'{\rightarrow} {\varepsilon} T′→ε | T ′ → ∗ F T ′ T'{\rightarrow}*FT' T′→∗FT′ | T ′ → ε T'{\rightarrow} {\varepsilon} T′→ε | T ′ → ε T'{\rightarrow} {\varepsilon} T′→ε | ||
F | F → i F{\rightarrow}i F→i | F → ( E ) F{\rightarrow}(E) F→(E) |
注:大写字母表示非终结符
,小写字母与符号表示终结符
总结:
- 当非终结符遇到其First集中的终结符时填入相应候选式
- 当非终结符的First集中含有
ε
{\varepsilon}
ε 元素时,遇到其Follow集中的终结符时填入
非终结符
→ ε {\rightarrow} {\varepsilon} →ε
如有错误欢迎指正