文章目录
一、构造预测分析表
①首先构造FIRST集合与FOLLOW集合;
②然后根据两个集合构造预测分析表。
1.FIRST集合
(1)定义3.10
文法符号序列α的FIRST集合为: F I R S T ( α ) = { a ∣ α = ∗ > a . . . , a ∈ T } FIRST(α)=\{a|α=*>a...,a∈T\} FIRST(α)={a∣α=∗>a...,a∈T},若 α = ∗ > ε α=*>ε α=∗>ε,则 ε ∈ F I R S T ( α ) ε∈FIRST(α) ε∈FIRST(α)。
解析:
- FIRST()内是文法符号序列α(包括终结符、非终结符)
- a a a表示终结符。
- 通俗地讲,文法符号序列α的FIRST集合就是从α开始可以导出的文法符号序列中的开头终结符。(开头意思是FIRST集合只取第一个终结符)
(2)算法3.5 文法符号X
- 输入:文法符号X
- 输出:X的FIRST集合
- 方法:
- 若X是终结符,则就是自身,FIRST(X)={X};
- 若X是非终结符且有X→ε,则加入ε到FIRST(X);
- 若X是非终结符且有 X → X 1 X 2 . . . X k X→X_1X_2...X_k X→X1X2...Xk,FIRST(X)= FIRST( X 1 X 2 . . . X k X_1X_2...X_k X1X2...Xk),同FISRT(文法符号序列)的方法
(3)FISRT(文法符号序列)
设
X
0
=
ε
X_0=ε
X0=ε,
X
k
+
1
=
ε
X_{k+1}=ε
Xk+1=ε。
F
I
R
S
T
(
X
1
X
2
.
.
.
X
n
)
FIRST(X_1X_2...X_n)
FIRST(X1X2...Xn)是所有
F
I
R
S
T
(
X
i
)
(
i
=
1
,
2
,
.
.
,
k
)
−
{
ε
}
\textcolor{blue}{FIRST(X_i)(i=1,2,..,k)-\{ε\}}
FIRST(Xi)(i=1,2,..,k)−{ε}的并集,其中
X
k
X_k
Xk为第一个具有ε不属于
F
I
R
S
T
(
X
j
)
FIRST(X_j)
FIRST(Xj)性质或k>n的文法符号,从
1
∼
k
−
1
1\sim k-1
1∼k−1每个
X
X
X都满足
ε
∈
F
I
R
S
T
(
X
i
)
ε∈FIRST(X_i)
ε∈FIRST(Xi)
若k>n,则将ε加入
F
I
R
S
T
(
X
1
X
2
.
.
.
X
n
)
FIRST(X_1X_2...X_n)
FIRST(X1X2...Xn),即所有
F
I
R
S
T
(
X
i
)
−
{
ε
}
{FIRST(X_i)-\{ε\}}
FIRST(Xi)−{ε}的并集再加上ε。
(4)例:
文法G为
S→Ap|Bq
,A→a|cA
,B→dB|ε
FIRST(a) = {a}
,FIRST(ε) = {ε}
FIRST(B) = {d,ε}
,FIRST(A) = {a,c}
,FIRST(S) = {a,c,d,q}
FIRST(cA) = {c}
,FIRST(dB) = {d}
FIRST(Aq) = FIRST(A) = {a,c}
,第一个就是
X
k
X_k
Xk,
FIRST(Bq) = FIRST(B) - {ε} U FIRST(q) = {d,q}
,第二个就是
X
k
X_k
Xk
更多例子:FIRST(a)集合
2.FOLLOW集合
(1)定义3.11
非终结符A的FOLLOW集合如下:
F
O
L
L
O
W
(
A
)
=
{
a
∣
S
=
∗
>
.
.
.
A
a
.
.
.
,
a
∈
T
}
FOLLOW(A) = \{a |S=*>...Aa...,a∈T\}
FOLLOW(A)={a∣S=∗>...Aa...,a∈T}。
若A是某句型的最右符号,则 # ∈ F O L L O W ( A ) \#∈FOLLOW(A) #∈FOLLOW(A)。
解析:
A的FOLLOW集合,就是从开始符号可以导出的所有含A的文法符号序列中紧跟A之后的终结符。
(2)算法3.6
- 输入:文法G
- 输出:G中所有非终结符的FOLLOW集合
- 方法:
- 加入#到FOLLOW(S),其中S是开始符号,#是输入结束标记
- 若有产生式A→αB,则FOLLOW(A)的全体加入到FOLLOW(B)。
- 若有产生式A→αBβ,
①先将 F I R S T ( β ) \color{blue}FIRST(β) FIRST(β) 除ε外的全体加入到FOLLOW(B)。
②然后判断如果 ε ∈ F I R S T ( β ) \color{blue}ε∈FIRST(β) ε∈FIRST(β) ,则将 F O L L O W ( A ) \color{blue}FOLLOW(A) FOLLOW(A)的全体加入到FOLLOW(B)。
【先first,再follow,都是FOLLOW(A)】
解析:
这个α可以是终结符,也可以是非终结符(S→AB,那么FOLLOW(B)=FOLLOW(S)
),我们只关心后面的β。
规则1只对开始符号起作用
(3)例子
例3.22 计算非终结符的FIRST与FOLLOW。
L →E;L|ε
(1)
E →TE'
(2)
E'→+TE'|-TE'|ε
(3)
T →FT'
(4)
T'→*FT'|/FT'|mod FT'|ε
(5)
F →(E)|id|num
(6)
自下而上计算FIRST(倒着,倒数第一)
自上而下计算FOLLOW(顺着FOLLOW)
解:
FIRST(F) = {( id num}
FIRST(T') = {* / mod ε}
FIRST(T) = FIRST(F) = {( id num}
FIRST(E') = {+ - ε}
FIRST(E) = FIRST(T) = FIRST(F) = {( id num}
FIRST(L) = {ε}∪FIRST(E) = {ε ( id num}
FOLLOW(L) = {#} // 规则1
FOLL0W(E) = {) ;} // (1)(6)规则3①
FOLLOW(E') = FOLL0W(E) = {) ;} // (2)(3)规则2
FOLLOW(T) = {+ - ) ;} // (2)(3)规则3①{+ -}和②{) ;}
FOLLOW(T') = FOLLOW(T) = {+ - ; )} // (4)(5)规则2
FOLLOW(F) = {* / mod + - ) ;} // (4)(5)规则3①{* / mod}和②{+ - ) ;}
3.算法3.7 构造预测分析表
- 输入:文法G
- 输出:分析表M
- 方法:
- 对文法的每个产生式A→α,执行2和3;
(分析表的行首是每个产生式的左部非终结符,列首是每个终结符和#)
【注意列首中没有ε那一列,ε列要填产生式相关部分就是ε,会和FOLLOW集填入的ε冲突。所以ε就要看有没有填入FOLLOW列就知道】 - 对 F I R S T ( α ) \color{blue}FIRST(α) FIRST(α)的每个终结符a,加入 产 生 式 右 部 相 关 部 分 \color{red}产生式右部相关部分 产生式右部相关部分到M[A,a];
- 若 ε ∈ F I R S T ( α ) \color{blue}ε∈FIRST(α) ε∈FIRST(α),则对 F O L L O W ( A ) \color{blue}FOLLOW(A) FOLLOW(A)的每个终结符b(包括#),加入 ε \color{red}ε ε到M[A,b];
- M中其它没有定义的条目均是error。
例:
L →E;L|ε
(1)
E →TE'
(2)
E'→+TE'|-TE'|ε
(3)
T →FT'
(4)
T'→*FT'|/FT'|mod FT'|ε
(5)
F →(E)|id|num
(6)
FIRST(F/T/E)= {( id num}
FIRST(T') = {* / mod ε}
FIRST(E') = {+ - ε}
FIRST(L) = {ε ( id num}
FOLLOW(L) = {#}
FOLL0W(E/E')= {) ;}
FOLLOW(T/T')= {+ - ; )}
FOLLOW(F) = {+ - * / mod ) ;}
比如F
行,FIRST(F) = {( id num}
,比如列(
,对应产生式是F→(E)
,将产生式右部相关部分(E)
填入列(
比如T'
行,FIRST(T') = {* / mod ε}
,填入对应的产生式右部相关部分后,有ε填FOLLOW,FOLLOW(T')= {+ - ; )}
,将这几列中填入ε
二、预测
已知某文法 G 如下所示,其中,S、A、B 为非终结符且 S 为开始符号。
G:S→AB
,A→aA |bA|ε
,B→cB |ε
根据前面的计算结果说明在基于预测分析器的语法分析过程中,当要展开的非终结符为A时,如何根据输入的下一个终结符选择具体的候选项。
FIRST(B) = {c, ε}
FIRST(A) = {a, b, ε}
FIRST(S) = {a, b, c, ε}
FOLLOW(S) = {#}
FOLLOW(A) = {c, #}
FOLLOW(B) = {#}
若输入为 a 则按照 aA 展开;【产生式,很好理解,这是FIRST集中的a】
若输入为 b 则按照 bA;【产生式,很好理解,这是FIRST集中的b】
若输入为 c 或#则按照ε展开。【A产生式展开不出c或#开头的,那就展开成ε,要给剩下的非终结符展开去匹配。这就是FOLLOW集的意义。】