第四章 语法分析
1. 自顶向下分析概述
从分析树的根节点向叶节点方向构造分析树,可以看做是从文法开始符号推导出词串的过程
(1). 最左推导
在最左推导中,总是选择每个句型的最左侧非终结符进行替换.
(2). 递归向下分析
计算机程序实现的自顶向下分析的通用形式.
每层递归对应一个非终结符(相当于遍历一个树的子节点,非终结符对应的是非叶子节点)
搭配回溯使用
2. 文法转换
(1). 消除直接左递归
当同一个非终结符的多个候选式存在相同的前缀时,会导致回溯(最终只会匹配其中一个)
将含有 A->Aα 形式产生式的文法称为是直接左递归的.使用最左推导的递归向下分析可能会无限递归.
A -> Aα | β ===> A -> βA’ 其中 A’ -> αA’ | ε
因为是左递归,所以都是A->βααααααα…这样的,那么把第一个β抽取出来,再新建立一个A’->αααααα…就可以替换左递归.其中后面新建立的这个式子是右递归的.
(2). 消除间接左递归
S -> Aa | b
A -> Ac | Sd | ε
这里的递归是间接存在于两条文法中的.
将两个式子代入,编程直接左递归,然后消除直接左递归
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9VtB3sxv-1575943236187)(http://benjaminlee.cn:8989/hello/images/1573666379351.png)]
(3). 提取左公因式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6irJ1trn-1575943236189)(http://benjaminlee.cn:8989/hello/images/1573666482505.png)]
推迟决定,等待获取到了足够的信息在做出选择.
3. LL1文法
(1). 预测分析法
在自顶向下的分析中,可能会遇到回溯.如果能够预先读取几个字符,就可以避免很多回溯.
LL1就是使用预先读取一个字符的预测分析技术的文法.
1). 工作过程
从文法开始符号出发,每一步根据当前句型的最左非终结符和当前输入符号,选择正确的产生式,所选出的产生式必须是唯一的.
文法最好满足的条件,即S_文法(简单的确定性文法):
- 每个产生式的右部都以终结符开始(每一次推导都能确定一个字符)
- 同一个非终结符的各个候选式的首终结符都不同.(每读入一个字符都决定依次推导,不会有回溯)
在推导过程中,如果当前的文法不匹配,能否使用空产生式取决于当前输入的符号是否在使用空产生式后能够被接收.(也就是跳过空产生式能否匹配)
4. FIRST集和FOLLOW集
(1). 非终结符的后继符号集
非终结符A的后继符号集就是指可能在某个句型中紧跟在A后面的终结符a的集合.记为**FOLLOW(A)**
(2). 产生式的可选集
产生式 A -> β的可选集是指可以选用该产生式**进行推导时对应的输入符号的概念.记为SELECT(A->β)**
- SELECT(A->aβ) = {a} (这里就是明显的可以接收字符a)
- SELECT(A->ε) = FOLLOW(A) (这里是非终结符A选择推导为空产生式的条件就是遇到了可以接收的终结符)
q_文法:
- 每个产生式的右部要么是ε,要么以终结符开始
- 相同左部的产生式有不想交的可选集
(3). 串首终结符集
作为串首的第一个符号,并且是终结符.
给定一个文法符号串α,α的串首终结符集**FIRST(α)**被定义为可以从α推导出的所有串首终结符构成的集合.
(α等价的所有串的首字符)
如果α能推出空串,那么空串也在FIRST集中.
那么,是不是意味着,如果FIRST(α)中不包含空串,那么SELECT(A->α) = FIRST(α).(如果该串A通过一个文法一定能推出来一个串,那么使用该文法记性推导时索要输入的字符一定是α的等价串的首字符…好像废话了)
如果FIRST(α)中包含空串,那么SELECT(A->α) = ( FIRST(α)-{ε} ) ∪ FOLLOW(A)(如果这个串A通过一个文法可能会推出空串,那么需要读入一个α等价串首字符-空字符 和 A后面可以接受的任意一个字符,也就是直接将A推导为空串)
总结:有文法A->α, 如果α可以推出空串,那么本次推导可以输入α等价串的首字符(除去空串)和A的任意后继终结符(直接将A推导为空串).如果不能推出空串,那么只能输入α等价串的首字符.
(4). LL1文法
文法G是LL(1)的,当且仅当G的任意两个拥有任意左部的产生式A -> α | β满足以下条件:
- 如果α和β都不能推导出空串,那么FIRST(α)∩FIRST(β) = Ø(不相交)
- α和β至多有一个能推出空串(FOLLOW(A)部分会相交)
- 如果α能推出空串,那么FIRST(β)∩FOLLOW(A) = Ø(原因同上)
(5). 预测分析表
1). 求FIRST集
根据定义,求出等价串的所有首字符即可.
2). 求FOLLOW集
根据定义求出所有跟随的字符,这里如果作为产生式的最右侧出现,要添加结束符$.
适当的参考FIRST集
3). 求SELECT集
右部的FIRST集,如果右部能推出空串,还要加上左部的FOLLOW集.
4). 预测分析表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y3O9lu1E-1575943236190)(http://benjaminlee.cn:8989/hello/images/1573677228209.png)]
SELECT集的含义是非终结符能通过读取那个字符通过产生式进行推导,这里装换为非终结符通过那个产生式读取某个符号.
5. 递归的预测分析法
6. 非递归的预测分析法
7. 预测分析法中的错误处理
8. 自底向上的分析概述
从分析树的底部叶节点向顶部根节点方向构造分析树.
可以看做是将输入串归约为开始符号的过程.
(1). 移入-归约分析
最右归约.
使用栈,将出入串输入到栈中,每次入栈后判断栈顶的n个元素是否是某个产生式的右部,如果是,进行归约.直到栈中包含开始符号且输入缓冲区为空.
所选栈顶的字符串要尽可能长,保证推导的唯一性.
9. LR分析法概述
LR文法是最大的,可以构造出移入-归约语法分析器的文法类.
LR(k)分析是指需要提前查看k个符号,一般k=0或者1是有实践意义的.
(1). 基本原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0KdLGpn3-1575943236191)(http://benjaminlee.cn:8989/hello/images/1573712334292.png)]
当输入栈中没有字符时,为移进状态.
当输入栈中的字符不能进行归约,需要继续输入字符时,为待约状态.
当输入栈中的字符符合某个产生式的右部时,为归约状态.
来源:CSDN
作者:Benjamin-__
链接:https://blog.csdn.net/Benjalin_76_84/article/details/103469677