语法分析
- 本章内容:根据token流生成AST
上下文无关文法(CFG)
- 最左推导:即对每个产生式先从左端的非终结符开始推导
- 二义性:给定文法,若存在某个句子有多个最左/右推导,既可以生成多棵解析树,则这个文法就是二义的
- 消除二义性:主要方式E—>E+E1 | E1 ; E1—>num
自顶向下语法分析技术
1.回溯算法
2.消除左递归
注意这里的=+>,意思是可能经过一步或多步到达
2.预测分析技术
1. LL(1)文法
- 构建解析表:
根据解析表和下一步看到的非终结符来比较,查看解析表中对应位置的序号,然后进行展开,若展开后得到的非终结符与句子中的非终结符一致,则匹配该非终结符 - 构建解析表需要两个函数:FIRST() FOLLOW()
- LL(1)文法的条件:
- LL(1)文法的条件:
2.递归下降算法
- 有了解析表的概念,对于LL(1)文法,又是我们不必实际构建解析表,并且可以借助系统栈来实现预测分析,此即递归下降算法
自底向上的语法分析
- 基本思想:一边从左—>右扫描输入,一边自叶—>根构建解析树,不成功便报错
- 自底向上语法分析的通用框架:移入—归约
- 因为自底向上是自左向右归约,也就是自右向左推导,即最右推导。
- 移入归约的过程(也是通过栈的方式,根据栈顶的句柄来决定如何归约)
- 为了应对如何识别句柄的问题,人们提出了LR语法分析技术
LR技术
- 特点:由表格驱动。只要写出上下文无关文法就能够造出识别该语言的LR语法分析器。最通用的无回溯移入归约分析技术
- 例子:
图中的意思是:Sn即shift(移入)之后栈顶切换到状态n,然后去读下一token
Rn即按第n条产生式reduce(归约),归约后状态弹出,弹出的状态数量为当前symbols中的数量,然后根据归约得到的非终结符以及栈项目目前状态,找到GOTO相应位置的状态码然后压入栈顶
LR(0)项
- 引入的目的是确定多个状态及他们之间的转移关系,即构建ACTION表,通过项的手段来确立。
- LR(0)项的含义:项描述了句柄识别的状态
- 增广文法
- 核心点在于LR(0)项的定义中先归约后面的再合起来一起归约
- 意思即将I中点后有X的点后移,然后求闭包
- 首先从0状态开始,0状态即所有都等待归约,然后根据不同的GOTO构建不同的状态,形成图之后,就可以构建表,状态散发出去的边为s(shift),只有进入的边,那么就按产生式的序号来进行ruduce
- 为了解决简单LR(0)文法中会出现的移入归约冲突,采用SLR(1)分析,
前提条件是,即有两类,一类是点在中间,一类是点在最后,所以有两种解决方式:
简单概括就是若下一个输入符号在点紧跟着的后面,那么就移入(shift)这个输入符号 - 但是SLR(1)仍然不能解决所有问题
LR(1)项集族的构造算法:
- 采用展望符
2.关键点在于点后面仍有一个非终结符时应该怎么构建族,主要是观察该非终结符在左边的产生式以及合理判断使用什么展望符
LALR