自顶向下的语法分析(1)
输入一个终结符串,求解该串是否合法,并指出转换路径.
自顶向下语法分析方法(即推导法)是从文法开始符S出发,逐步进行推导,以证实
S
→
α
S\rightarrow\alpha
S→α的推导过程是否存在的方法。
- 推导哪一个非终结符
- 选取哪条路径
(1)通常使用最左推导原则.
问题⑵通常需要穷举每一个规则的可能推导,即不确定的自顶向下语法分析。具体思想是:
一旦寻找到一个符号串α之推导过程,便结束穷举过程,断定符号串α是句子.只有当穷举全部可能的推导,而没有一个符号串α之推导过程的时候,才可以断定符号串α不是句子。
自顶向下的思想
对于问题⑵ “选择非终结符A的哪一个规则进行推导”,选择唯一的可能推导出输入串α的规则进行推导。
如果没有一个可能推导出输入串α的规则,则结束推导,宣告输入串α不是句子。
- “唯一”意味着非终结符U的其它任意规则,不可能推导出输入串α.
- “唯一”意味着每次选择非终结符U哪一个规则时,选择是“确定的”。
自顶向下的语法分析,重点就在于如何得到可以唯一确定路径的文法规则.
FIRST集
定义:
F
i
r
s
t
(
α
)
=
{
a
∣
α
→
∗
a
A
,
a
∈
V
T
,
α
,
A
∈
V
∗
}
First(\alpha)=\{a|\alpha\rightarrow^* aA,a\in V_T,\alpha,A\in V^*\}
First(α)={a∣α→∗aA,a∈VT,α,A∈V∗}
FIRST(α)是由α可以推导以终结符号开头符号串的头符号集合。如果所有非终结符右部的FIRST集合两两相交为空,可以使用确定的最左推导。
First的参量可以是终结符或非终结符或混合串.结果是终结符的集合.
e.g.
设文法G [S]:S→Ap︱Bq,A→cA︱a,B→dB︱b,则
FIRST(cA)= {c}
FIRST(A)= {c,a}
FIRST(Ap)= {c,a}
FIRST(Bq)= {d,b}
cA->ccA->ccc…A 头字符都是终结符c,就是{c}.
A->cA&a,就是{c,a}
求法
对
α
\alpha
α进行最左推导直至开头是终结符.注意尝试多种推导路径
纯终结符的first集是自己.
性质
如果所有非终结符右部的FIRST集合两两相交为空,可以使用确定的最左推导.
在上个例子中:
需要检查的是Ap,Bq,cA,a,dB,b
如果没有相交则可以通过最左推导唯一推导.
FOLLOW集
在最左推导中,一旦句型的最左非终结符A,除空规则外,其它所有规则都不可能推导出由输入符(假定为ai )开头的符号序列,这时使用空规则,意味着将匹配d的工作交给了句型A之后的部分,也就是后面这部分要能推导出以ai开头的符号串才有可能匹配成功。
如果输入符号d能在某个句型中能出现在A的后面,可以使用了A的空规则再继续分析,否则即使使用了A的空规则,后面的推导也不可能匹配。所以需要对文法进行分析,文法的所有句型中,任意一个非终结符后可能出现的终结符的集合。
输 入 串: a1a2……ai-1 ai……an
句型推导到:S-> a1a2……ai-1 Aβ
如果使用空规则,意味着需要:β -> ai……an 才会有句型: S->a1a2……ai-1 A ai……an
定义
FOLLOW(A)是由任意句型中紧邻非终结符号A之后出现的终结符号a组成的集合。
e.g.
设文法G [S]:S→Ap︱Bq,A→cA︱a,B→dB︱b,则
FOLLOW(S)={None}
Follow(A)={p}
Follow(B)={q}
性质
如果对非终结符A,有一条空规则,则A的FOLLOW集合和A的非空右部的FIRST集合两两相交为空,可以使用确定的最左推导。
SELECT集(*)
使用统一的方法来选择使用规则,即当某规则右部能推导出 空时,将其FIRST和FOLLOW这2个集合合并考虑,以确定在什么 情况下选择该规则。
文
法
G
,
A
∈
V
N
,
A
→
α
∈
P
S
E
L
E
C
T
(
A
→
α
)
=
F
I
R
S
T
(
α
)
,
w
h
e
n
(
α
̸
⇒
∗
ξ
)
o
r
=
(
F
I
R
S
T
(
α
)
−
{
ξ
}
)
∪
F
O
L
L
O
W
(
A
)
w
h
e
n
α
⇒
∗
ξ
文法G,A\in V_N,A\rightarrow \alpha\in P\\SELECT(A\rightarrow\alpha)=FIRST(\alpha),when(\alpha\not\Rightarrow^* \xi)\\or=(FIRST(\alpha)-\{\xi\})\cup FOLLOW(A)when\alpha\Rightarrow^*\xi
文法G,A∈VN,A→α∈PSELECT(A→α)=FIRST(α),when(α⇒∗ξ)or=(FIRST(α)−{ξ})∪FOLLOW(A)whenα⇒∗ξ
SELECT(A→α)称为规则A→α的选择集。它是FIRST(α) 和FOLLOW(A)组成,是终结符号集VT的子集.
LL1
定义
文法G是LL(1)文法的充分必要条件是文法G每个
U
→
α
1
︱
α
2
︱
⋅
⋅
⋅
︱
α
n
U→α1︱α2︱···︱α n
U→α1︱α2︱⋅⋅⋅︱αn规则,满足下列条件:
S
E
L
E
C
T
(
U
→
α
i
)
∩
S
E
L
E
C
T
(
U
→
α
j
)
=
∅
SELECT(U→αi)\cap SELECT(U→αj)=\empty
SELECT(U→αi)∩SELECT(U→αj)=∅
(
i
≠
j
,
1
≤
i
≤
n
,
1
≤
j
≤
n
)
(i≠j ,1≤i≤n,1≤j≤n)
(i=j,1≤i≤n,1≤j≤n)
即SELECT无交集.
性质
假定文法G是LL(1)文法,在S->α 最左推导过程中,遇到选用U规则时,如果输入串α 的当前符号a,属于某个U规则的 SELECT(U→αi),则采用U→αi进行唯一可能正确的推导。 如果当前符号a,不属于任何一个U规则的 SELECT(U→αi), 则结束推导,同时断定α不是文法G的句子。
确定的自顶向下语法分析不必穷举所有的推导过程,避免 了回溯现象,极大地提高了语法分析的效率。这里“确定的” 意指选择规则的确定性。这类分析法,也称为不带回溯的自顶向下语法分析。
理解
这种LL1文法明确了推导路径,如果当前符号a落在某个推导路径的SELECT中(并且只可能落在这里),则使用该路径而不需要进行尝试.如果在所有的SELECT外,则不构成句子.
Example
文法:
G
1
[
S
]
:
S
→
p
A
∣
q
B
A
→
c
A
d
∣
a
B
→
d
B
∣
b
G1[S]:S\rightarrow pA|qB\\A\rightarrow cAd|a\\B\rightarrow dB|b
G1[S]:S→pA∣qBA→cAd∣aB→dB∣b
输入串:
p
c
c
a
d
d
pccadd
pccadd
首先确认SELECT集:
pa,qb等都推不到ξ,SELECT使用下面的公式:SELECT=FIRST=后续推导的首终结符集合
SELECT(S→pA)={p} , SELECT(S→ qB)={q}
SELECT(A→cAd)={c} , SELECT(A→a)={a}
SELECT(B→dB)={d} , SELECT(B→b)={b}
检查同一个左部下的右部,
S
E
L
E
C
T
(
S
→
p
A
)
∩
S
E
L
E
C
T
(
S
→
q
B
)
=
Φ
S
E
L
E
C
T
(
A
→
c
A
d
)
∩
S
E
L
E
C
T
(
A
→
a
)
=
Φ
S
E
L
E
C
T
(
B
→
d
B
)
∩
S
E
L
E
C
T
(
B
→
b
)
=
Φ
SELECT(S→pA)∩SELECT(S→ qB)=Φ \\SELECT(A→cAd)∩SELECT(A→a)=Φ \\SELECT(B→dB)∩SELECT(B→b) =Φ
SELECT(S→pA)∩SELECT(S→qB)=ΦSELECT(A→cAd)∩SELECT(A→a)=ΦSELECT(B→dB)∩SELECT(B→b)=Φ
都是empty,是LL1.
所以输入串的推导唯一确定.
S
−
>
p
A
−
>
p
c
A
d
−
>
p
c
c
A
d
d
−
>
p
c
c
a
d
d
S->pA->pcAd->pccAdd->pccadd
S−>pA−>pcAd−>pccAdd−>pccadd
LL1的判别
实质上是计算每个右部的SELECT的交集.
- 判断SELECT的选择路径,通过是否可推导出 ξ \xi ξ.
- 计算SELECT
- 检查同一个左部的交集
自动化计算可以推导 ξ \xi ξ的非终结符
- 初始化X[]为
Undefined
- 删除规则所有右部至少含有一个终结符的规则。若删除后 某非终结符A的所有规则都被删除,置X[A]为“否”
- 对所有空规则(A→ε),置X[A]为“是”,并删除左部 为A所有规则
- Loop:
- 剩下的规则中:如果某规则右部非终结符都是Y,设置X[A]=Y,删除所有规则
- 删除右部含有标记为N的非终结符的规则;如果删除后规则为空,设置X[A]=N
- Until X[]不再变化
X[]是一个非终结符为下标、元素个数为 ︱ V N ︱ ︱V_N︱ ︱VN︱的一维数组。数组元素X[A]取值为“ 未定”、“否”和“是”,分别表示非终结符A还不确定能否可推导ε、确定不可推导ε 和确定可推导ε。
理解
和人工确定的步骤类似:
- 右部全部能推出的非终结符可以推出
- 右部全部不能推出的非终结符不可以推出
- 删除,迭代,直到稳定解
自动化计算FIRST(X)
这里X是单个终结符或非终结符.
- 对于所有终结符号X,FIRST(X)={X};
- 对于所有空规则X→ε,FIRST(X)∪={ε}; //Add empty
- 对于所有形如X→a···规则,且a∈VT,FIRST(X)∪={a};//Add a
- 对于所有形如X→Y1 Y2 ···Yn规则, 如果Y1->*ε、Y2->*ε、 ··· 、Yi-1->*ε(i<=n), 则 FIRST(X)∪=(FIRST(Y1 )∪FIRST(Y2 )…∪FIRST(Yi))-{ε}; 如果Y1->*ε、Y2->*ε、 ··· 、Yn->*ε 则 FIRST(X)∪= (FIRST(Y1 )∪FIRST(Y2 )…∪FIRST(Yi ))∪{ε};
- 重复⑷,直到FIRST()不再扩大为止。
自动化确定FIRST( α \alpha α)
确定了所有的FIRST(X),自动求终结符+非终结符的串的FIRST.
α
=
Y
1
.
.
.
Y
n
\alpha=Y_1...Y_n
α=Y1...Yn
如果 Y1 为终结符,则 FIRST(α)={ Y1 };
如果 Y1 ->*ε、Y2 ->*ε、 ··· 、Yi-1 ->*ε(1<i<=n),则 FIRST(α)=(FIRST(Y1 )∪FIRST(Y2 )…∪FIRST(Yi ))-{ε};
如果 Y1 ->*ε、Y2 ->*ε、 ··· 、Yn ->*ε 则 FIRST(α)=(FIRST(Y1 )∪FIRST(Y2 )…∪FIRST(Yn ))∪{ε}。
解释:
- 串的首字为终结符,FIRST只有该终结符(定义)
- 剩下的,如果前i个非终结符都可以推出空,则为这样一个并集,没有empty.此时等价A->…|…|…|…
- 如果捅到底,还要加上empty.(此时等价A->empty)
自动化计算FOLLOW
目标:FOLLOW(X)是任何句型中出现在紧邻非终结符X之后的终结符.
- FOLLOW(S)={#}
- Loop…
- if A → α B β A\rightarrow \alpha B\beta A→αBβ(串+非终结符+串),FOLLOW(B) add(FIRST(β)-{ε})
- if β → ∗ ξ \beta\rightarrow^* \xi β→∗ξ,FOLLOW(B) add FOLLOW(A)
- Until 稳定解
SUM
- FITRST集:针对终结符+非终结符的串,是推导结果的首字的集合.主要推导出每个右部的FIRST.
- FOLLOW集:针对非终结符,是推导过程中(几步推导)该非终结符后一个相邻的终结符的集合或者尾符#
- SELECT集:针对规则:
- 如果该式起始不能推导到empty,为右部的FIRST;
- 否则,为 ( F I R S T ( α ) − ∅ ) ∪ F O L L O W ( A ) (FIRST(\alpha)-\empty)\cup FOLLOW(A) (FIRST(α)−∅)∪FOLLOW(A)
LL1的判定
- 计算可以推出empty的非终结符
- 计算非终结符的FIRST
- 计算右部的FIRST
- 计算非终结符的FOLLOW
- 计算每条规则的SELECT
- 查看同一左部是否有交集
See:
https://www.cnblogs.com/standby/p/6792774.html
https://www.cnblogs.com/standby/p/6792814.html