LL(1)文法
属于自上而下的分析方法。
也就是说,同一个非终结符的多种递推方式中,首字母一定不同。这样就可以只用根据一个首字母就可以判断出是哪一个递推式子。
文法名字由来
第一个L代表从左边开始扫描;
第二个L表示产生最左推导
数字1表示每一步推导式只需要向后看一个符号就可以
LL(1)文法的明显性质
- 没有公共左因子(如果有,那么无法只读一个字符就判断如何递归)
- 不是二义的(每个读入的字符都能确定具体含义)
- 不含有左递归(不包含回溯)
LR(SLR基于LR(0),LR(1)存在缺点,LALR进行折衷)
属于自下而上的分析方法。
- 栈中文法符号必定是构成一个活前缀
- 分析表中建立转移函数,本质上转移函数就是识别活前缀的DFA(有限状态转换自动机)
- 栈顶的状态符号包含了确定句柄所需要的一切信息;因为根据栈顶的状态符号和分析表就可以唯一地确定下一步要做什么。
缺点:
手工构造分析表的工作量太大了。
现在一般用机器生成分析表,可以找到相关开源软件。
SLR(1)分析表
简单的LR方法,简称SLR;它功能最弱但是最容易实现。
构造脱胎于LR(0)分析表
根据期待的不同后继来决定归约方式。
构造SLR分析表的两大步骤
- 从文法构造识别活前缀的DFA
- 从上述活前缀的DFA构造分析表
文法特点:
SLR(1)文法都不是二义的,但是很多非二义的文法都不是SLR(1)的。
文法的描述能力有限,因为对于相同的字母,在不同情况下的归约方式可能会不同。
缺点解决方法:
加上后继搜索符,转变成LR(1)
LR(1)
将SLR的项目带上搜索符。
部分基于SLR(1)会产生移进-规约冲突的例子,在基于LR(1)时没有冲突。如:
缺点:
相当于是把SLR(1)中可能产生分歧的状态通过搜索符划分成了多个不会产生冲突的状态,因此状态数大大增加。
解决思路:
提出LALR分析表,功能介于SLR(1)和LR(1)之间,但是状态数与SLR(1)一样多。
LALR
lookahead LR 方法,实际编译器经常采用这种方法
构造方法:
通过合并规范LR(1)项目集得到;也就是说,通过损失一点点的精度来达到减少状态数量的目的。因为合并是有可能产生新的归约-归约冲突。
总结:
以上部分属于自己总结,部分截取自电子书与老师课件。
有什么问题欢迎大家指出。