第四章 语法分析
4-1
自顶向下的分析
根节点开始
最左推导|最右归约
总是选择最左非终结符进行替换
对应的逆过程称为最右归约
最右推导则相反
自底向上选择最左归约(从左往右归约)
最左推导和最右推导都具有唯一性
自顶向下的语法分析采用最
左推导方式
回溯
需要回溯的分析器称作不确定的分析器
预测分析
4-2 文法转化
消除直接左递归
直接左递归和间接左递归
消除左递归的方法就是把左递归转换为右递归
一般形式
但是引入了非终结符和空产生式
消除间接左递归
代入法:
消去左递归算法
可以同时消去直接和间接的左递归
公共前缀的解决方法:提取左公因子
算法:
4-3 LL(1)文法
S_文法
空产生式
如果其他候选式都不匹配的话,可以选择空产生式
非终结符的后继符号集 FOLLOW集
相对于位于左部的非终结符号而言
产生式的可选集 SELECT集
相对于产生式而言
串首终结符集 FIRST集
α=>*ε,则FIRST(a) 串首都是非终结符,而且每个非终结符都推导出空串
α
=
>
∗
ε
α=>^*ε
α=>∗ε
如果ε∉FIRST(α),则SELECT集不包含其他
ε∈FIRST(α)的话,还要FOLLOW(A)并减去ε
LL(1)文法
4-4 FIRST集和FOLLOW集的计算
计算FIRST集
计算FIRST(X)X为非终结符
使用以下算法以确保无误
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KGDDEc3K-1636114233687)(C:/Users/l/AppData/Roaming/Typora/typora-user-images/image-20211105152508330.png)]
计算FIRST(X1X2……) X为非终结符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ERLwPMle-1636114233688)(https://i.loli.net/2021/11/05/ZRBzf4mYjMtKPOr.png)]
计算FOLLOW集
计算非终结符A的FOLLOW(A),终结符不用算follow集
运用以下算法确保集合元素都找到了
- 将 放 入 F O L L O W ( S ) 中 , 其 中 S 是 开 始 符 号 , 放入FOLLOW( S )中,其中S是开始符号, 放入FOLLOW(S)中,其中S是开始符号,是输入右端的结束标记
- 如果存在一个产生式A→αBβ,那么FIRST ( β )中除ε 之外的所有符号都在FOLLOW( B )中
- 如果存在一个产生式A→αB,或存在产生式A→αBβ且FIRST( β ) 包含ε,那么 FOLLOW( A )中的所有符号都在FOLLOW( B )中
计算SELECT集
如果全部左部相同的表达式,右部的SELECT集不相交,则为LL(1)文法
预测分析表
根据SELECT集填入即可
LL(1)文法的分析方法
递归的预测分析法
非递归的预测分析法
4-5 递归的预测分析法
program DESCENT;
begin
GETNEXT(TOKEN);
PROGRAM(TOKEN);
GETNEXT(TOKEN);
if TOKEN≠’$’ then ERROR;
end
procedure PROGRAM(TOKEN);
begin
if TOKEN≠’program’ then ERROR;
GETNEXT(TOKEN);
DECLIST(TOKEN);
if TOKEN≠’:’ then ERROR;
GETNEXT(TOKEN);
TYPE(TOKEN);
GETNEXT(TOKEN);
if TOKEN≠’;’ then ERROR;
GETNEXT(TOKEN);
STLIST(TOKEN);
if TOKEN≠’end’ then ERROR;
end
4-6非递归的预测分析法
栈顶在左侧,栈底在右侧
非递归的预测分析不需要为每个非终结符编写递归下降过 程,而是根据预测分析表构造一个自动机,也叫表驱动的 预测分析
非递归的预测分析法的实现(重点)
1)构造文法
2)改造文法:消除二义性、消除左递归、消除回溯
3)求每个变量的FIRST集和FOLLOW集,从而求得每个 候选式的SELECT集
4)检查是不是 LL(1) 文法。若是,构造预测分析表
5)对于递归的预测分析,根据预测分析表为每一个非终结 符编写一个过程;对于非递归的预测分析,实现表驱动 的预测分析算法
4-7 预测分析中的错误处理
可检测到的两种错误
- 栈顶的终结符和当前输入符号不匹配
- 栈顶非终结符与当前输入符号在预测分析表对应项中的信息为空
恐慌模式
忽略输入的一些符号,直到输入中出现合法的词法单元。设计者可以选定一些同步词法单元
利用FOLLOW集和同步词法单元更新分析表
可以将FOLLOW(A)中的所有终结符放入非终结符A的同步记号集合
终结符在栈顶而不能匹配,一个简单的办法就是弹出该终结符。
空产生式不作为同步词法单元
Synch表示根据相应非终结符的FOLLOW集得到的同步词法单元
分析表的使用方法
- 如果M[A,a]是空,表示检测到错误,根据恐慌模式,忽略输入符号a
- 如果M[A,a]是synch,则弹出栈顶的非终结符A,试图继续分析后面的语法成分
- 如果栈顶的终结符和输入符号不匹配,则弹出栈顶的终结符
例题
可检测到的两种错误
- 栈顶的终结符和当前输入符号不匹配
- 栈顶非终结符与当前输入符号在预测分析表对应项中的信息为空
恐慌模式
忽略输入的一些符号,直到输入中出现合法的词法单元。设计者可以选定一些同步词法单元
利用FOLLOW集和同步词法单元更新分析表
可以将FOLLOW(A)中的所有终结符放入非终结符A的同步记号集合
终结符在栈顶而不能匹配,一个简单的办法就是弹出该终结符。
空产生式不作为同步词法单元
Synch表示根据相应非终结符的FOLLOW集得到的同步词法单元
分析表的使用方法
- 如果M[A,a]是空,表示检测到错误,根据恐慌模式,忽略输入符号a
- 如果M[A,a]是synch,则弹出栈顶的非终结符A,试图继续分析后面的语法成分
- 如果栈顶的终结符和输入符号不匹配,则弹出栈顶的终结符