自顶向下的语法分析(1)
输入一个终结符串,求解该串是否合法,并指出转换路径.
自顶向下语法分析方法(即推导法)是从文法开始符S出发,逐步进行推导,以证实
的推导过程是否存在的方法。
- 推导哪一个非终结符
- 选取哪条路径
(1)通常使用最左推导原则.
问题⑵通常需要穷举每一个规则的可能推导,即不确定的自顶向下语法分析。具体思想是:
一旦寻找到一个符号串α之推导过程,便结束穷举过程,断定符号串α是句子.只有当穷举全部可能的推导,而没有一个符号串α之推导过程的时候,才可以断定符号串α不是句子。
自顶向下的思想
对于问题⑵ “选择非终结符A的哪一个规则进行推导”,选择唯一的可能推导出输入串α的规则进行推导。
如果没有一个可能推导出输入串α的规则,则结束推导,宣告输入串α不是句子。
- “唯一”意味着非终结符U的其它任意规则,不可能推导出输入串α.
- “唯一”意味着每次选择非终结符U哪一个规则时,选择是“确定的”。
自顶向下的语法分析,重点就在于如何得到可以唯一确定路径的文法规则.
FIRST集
定义:
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}
求法
对
进行最左推导直至开头是终结符.注意尝试多种推导路径
纯终结符的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个集合合并考虑,以确定在什么 情况下选择该规则。
SELECT(A→α)称为规则A→α的选择集。它是FIRST(α) 和FOLLOW(A)组成,是终结符号集VT的子集.
LL1
定义
文法G是LL(1)文法的充分必要条件是文法G每个
规则,满足下列条件:
即SELECT无交集.
性质
假定文法G是LL(1)文法,在S->α 最左推导过程中,遇到选用U规则时,如果输入串α 的当前符号a,属于某个U规则的 SELECT(U→αi),则采用U→αi进行唯一可能正确的推导。 如果当前符号a,不属于任何一个U规则的 SELECT(U→αi), 则结束推导,同时断定α不是文法G的句子。
确定的自顶向下语法分析不必穷举所有的推导过程,避免 了回溯现象,极大地提高了语法分析的效率。这里“确定的” 意指选择规则的确定性。这类分析法,也称为不带回溯的自顶向下语法分析。
理解
这种LL1文法明确了推导路径,如果当前符号a落在某个推导路径的SELECT中(并且只可能落在这里),则使用该路径而不需要进行尝试.如果在所有的SELECT外,则不构成句子.
Example
文法:
输入串:
首先确认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}
检查同一个左部下的右部,
都是empty,是LL1.
所以输入串的推导唯一确定.
LL1的判别
实质上是计算每个右部的SELECT的交集.
- 判断SELECT的选择路径,通过是否可推导出 .
- 计算SELECT
- 检查同一个左部的交集
自动化计算可以推导 的非终结符
- 初始化X[]为
Undefined
- 删除规则所有右部至少含有一个终结符的规则。若删除后 某非终结符A的所有规则都被删除,置X[A]为“否”
- 对所有空规则(A→ε),置X[A]为“是”,并删除左部 为A所有规则
- Loop:
- 剩下的规则中:如果某规则右部非终结符都是Y,设置X[A]=Y,删除所有规则
- 删除右部含有标记为N的非终结符的规则;如果删除后规则为空,设置X[A]=N
- Until X[]不再变化
X[]是一个非终结符为下标、元素个数为 的一维数组。数组元素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( )
确定了所有的FIRST(X),自动求终结符+非终结符的串的FIRST.
如果 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 (串+非终结符+串),FOLLOW(B) add(FIRST(β)-{ε})
- if ,FOLLOW(B) add FOLLOW(A)
- Until 稳定解
SUM
- FITRST集:针对终结符+非终结符的串,是推导结果的首字的集合.主要推导出每个右部的FIRST.
- FOLLOW集:针对非终结符,是推导过程中(几步推导)该非终结符后一个相邻的终结符的集合或者尾符#
- SELECT集:针对规则:
- 如果该式起始不能推导到empty,为右部的FIRST;
- 否则,为
LL1的判定
- 计算可以推出empty的非终结符
- 计算非终结符的FIRST
- 计算右部的FIRST
- 计算非终结符的FOLLOW
- 计算每条规则的SELECT
- 查看同一左部是否有交集
See:
https://www.cnblogs.com/standby/p/6792774.html
https://www.cnblogs.com/standby/p/6792814.html