我正在用Bison定义一个语法,我偶然发现了一个我想要消除的转变/减少冲突。冲突是由旨在匹配if/else
语句的规则引起的:
state 17
13 Stmt: IfBlock . OptionalElseBlock
ELSE shift, and go to state 42
ELSE [reduce using rule 16 (OptionalElseBlock)]
$default reduce using rule 16 (OptionalElseBlock)
OptionalElseBlock go to state 43
OptionalElseBlock
的定义如下:
16 OptionalElseBlock: /* empty */
17 | ELSE Stmt
状态42和43看起来像这样,省略了shift和reduce信息:
state 42
17 OptionalElseBlock: ELSE . Stmt
state 43
13 Stmt: IfBlock OptionalElseBlock .
之前我使用过可选令牌,但我猜测因为解析器的前瞻缓冲区只包含1个终端OptionalElseBlock
会导致冲突。有没有简单的方法可以解决这个冲突?
答案 0 :(得分:0)
这是经典的转移/减少冲突。问题如下:
if (c1) if (c2) stmt1; else stmt2;
问题是if
所属的else
。如果它不是可选的,那么就没有问题,或者if
语句必须被终止(比如fi
或end
,以选择两个流行的替代方案),但是{ {1}}语法似乎已经赢了,因此我们可以改变/减少冲突。
写一个没有出现这个问题的语法是可能的,但并不重要。您可以通过使用优先规则玩游戏或仅仅“预期”转移/减少冲突来隐藏冲突。 (我更喜欢后者,但有很多人会说优先黑客更好,虽然它与imho相同。)
重写的语法是龙书中的一个练习,可能是其他解析文本,所以它可能值得为学习目的而做,但它在语法维护方面是一个真正的痛苦,它使得语法更难阅读,如果这完全是一个问题。
关于如何使用优先级和移位偏好来简化解析的经典论文是由Aho,Johnson和Ullman于1975年出版的“确定性解析模糊语法”。如果您无法访问好的图书馆,谷歌可能会找到一份您可以在线阅读的副本。
答案 1 :(得分:0)
您可能想查看我对同一问题的回答。这是一个FAQ。
Reforming the grammar to remove shift reduce conflict in if-then-else
我建议不要将%expect n
用于除0之外的任何内容。