编译器笔记17-语法分析-二义性文法的LR分析

二义性文法的特点

  • 每个二义性文法都不是LR的
  • 某些类型的二义性文法在语言的描述和实现中很有用更简短、更自然
例.png

二义性文法之所以相对简洁,是因为非二义性文法为了消除二义性引入了新的非终结符,需要更多的产生式,LR项目也更多。

二义性算术表达式文法的LR(0)分析器

LR(0)分析器.png

状态7和状态8都存在移入-归约冲突,当状态7遇到*和+时查看FOLLOW(E)可知,可以采用移入操作也可以采用归约动作。状态8遇到*和+时也是跟状态7同样的情况。

问: 如何消解这种移入归约冲突?
答:状态7表示栈顶的符号串是E+E,若栈外的输入符号是*时,由于乘法的优先级高于加法,因此应该把*移入到栈中(蓝色)进入状态5,来先进行乘法运算。若下一个输入符号为+,因加法是左结合的,所以先算栈里的加法这时候应执行归约操作。

状态8表示栈顶的符号串是E*E,不管栈外的输入符号是+或*,无论从优先级还是结合性考虑都应该先算栈内的乘法运算。因此最后执行归约操作。

可见同时利用运算的优先级和结合性就解决了这两个状态的冲突。

二义性算术表达式文法的SLR分析表

SLR分析表.png
例 - 二义性if 语句文法的LR分析.png
2196908-17aaf9e22707588c.png

说明:利用了最近匹配原则化解了该冲突。

二义性if语句文法的SLR分析表

SLR分析表.png

二义性文法的使用

应该保守地使用二义性文法,并且必须在严格控制之下使用,因为稍有不慎就会导致语法分析器所识别的语言出现偏差。

简单地说使用二义性文法产生冲突时,必须要有文法外的规则限制(运算优先级、最近匹配原则等等)才能在冲突中作出选择。

你可能感兴趣的:(编译器笔记17-语法分析-二义性文法的LR分析)