自上而下分析面临的问题
-
回溯 (当候选有多个的时候,匹配失败会造成回溯)
-
文法左递归问题
那么他这个语法树就会无限增长但是分析并没有继续进行下去,就会导致分析进入死循环中
LL1文法消除左递归
消除直接左递归
思想就是把左递归变成右递归
消除间接左递归
你看,上面消除间接左递归的过程就是把R带入Q中的推导,再把新得到的Q的推导带入S的推导中去,然后我们就得到了直接左递归,然后就可以使用之前的方法来消除左递归了,这样我们就打破了S的左递归,同样的我们也打破了 Q 和 R 的左递归
我们下面的算法就是应用这样的思想来计算的
下面给出一个消除左递归的算法(可以消除直接左递归和间接左递归):
但是这个算法有两个条件:
不含有空产生式
不含有回路
消除回溯
First集合
一个文法一开始可能并不存在每个非终结符的首符集两两不相交的情况,我们可以通过一个算法,把这个文法改造成两两不相交,这个算法叫做提取公共左因子
但是这个算法对绝大多数文法是能变成两两不相交的,但是也存在某些文法,他就是无法变成两两不相交的
Follow集合
只用当A -> 空 的时候才会用到 Follow 集合, 否则,如果A不能推出空的, 那么轮到A匹配的时候,要么就A匹配成功,要么匹配失败,不可能有A之后字符的事
LL1文法
递归下降分析器
比如:A的程序就会依次调用B和D的程序进行语法分析
ADVANCE就相当于词法分析的子程序,当这个程序执行完后,就会把识别的词放到变量SYM当中去
扩充的巴克斯范式和语法图
α是个字符串
预测分析程序
预测分析程序就是采用非递归的方法实现递归下降程序
预测分析表是个二维矩阵,用于指导语法分析,表示栈顶符号是 A 时 , 面临非终结符a时应该采取的动作,用哪个候选进行扩展
预测分析表的构造
构造分析表说白了就是把每一个非终结符的每一个候选放到在表中合适的位置上去
分析表就是告诉你当非终结符 A 面临终结符a 时应该选择哪个候选式进行扩展
对于 A -> a 一定是放到 A 的那一行, 然后 First(a) 的那一列上
对于 A-> 空 一定是放到 A 的那一行, 然后 Follow(A) 的那一列上
LL1文法与二义性
如果G是左递归或者二义的,那么构造出的预测分析表的某一个格子中一定会有多个候选(也就是M含有多重定义入口的意思),如果一个格子里有多个候选,就会给分析带来不确定
但是,并不是所有的文法经过消除左递归和提取左公共因子都可以变得无二义,比如说下面这个文法
那么导致这种二义性出现的原因就是 那个 else 和 if then 匹配的问题
你可以理解为else 和就近的 if then 匹配 也可以理解为 else 和 远处的 if then 匹配
这种问题称为 悬挂else问题
所以说描述 if else 的文法是二义的