自上而下分析面临的问题:
1.文法的左递归问题,会使分析过程陷入无限循环。
2.若匹配不成功,需要回溯。需要把已经做过的一大堆工作(各种表格工作、语义分析等)推倒重来,既费时又费力。
3.虚假匹配的问题。由于虚假现象,我们需要更复杂的回溯技术,一般来说,要消除虚假匹配是很困难的。
4.当最终报告分析不成功时,难于知道输入串中出错的确切位置。
1.不带回溯的自上而下分析的文法条件(LL(1)文法)
(1)文法不含左递归
(2)对于文法中每一个非终结符A的各个产生式的候选式的FIRST集两两不相交。即,若
A→α1|α2|…|αn
则 FIRST(αi)∩FIRST(αj)=Φ (i≠j)
(3)对于文法中的每个非终结符A,若它的某个候选首符集包含ε,则
FIRST(A)∩FOLLOW(A)=Φ
如果一个文法G满足以上条件,则称该文法G为LL(1)文法(第1个L代表从左到右扫描输入串,第2个L代表最左推导,1表示分析时每一步只看1个符号)
当一个文法满足LL(1)条件时,我们就可以构造一个不带回溯的自上而下分析程序,这个分析程序由一组(可能的)递归程序组成,每个过程对应文法的一个非终结符。这样一个分析程序称为递归下降分析器。
具体做法:
对文法的每一个非终结符都编一个分析程序,当根据文法和当时的输入符号预测到要用某个非终结符去匹配输入串时,就调用该非终结符的分析程序。
LL-自左向右扫描、自左向右的分析和匹配输入串。分析过程表现为最左推导的性质。该过程由分析表、总控程序、符号栈三部分组成。由于最左推导,进栈过程是逆序的。
2.预测分析表的构造——FIRST(X)
(1)若X终结符,则FIRST(X)={X};
(2)若X为非终结符,且有X->a …的产生式,则把a加入到FIRST(X)中;
(3)若X->Y…是一个产生式,且Y为非终结符,则把FIRST (Y)-ε加入到FIRST(X)中;
(4)若X->Y1Y2Y3….YK,是产生式,Y1Y2Y3….Yi-1是非终结符,而且ε属于FIRST (Yj)(1<=j<=i-1),则把FIRST (Yj)-ε加入到FIRST(X)中;如果ε属于所有的FIRST (Yj),则ε加入到FIRST(X)中。
(1)对于文法的开始符,置#于FOLLOW(S)中;
(2)若A->αBβ, 则把FIRST (β)-ε加入到FOLLOW(B)中;
(3)若A->αB 是一个产生式,或 A->αBβ是一个产生式,而β-> ε,则把FOLLOW(A)加入到FOLLOW(B)中。
4.
构造分析表的算法:
对文法G的每个产生式, A->α,进行下面的处理
- 对每个终结符a,如果a属于FIRST(α),则把该产生式写入到M[A,a]
若ε属于FIRST(α),则对任何b属于FOLLOW(A), 把该产生式加入到M[A,b]
所有无定义的M[A,a]标上出错标志
习题:
总结:这一章内容难度有点大,求FIRST集和FOLLOW集是重点,做题目的时候很容易出错,因此需要很仔细。通过对本章的学习,对于预测分析法的语法分析程序和递归子程序的区别与联系有了一定认知了解,还有一部分内容没有弄懂,还需课下多看多理解。