FIRST集是一个文法符号串所可能推导出的符号串的第一个终结符的集合
对于文法G的任一符号串 α \alpha α = x 1 x 2 … x n x_{1}x_{2} \ldots x_{n} x1x2…xn
note:
FIRST集从产生式左侧推导,例如求A的FIRST集,要先从产生式左侧找到A,然后根据产生式右侧的信息求出A的FIRST集
例如:
S → \rightarrow → BS ‘ ^` ‘
S ‘ → ^` \rightarrow ‘→ aB | ϵ \epsilon ϵ
B → \rightarrow → DB ‘ ^` ‘
B ‘ → ^` \rightarrow ‘→ b | ϵ \epsilon ϵ
D → \rightarrow → d | ϵ \epsilon ϵ
FIRST(S) = {d, b, a, ϵ \epsilon ϵ}
FIRST(S ‘ ^` ‘) = {a, ϵ \epsilon ϵ}
FIRST(B) = {d, b, ϵ \epsilon ϵ}
FIRST(B ‘ ^` ‘) = {b, ϵ \epsilon ϵ}
FIRST(D) = {d, ϵ \epsilon ϵ}
解释:
第一个求S的FIRST集,先从产生式的左侧找到S, (S → \rightarrow → BS ‘ ^` ‘), 然后根据该产生式右侧的信息(BS ‘ ^` ‘) 和求FIRST集的第二条规则求FIRST(B), 从产生式的左侧找到B, (B → \rightarrow → DB ‘ ^` ‘), 然后根据该产生式右侧的信息(DB ‘ ^` ‘) 和求FIRST集的第二条规则求FIRST(D), 从产生式的左侧找到D, (D → \rightarrow → d | ϵ \epsilon ϵ), 然后根据该产生式右侧的信息(d | ϵ \epsilon ϵ) 和求FIRST集的第二条规则, 将终结符d加入FIRST(S).
F I R S T ( S ) = { d } \color{red} { FIRST(S) = \{d\} } FIRST(S)={d}
又根据第三条规则,因为D → ϵ \rightarrow \epsilon →ϵ, 所以将FIRST(B ‘ ^` ‘) 加入到FIRST(S)中,从产生式的左侧找到B ‘ ^` ‘, (B ‘ → ^` \rightarrow ‘→ b | ϵ \epsilon ϵ), 然后根据该产生式右侧的信息(b | ϵ \epsilon ϵ) 和求FIRST集的第二条规则, 将终结符b加入FIRST(S).
F I R S T ( S ) = { d , b } \color{red} { FIRST(S) = \{d, b\} } FIRST(S)={d,b}
又根据第三条规则,因为B ‘ → ϵ ^` \rightarrow \epsilon ‘→ϵ, 所以将FIRST(S ‘ ^` ‘) 加入到FIRST(S)中,从产生式的左侧找到S ‘ ^` ‘, (S ‘ → ^` \rightarrow ‘→ aB | ϵ \epsilon ϵ), 然后根据该产生式右侧的信息(aB | ϵ \epsilon ϵ) 和求FIRST集的第二条规则, 将终结符a加入FIRST(S).
F I R S T ( S ) = { d , b , a } \color{red} { FIRST(S) = \{d, b, a\} } FIRST(S)={d,b,a}
又根据第四条规则,因为 ϵ ∈ \epsilon \in ϵ∈ FIRST(D) , ϵ ∈ \epsilon \in ϵ∈ FIRST(B ‘ ^` ‘), 所以 ϵ ∈ \epsilon \in ϵ∈ FIRST(B), 又因为 ϵ ∈ \epsilon \in ϵ∈ FIRST(S ‘ ^` ‘), 所以 ϵ ∈ \epsilon \in ϵ∈ FIRST(S). 最终结果如下:
F I R S T ( S ) = { d , b , a , ϵ } \color{red} { FIRST(S) = \{d, b, a, \epsilon\} } FIRST(S)={d,b,a,ϵ}
第二个求S ‘ ^` ‘的FIRST集, 先从产生式左侧找到S ‘ ^` ‘, (S ‘ → ^` \rightarrow ‘→ aB | ϵ \epsilon ϵ), 然后根据产生式右侧的信息(aB | ϵ \epsilon ϵ), S既能推导出aB又能推导出 ϵ \epsilon ϵ, 所以根据规则二和规则四得出:
F I R S T ( S ‘ ) = { a , ϵ } \color{red}{ FIRST(S^`) = \{a, \epsilon\} } FIRST(S‘)={a,ϵ}
第三个求B的FIRST集, 产生式的左侧找到B, (B → \rightarrow → DB ‘ ^` ‘), 然后根据该产生式右侧的信息(DB ‘ ^` ‘) 和求FIRST集的第二条规则求FIRST(D), 从产生式的左侧找到D, (D → \rightarrow → d | ϵ \epsilon ϵ), 然后根据该产生式右侧的信息(d | ϵ \epsilon ϵ) 和求FIRST集的第二条规则, 将终结符d加入FIRST(B).
F I R S T ( B ) = { d } \color{red} { FIRST(B) = \{d\} } FIRST(B)={d}
又根据第三条规则,因为D → ϵ \rightarrow \epsilon →ϵ, 所以将FIRST(B ‘ ^` ‘) 加入到FIRST(B)中,从产生式的左侧找到B ‘ ^` ‘, (B ‘ → ^` \rightarrow ‘→ b | ϵ \epsilon ϵ), 然后根据该产生式右侧的信息(b | ϵ \epsilon ϵ) 和求FIRST集的第二条规则, 将终结符b加入FIRST(B).
F I R S T ( B ) = { d , b } \color{red} { FIRST(B) = \{d, b\} } FIRST(B)={d,b}
又根据第四条规则,因为 ϵ ∈ \epsilon \in ϵ∈ FIRST(D) , ϵ ∈ \epsilon \in ϵ∈ FIRST(B ‘ ^` ‘), 所以 ϵ ∈ \epsilon \in ϵ∈ FIRST(B), 最终结果如下:
F I R S T ( B ) = { d , b , ϵ } \color{red} { FIRST(B) = \{d, b, \epsilon\} } FIRST(B)={d,b,ϵ}
求第四个B ‘ ^` ‘的FIRST集和第五个求D的FIRST集同求第二个求S ‘ ^` ‘的FIRST集,结果为:
F I R S T ( B ‘ ) = { b , ϵ } F I R S T ( D ) = { d , ϵ } \color{red} { FIRST(B^`) = \{b, \epsilon\} }\\ { FIRST(D) = \{d, \epsilon\} } FIRST(B‘)={b,ϵ}FIRST(D)={d,ϵ}
FOLLOW集是文法符号后面可能跟随的终结符的集合(不包括空串)
note:
例如:
S → \rightarrow → BS ‘ ^` ‘
S ‘ → ^` \rightarrow ‘→ aB | ϵ \epsilon ϵ
B → \rightarrow → DB ‘ ^` ‘
B ‘ → ^` \rightarrow ‘→ b | ϵ \epsilon ϵ
D → \rightarrow → d | ϵ \epsilon ϵ
FOLLOW(S) = {#}
FOLLOW(S ‘ ^` ‘) = {#}
FOLLOW(B) = FIRST(S ‘ ^` ‘) \ | ϵ \epsilon ϵ| ∪ \cup ∪ FOLLOW(S ‘ ^` ‘) ∪ \cup ∪ FOLLOW(S) = {a, #}
FOLLOW(B ‘ ^` ‘) = FOLLOW(B) = {a, #}
FOLLOW(D) = FIRST(B ‘ ^` ‘) \ | ϵ \epsilon ϵ| ∪ \cup ∪ FOLLOW(B) = {b, a, #}
解释:
第一个求S的FOLLOW集, 因为S是开始符号,所以将#加入到FOLLOW(S)中,从产生式右侧找S,没有找到,所以最终结果:
F O L L O W ( S ) = { # } \color{red} { FOLLOW(S) = \{ \# \} } FOLLOW(S)={#}
第二个求S ‘ ^` ‘的FOLLOW集, 从产生式右侧找S ‘ ^` ‘, (S → \rightarrow → BS ‘ ^` ‘), 根据右侧符号信息和求FOLLOW集的第三条规则,将 FOLLOW(S) 加入到 FOLLOW(S ‘ ^` ‘) 中,最终结果:
F O L L O W ( S ‘ ) = { # } \color{red} { FOLLOW(S^`) = \{ \# \} } FOLLOW(S‘)={#}
第三个求B的FOLLOW集,从产生式右侧找到B,(S → \rightarrow → BS ‘ ^` ‘ 、S ‘ → ^` \rightarrow ‘→ aB | ϵ \epsilon ϵ), 根据 S → \rightarrow → BS ‘ ^` ‘ 和第二条规则,得:
F O L L O W ( B ) = F I R S T ( S ‘ ) ∖ ∣ ϵ ∣ = { a } \color{red} { FOLLOW(B) = FIRST(S^`) \setminus |\epsilon| = \{a\} } FOLLOW(B)=FIRST(S‘)∖∣ϵ∣={a}
根据S ‘ → ^` \rightarrow ‘→ aB 和第三条规则,得:
F O L L O W ( B ) = F O L L O W ( S ‘ ) = { a , # } \color{red} { FOLLOW(B) = FOLLOW(S^`) = \{a, \# \} } FOLLOW(B)=FOLLOW(S‘)={a,#}
又因为S ‘ → ϵ ^` \rightarrow \epsilon ‘→ϵ, 根据S → \rightarrow → BS ‘ ^` ‘ 和第三条规则,得:
F O L L O W ( B ) = F O L L O W ( S ) = { a , # } \color{red} { FOLLOW(B) = FOLLOW(S) = \{a, \#\} } FOLLOW(B)=FOLLOW(S)={a,#}
第四个求B ‘ ^` ‘的FOLLOW集,从产生式的右侧找到B ‘ ^` ‘, (B → \rightarrow → DB ‘ ^` ‘), 根据第三条规则,得:
F O L L O W ( B ‘ ) = F O L L O W ( B ) = { a , # } \color{red} { FOLLOW(B^`) = FOLLOW(B) = \{a, \#\} } FOLLOW(B‘)=FOLLOW(B)={a,#}
第五个求D的FOLLOW集,从产生式的右侧找到D, (B → \rightarrow → DB ‘ ^` ‘), 根据第二条规则,得:
F O L L O W ( D ) = F I R S T ( B ‘ ) ∖ ∣ ϵ ∣ = { b } \color{red} { FOLLOW(D) = FIRST(B^`) \setminus |\epsilon| = \{b\} } FOLLOW(D)=FIRST(B‘)∖∣ϵ∣={b}
又因为B ‘ → ϵ ^` \rightarrow \epsilon ‘→ϵ, 根据 B → \rightarrow → DB ‘ ^` ‘ 和第三条规则,得:
F O L L O W ( D ) = F O L L O W ( B ) = { b , a , # } \color{red} { FOLLOW(D) = FOLLOW(B) = \{b, a, \#\} } FOLLOW(D)=FOLLOW(B)={b,a,#}
note:
每个产生式的意思是将所有含“|”的产生式全部展开,然后看每个产生式的FIRST集,如果这个FIRST集中有“ ϵ \epsilon ϵ”, 那就要将这个产生式加入到 FOLLOW集中相应符号中
已知文法G如下:
S → \rightarrow → AB
A → \rightarrow → Ba | ϵ \epsilon ϵ
B → \rightarrow → Db | D
D → \rightarrow → d | ϵ \epsilon ϵ
(1) 构建文法G的LL(1)分析表
(2) 判断句子adb是否为有效文法产生的语言,并给出分析过程
因为 S ⇒ \Rightarrow ⇒ A ⇒ \Rightarrow ⇒ B ⇒ \Rightarrow ⇒ D ⇒ ̸ \Rightarrow \not ⇏ S, 所以不存在左递归
因为将 A → \rightarrow → Ba | ϵ \epsilon ϵ 代入到 S → \rightarrow → AB 会含有回溯,B → \rightarrow → Db | D 这条产生式本身也含有回溯,所以要先消除回溯
消除左递归(本题不需要消除左递归):
P的产生式: P → \rightarrow → Pa 1 _1 1 | Pa 2 _2 2 | … | Pa m _m m | β 1 \beta_1 β1 | β 2 \beta_2 β2 | … | β n \beta_n βn
其中,每个a不等于 ϵ \epsilon ϵ, 每个 β \beta β不以P开头
P → β 1 P ‘ \rightarrow \beta_1 P^` →β1P‘ | β 2 P ‘ \beta_2 P^` β2P‘ | … | β n P ‘ \beta_n P^` βnP‘
P ‘ → a 1 P ‘ ^` \rightarrow a_1 P^` ‘→a1P‘ | a 2 P ‘ a_2 P^` a2P‘ | … | a m P ‘ a_m P^` amP‘
消除回溯(提左因子)
A的规则是: A → δ β 1 \rightarrow \delta \beta_1 →δβ1 | δ β 2 \delta \beta_2 δβ2 | … | δ β n \delta \beta_n δβn | γ 1 \gamma_1 γ1 | γ 2 \gamma_2 γ2 | … | γ m \gamma_m γm
其中,每个 γ \gamma γ不以 δ \delta δ开头
A → δ A ‘ \rightarrow \delta A^` →δA‘ | γ 1 \gamma_1 γ1 | γ 2 \gamma_2 γ2 | … | γ m \gamma_m γm
A ‘ → β 1 ^` \rightarrow \beta_1 ‘→β1 | β 2 \beta_2 β2 | … | β n \beta_n βn
通过消除回溯,将文法改写为:
S → \rightarrow → BS ‘ ^` ‘
S ‘ → ^` \rightarrow ‘→ aB | ϵ \epsilon ϵ
B → \rightarrow → DB ‘ ^` ‘
B ‘ → ^` \rightarrow ‘→ b | ϵ \epsilon ϵ
D → \rightarrow → d | ϵ \epsilon ϵ
通过拆分上边的产生式,得到:
先看这八个产生式的FIRST集,如果FIRST集中有 ϵ \epsilon ϵ, 就要看相应产生式的FOLLOW集(例如产生式3、6、8)
终结符: {a, b, d, #}
非终结符: {S, S ‘ ^` ‘, B, B ‘ ^` ‘, D}
FIRST(S) = {a, b, d, ϵ \epsilon ϵ} FOLLOW(S) = {#}
FIRST(S ‘ ^` ‘) = {a, ϵ \epsilon ϵ} FOLLOW(S ‘ ^` ‘) = {#}
FIRST(B) = {d, b, ϵ \epsilon ϵ} FOLLOW(B) = {a, #}
FIRST(B ‘ ^` ‘) = {b, ϵ \epsilon ϵ} FOLLOW(B ‘ ^` ‘) = {a, #}
FIRST(D) = {d, ϵ \epsilon ϵ} FOLLOW(D) = {b, a, #}
解释:
先看S这一行,因为第一条产生式 FIRST(BS ‘ ^` ‘) = {a, b, d, ϵ \epsilon ϵ},所以根据第二条规则,在a, b, d列填入BS ‘ ^` ‘,又因为 ϵ ∈ \epsilon \in ϵ∈ FIRST(BS ‘ ^` ‘), 所以还要看S的FOLLOW集,FOLLOW(S) = {#},所以在#这一列也填入BS ‘ ^` ‘
看S ‘ ^` ‘这一行,第二条产生式 FIRST(aB) = {a}, 根据第二条规则,在a这一列填入aB
又因为第三条产生式S ‘ → ϵ ^` \rightarrow \epsilon ‘→ϵ, ϵ ∈ \epsilon \in ϵ∈ FIRST(S ‘ ^` ‘), 所以看S ‘ ^` ‘的FOLLOW集,FOLLOW(S ‘ ^` ‘) = {#}, 所以在#这一列填入 ϵ \epsilon ϵ (这个 ϵ \epsilon ϵ 由S ‘ → ϵ ^` \rightarrow \epsilon ‘→ϵ这条产生式得出)
看B这一行,因为第四条产生式 FIRST(DB ‘ ^` ‘) = {d, b, ϵ \epsilon ϵ}, 根据第二条规则,在d, b列填入DB ‘ ^` ‘, 又因为 ϵ ∈ \epsilon \in ϵ∈ FIRST(DB ‘ ^` ‘), 所以看B的FOLLOW集,因为FOLLOW(B) = {a, #}, 所以在a, #列填入DB ‘ ^` ‘
看B ‘ ^` ‘这一行,因为第五条产生式 FIRST(b) = {b}, 所以在b列填入b
又因为第六条产生式B ‘ → ϵ ^` \rightarrow \epsilon ‘→ϵ, ϵ ∈ \epsilon \in ϵ∈ FIRST(B ‘ ^` ‘), 所以看B ‘ ^` ‘的FOLLOW集,FOLLOW(B ‘ ^` ‘) = {a, #}, 所以在a, #列填入 ϵ \epsilon ϵ
看D这一行,因为第七条产生式 FIRST(d) = {d}, 所以在d列填入d
又因为第八条产生式 D → ϵ \rightarrow \epsilon →ϵ, ϵ ∈ \epsilon \in ϵ∈ FIRST(D), 所以看D的FOLLOW集,FOLLOW(D) = {a, b, #}, 所以在a, b, #列填入 ϵ \epsilon ϵ
栈STACK用于存放文法符号。分析开始时,栈底先放一个’#’, 然后,放进文法开始符号。同时,假定输入串之后也总有一个‘#’,标志输入串结束
对于任何(X, a), 总控程序每次都执行下述三种可能的动作之一