[第一章:文法(语法)和语言]
[第四章:词法分析]
[第五章:自顶向下的语法分析]
[第六章:自底向上的语法分析(移进—归约分析)]
[第七章:LR分析:一种自下而上的分析方法]
[第八章:语法制导和中间代码生成]
LR:L表示从左至右扫描输入串,R表示构造一个最右推导的逆过程
四种分析表
分析表工作流程
归约了几个符号,状态栈就出栈几个
归约动作 GOTO的使用
LR文法:对于一个文法,如果能够构造出一张分析表,使得它的每个入口均是唯一的,则称该文法为LR文法
LR(0):不需要向前查看输入符号
活前缀和可归前缀
LR(0)项目:
文法G的每一个产生式的右部添加一个圆点称为G的一个LR(0)项目,简称项目。项目个数是右部符号长度加1
构造识别活前缀的DFA:
项目集I的闭包函数CLOSURE(I):
第二条意思是:如果·后面是非终结符,那么这个非终结符对应的项目中,·在第一位的都加入clousre集
状态转换函数GO
我们将圆点不在产生式右部最左边的项目称为核,唯一的例外是S’-> • S也是核
GO(I, X)的直观意义是:从状态I出发,经过X弧所应该到达的状态(项目集) 。也就是说,J是由I中那些X左边有圆点的项目,把圆点右移一个位置所得的项目的集合
拓广文法:为使“接受状态”唯一且易于识别,构造文法G的拓广文法G': 引进一个新初态S',增加产生式S'->S
例:
LR(0)分析表相当于识别活前缀的有限自动机DFA的状态转换矩阵
LR(0)步骤:
例:第三步不懂看BV1MV411x78Z
SLR(1)分析:
若一个文法G的拓广文法G'的活前缀识别自动机中的每个状态不存在下述情况
则称G是一个LR(0)文法
LR(0)要求的条件很苛刻。常见的程序设计语言都不是LR(0),即大多存在两种冲突
SLR(1)做法与LR(0)类似
差别:设某状态转换表中有这三个状态存在冲突
只需要注意一点,就是SLR(1)中写r不需要把所有终结符都写上,只把FOLLOW集中有的终结符写上r就可以。其他的和LR(0)分析表构造完全一样
LR(1)分析法
SLR(1)使用的follow集方法不能完全解决冲突,也不能解决存在公共元素的情况(即并集不为空的情况)
SLR分析和规范LR分析都是通过“展望”信息来解决冲突的,但前者仅对归约项才向前搜索,而后者是任何时候都向前搜索
LR(1)集族写法:【产生式,搜索符号串】
LALR分析法:
在LR(1)基础上:合并那些仅仅搜索符号串不同而其余完全相同的项目集(同心集)
判断文法属于那种LR类:
首先不能是二义文法。构造出集族表后,如果没有两种冲突,就是LR0。如果有,看冲突项的follow集的并,如果是空集就是SLR。若不空,则LR1。LR1基础上合并同心集,合并后若仍没有冲突,则LALR1。(合并同心集可能会引入归约—归约冲突)