声明:本系列文章,是根据中国大学MOOC网 哈工大的编译原理 这门课学习而成的学习笔记。
一、自底向上分析概述
自底向上的语法分析
-
从分析树的底部(叶节点)向顶部(根节点)方向构造分析树
可以看成是将输入串w归约为文法开始符号S的过程 -
自顶向下的语法分析采用最左推导方式
自底向上的语法分析采用最左归约方式(反向构造最右推导) -
自底向上语法分析的通用框架
移入-归约分析(Shift-Reduce Parsing)
移入-归约分析的工作过程
移入-归约分析器可采取的4种动作
- 移入:将下一个输入符号移到栈的顶端
- 归约:被归约的符号串的右端必然处于栈顶。语法分析器在栈中确定这个串的左端,并决定用哪个非终结符来替换这个串
- 接收:宣布语法分析过程成功完成
- 报错:发现一个语法错误,并调用错误恢复子例程
移入-归约分析中存在的问题
二、LR分析法概述
LR分析法
-
LR文法(Knuth, 1963)是最大的、可以构造出相应移入-归约语法分析器的文法类
- L: 对输入进行从左到右的扫描
- R: 反向构造出一个最右推导序列
-
LR(k)分析
需要向前查看k个输入符号的LR分析
k = 0 和 k = 1 这两种情况具有实践意义,当省略(k)时,表示k =1
LR 分析法的基本原理
-
自底向上分析的关键问题是什么?
如何正确地识别句柄 -
句柄是逐步形成的,用“状态”表示句柄识别的进展程度
LR 分析器(自动机)的总体结构
LR 分析器的工作过程
LR 分析算法
三、LR(0)分析
LR(0)项目
增广文法
引入这个新的开始产生式的目的是使得文法开始符号仅出现在一个产生式的左边,从而使得分析器只有一个接受状态
文法中的项目
由①②可知,当等待S时,实际也是再等待v,故(0)(2)等价,同理,(3)(7)(11)等价,(5)(13)等价
当后继项目中有非终结符时,需要写出其等价项目
CLOSURE( )函数
GOTO ( )函数
构造LR(0)自动机的状态集
LR(0)分析表构造算法
LR(0) 分析过程中的冲突
i2中,E->T· 要求进行归约,而T->T·*F要求进行移进,造成了冲突
四、SLR分析
SLR分析法的基本思想
- 简单来说,文法,就是看该符号的FOLLOW集来判断此时倒是是规约还是移进,肯定会有人问,什么是FOLLOW集啊,所以
I2来说,E的follow集中没有*,故此时应该进行移入,不应该规约,I9同理
SLR 分析表构造算法
SLR 分析中的冲突
I2中,第一条表遇到等号进行移入,第二条,R的FOLLOW中也有R,表明遇到=进行规约,此时造成了规约移入冲突。
五、LR(1)分析
LR(1)分析法的提出
LR(1)分析法的提出
规范LR(1)项目
等价LR(1)项目
推断时,要在后面加上后继符,自身的和继承的都要加,比如I0中,L的后继符本身有个=,同时也继承了S’的$,故其中L要写两遍,其后继也要写两遍。
如I4和I11是同心的,I7和I13是同心的,I5和I12是同心的,I8和I10是同心的
LR(1)项目集闭包
GOTO 函数
为文法G’ 构造LR(1)项集族
LR(1)自动机的形式化定义
- LR分析表构造算法
六、LALR分析法
LALR分析法的提出
合并同心项集产生的问题
I6中遇到d,将c规约成A,而在I9中,遇到d,则规约成B,故这两个不能合并,否则会造成归约-归约冲突。
- 上述例子中,r至少包含dcd三个符号,同时I4和I9合并后不会造成冲突,所以可以合并。但例如输入一个d,如果不合并,则在I4就检测出问题,如果合并,则会在I4->I0->I2才会发现错误。
- LALR合并只合并其展望符相关的,而移位和展望符没有任何关系,故LALR不会作错误的移进操作。
LALR(1)的特点
- 形式上与LR(1)相同
- 大小上与LR(0)/SLR相当
- 分析能力介于SLR和LR(1)二者之间
SLR<LALR(1)<LR(1)
合并后的展望符集合仍为FOLLOW集的子集
七、二义性文法的LR分析
二义性文法的特点
二义性文法的使用
- 应该保守地使用二义性文法,并且必须在严格控制之下使用,因为稍有不慎就会导致语法分器所识别的语言出现偏差
八、LR分析中的错误处理
语法错误的检测
- 当LR分析器在查询分析表并发现一个报错条目时,就检测到了一个语法错误
错误恢复策略
- 恐慌模式错误恢复
- 短语层次错误恢复
恐慌模式错误恢复
短语层次错误恢复
- 检查LR分析表中的每一个报错条目,并根据语言的使用方法来决定程序员所犯的何种错误最有可能引起这个语法错误
- 然后构造出适当的恢复过程