上下文无关文法:字符 V 总可以被字串 w 自由替换,而无需考虑字符 V 出现的上下文
自顶向下:针对输入串,从文法的开始符号出发,尝试根据产生式规则推导出该输入串
自底向上:针对输入串,尝试根据产生式规则规约到文法的开始符号
一. 自顶向下
1. 自上而下的分析方法不能用于左递归文法,因此需要消除左递归。
2. LL(1)文法:
从左向右地扫描输入,产生最左推导,每次向后看一个字符
满足什么条件的文法是LL(1)文法?对于文法
- 如果,
递归的预测分析:
- 包括一个输入缓冲区和一个向前看的指针lookahead
- 有一个辅助过程match(x),如果lookahead = x,就令lookahead指向缓冲区的下一个字符
- 为每一个非终结符写一个分析过程:该过程调用其他非终结符分析过程及match()
非递归的预测分析:
如上图所示,包括一个输入缓冲区,一个栈,一个分析表和一个输出流
例:
如果分析表是这样的:
则分析器运行过程是这样的:
运行开始时,栈内是文法的开始符号E和结束符号$;之后根据栈顶状态和lookahead指向的非终结符,替换栈顶符号,输出替换文法,直到栈顶非终结符可替换为终结符时,才将输入指向输入缓冲区的下一个符号。如此往复,直到栈顶指向$符号.
那么预测分析表如何构造呢?
- 对中的每一个终结符a,把填入M[A,a]中
- 如果在中,对中的每个终结符b,把填入M[A,b]中
二. 自下而上分析
用栈实现移进-归约分析:
- 移进:将下一个输入符号放到栈顶,以形成句柄
- 规约:将句柄替换为对应产生式的左部非终结符
- 接受:分析成功
- 报错:发现语法错误
LR分析
L: 对输入进行从左到右的扫描
R: 反向构造出一个最右推导序列
LR分析器:
LR分析算法:
LR(0)分析
如何构造LR(0)分析表:
LR(0)分析可能会遇到移进-归约冲突和归约-归约冲突,如果分析表中没有冲突,就称给定的文法为LR(0)文法
如何避免冲突呢?下面介绍SLR分析法
SLR分析
与LR分析的不同:仅对于Follow集中的元素进行归约动作
但是有时候仅用Follow集来化解冲突是不够的,这时候就需要功能更强大的LR(1)文法
LR(1)文法
在每条LR(1)语句后面增加一个展望符
展望符确定的方式:
如何构造LR(1)自动机,例:
如果两个项目集,除了展望符其他都是相同的,则称两个项目集同心
LALR分析
合并同心项目集,如果合并后语法分析没有冲突,则称该文法为LALR文法
LALR分析可能会做多余的归约,却不会做错误的移进
特点:
- 形式上与LR(1)相同
- 大小上与LR(0)和SLR(1)相同
- 分析能力上,介于SLR(1)和LR(1)之间