编译原理5 自底向上语法分析

就比如说,乘法比加法优先级高,我们规约的时候就会先规约乘法 。正要输入的X2有限级比在栈里面的X1优先级高,那我们就移进而不是规约X1;这时X3有限集和X2一样,那就先移进X3在规约。

小数点的意思是待输入和栈的分割。

细说优先法:

注意看,想要规约E那就要先找到T,说明我们要先规约出T才能规约出E,暗示乘法优先级比加法高。而要先有E才能有F,暗示加法优先级比括号高。

优先级的标准算法:

注意:中间夹了一个B也算相邻,毕竟在算法中我们比较优先级是用最上面的终结符号来和输入符号比较(非终结符哪来的优先级)。所以这个B无伤大雅。

FIRSTOP把后半边的条件遮住就和FIRST集一样了,不过这个更大,前面有非终结符也没有关系。

就比如说第二条,假如b不属于FIRSTOPB的话,ab之间可能还会有其他终结符号,那他们两个就不能比较了,所以这个OP集合还是有用的。

实践的时候,其实就是把那些非终结符的OP集算出来,然后看那些产生式,看那些和这个非终结符相邻的终结符,就可以愉快的写出比较了。

 竖列的那一批是已经在栈里面的.

有几个问题:

 

用递归定义更好理解素短语:就是有至少一个终结符的短语,并且内部没有其他的素短语。

举个例子:

 先把短语都写出来,然后一个一个看,先看有没有终结符号,再看这个短语中有没有包含更小的短语,这个更小的短语符不符合素短语的定义。

算符优先文法中优先级表可能会很大(N^2)我们可以把它该改造成2*n的

f是在栈里面的优先级,g是在字符串里的优先级

这个优先函数怎么写呢?:

拓扑排序

状态识别法:

由此引出LR分析法 

S代表shift(移进),r代表reduction(规约) 

正常情况下状态栈和符号栈是平的。规约的时候,符号栈把需要规约的符号都弹出去,把与之对应的状态也都弹出去,符号栈再压入对应的非终结符号。这时符号栈比状态栈高一位而且最上面是非终结符号,就要用到goto表了。

只有在两边不平的时候才要用goto

acc代表结束,也就是:在一状态收到#号那就成功了。

 

以图为例:

 从一个闭包变成下一个闭包

 

 

先让I0 = 初始产生式的克林闭包,然后通过不断地输入各种符号来获得所有可以的闭包,每个闭包就是一个状态 

之前的a只要是个东西都可以得出规约的结论,现在a需要是A的follow集

举个例子:

 

新的项目还要考虑字符串

也就是说,a是规约之后的第一个字符(可以是#) 

和之前的算法一样,A->a.Bbeita,a也可以得出B->.y,但是这个B->y逗号后面的是什么呢?是FIRST(beita a)。为什么呢?我们要知道:逗号后面的那个符号代表:只有紧接着这个符号才可以规约。那么既然我的这个新的项目是由这个旧项目推出来的,我肯定要配合这个旧项目,那么接下来的就是beita 和a(beita1可能是空串所以考虑一下a).然后的思路就都是一样的。

这些做法改来改去其实就是规约有问题,我们这个把规约的情况限定死了,只有在后面跟着特定符号的时候可以规约,因此绝对准确 

转移不需要改变后面的那个符号 

和之前的一样,改也就是改规约那一步 

 LR(0)觉得后面跟什么符号我都可以随便规约

SLR(1)觉得只有后面跟着follow集的才可以规约,但这样只能保证可以存在,不代表这一步应该归月

LR(1)是最准确的

 为什么要求follow集?感觉不用啊,就开头的s'->.S后面的那个后继符号是直接通过follow得出的。

注意:构造这个东西的时候有两点要注意,一是构造文法(加一个头),二是用一个项目集产生新的项目集的时候,注意新的项目集也要是闭包,是要扩展的

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值