关于LALR(1)解析器中的冲突的一些问题,主要与解析的细节有关:
根据教科书中描述的不同LALR(1)解析器,如果遇到移位/减少冲突,则表示语法不是LALR(1)开始,对吧?
减少/减少冲突可能会出现在 有效 LALR(1)语法中,因为从LR(1)到LALR(1)的状态合并, 对?
YACC和GNU Bison中使用的优先级和关联性是为帮助解决转移/减少冲突而引入的工具,对吧?
此外,如果冲突的shift / reduce规则优先级等于前瞻符号优先级,则只能由解析器检查关联性,在任何其他情况下,关联性是无关紧要的,对吗?
我在问,因为我不是100%肯定,并且这些书没有提供有关冲突解决的详细信息,我在这个主题上找到的唯一几行是in the GNU Bison Manual
与上述Bison手册链接相关的问题:
答案 0 :(得分:4)
如果在LALR(k)构造期间发现任何冲突(shift / reduce或reduce / reduce),则语法不是LALR(k)。
从LR(1)到LALR(1)的状态合并不能产生移位/减少冲突,所以如果有,则语法也不是LR(1)。但它可以产生减少/减少冲突。如果是,则语法不是LALR(1),即使它是LR(1)。 (这不是“有效性”的问题;它是特定算法可解析性的问题。)
是的,优先级(以及关联性,这只是优先级的一个子例程)允许解决转移/减少冲突。
优先顺序是 production (左侧)和前瞻标记(右侧)之间的比较。关联性影响使用的比较运算符:≤或< (或者,在%nonassoc
的情况下,错误相等)。
在Dragon book中对算法进行了很好的讨论。但是,它并不是很复杂:如果生产“获胜”,则解析器会减少;否则就会改变。
奖励问题:只有在为生产(通过%prec
或默认情况下,生产中的最后一个终端的优先级)和前瞻令牌定义优先级时,才会应用优先规则。如果其中任何一个缺少优先级声明,则shift获胜。这似乎不符合逻辑,但它就是这样。