编译原理-语法分析-LR系列

前面说过了LLR(1)分析,它是自顶向下分析的,也就是推导。

下面就说LR系列的,它是自底向上分析的,也就是规约。

目录

LR(0)

SLR(1)

LR(1)

LALR(1)


LR(0)

在LR中,LR(0)是最简单的,也是要求最高的。括号中的数字就是向前看几个字符,显然这里是不向前看的。LR,L就是自左到右扫描输入串,R就是最右推导的逆过程最左规约。

注意:正规文法和规范推导别混淆了。规范文法是右递归或者左递归文法,规范推导就是最右推导,推出的句型是规范句型,其逆过程就是规范规约也就是最左规约。

我们知道,句柄就是最左直接短语,也就是最左规约过程中最先被规约的那个。

那么LR既然是规约的过程,势必先规约句柄。

LR(0)分析法的关键就在于构造相应的分析表。

活前缀:含句柄前面及其自身的前缀都是其活前缀。显然到一个活前缀的末尾时就该规约了。

LR(0)项目:就是文法中右部带 ·的规则

四种LR(0)项目

归约项目,圆点到达最右边

移进项目,点后面仍有终结符

待约项目,点后面有非终结符

接受项目,归约到文法的开始符号

 

构造DFA

我们知道NFA 到DFA的方法就是闭包,合并  空转移的状态。

最初我们可以由给出的LR(0)项目写出NFA,然后遇到待约项目可以加空串从而跳到相应非终结符对应的状态,从而构造DFA时要将这种状态合并。

此时的闭包函数CLOSURE,就是将待约项目中 圆点后面的非终结符对应的LR(0)项目加入当前状态中即可。

根据上述DFA写出转移表即可。

(状态,终结符)=终结符入栈+对应的下个状态入栈=Si

上面对应,DFA的移进项目的转移

(状态,终结符)=状态栈出一个状态+符号栈出若干进行对应的归约=Ri

(状态,非终结符)=将下个状态入栈

上面对应,DFA的待约项目中的非终结符完成了归约,然后退回到前一状态,紧接着可以直接跳到下个状态,因为此时归约的非终结符已经在栈中了

对应上面的状态写出即可。

限制:LR(0)文法,LR(0)文法,不能存在移进项目和归约项目、归约项目和归约项目同时并存。于是紧接着出现了下面的SLR(1)来协助解决一下。

SLR(1)

在上面的基础上,SLR(1)就想我能不能往前看一个字符呢,看看能不能根据下一个字符来确定是进行移进还是归约,或是进行哪种归约?

基于这种思想,我们能够解决LR(0)遗留的一部分问题,但是仍然会存在问题。

 

因为它要求移进与归约冲突中:移进的字符与归约到的非终结符的Follow集不能有交集;或是归约到的非终结符的Follow集之间不能有交集。因为一旦有交集又会冲突。所以又出现了LR(1)来继续协助。

SLR(1)文法就是能通过上面交集的办法解决LR(0)问题的文法。

LR(1)

SR(1)虽然能解决部分LR(0)的问题,但是它自身也存在一些问题。

因为上面的Follow集中出现的字符并非出现在特定的句型中,所以它可能会产生一些错误句型,就是条件相对宽松。

LR(1)也针对此问题给出了相应的办法,就是展望符,展望特定句型中的非终结符的Follow集,这样不会凭空出现新的句型。

LR(1)文法就是LR(1)的项目集中没有  移进-归约冲突  或 归约-归约冲突。

但不是LR(1)分析法能解决所有问题,也只是部分问题。

 

LALR(1)

LALR(1)分析法就是在LR(1)的基础上进行简化的,因为LR(1)的状态数比较多,存在同心集,就是除了展望符不同,其他都一样。LALR(1)将其合并会简化,但是有可能会出现新的问题就是归约-归约冲突,但是不会出现移进-归约冲突,因为LALR(1)分析法是在LR(1)的基础上,LR(1)是没有移进-归约冲突的,合并后也不会出现移进-归约冲突。但是归约-归约冲突是因为合并同心集时由于展望符不同而可能引发的问题。

 

至此就是LR的基本系列,我们可以看出LR系列也只是能解决部分问题,仍然有些问题是其不能解决的。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值