3

当 Yacc/Bison 中存在 shift/reduce 冲突时,是否可以强制冲突完全按照您的意愿解决?换句话说:是否可以明确强制它优先考虑转变或减少?

对于我所阅读的内容,如果您对默认分辨率感到满意,您可以告诉生成器不要抱怨它。我真的不喜欢这样,因为它混淆了你的理性选择。

另一种选择是重写语法以解决问题。我不知道这是否总是可能的,而且这通常会使它更难理解。

最后,我已经阅读了优先规则可以解决这个问题。我无能为力地尝试了很多方法,但我无法让它发挥作用。是否可以为此使用优先规则?如何?

虽然我的模棱两可的语法非常不同,但我可以使用Bison 手册中的经典 if-then-else来举一个具体的例子:

 %token IF THEN ELSE variable
 %%
 stmt:
   expr
 | if_stmt
 ;

 if_stmt:
   IF expr THEN stmt
 | IF expr THEN stmt ELSE stmt
 ;

 expr:
   variable
 ;
4

2 回答 2

1

好吧,移位/减少冲突的默认解决方案是移位,所以如果这是你想要的,你不需要做任何事情(除了忽略警告)。

如果你想通过减少来解决移位/减少冲突,你可以使用优先规则——只要确保要减少的规则的优先级高于要移位的令牌。如果存在涉及相同规则和令牌的多个移位/减少冲突,则可能无法找到全局一致的规则和令牌优先级集,从而以您想要的方式解决问题。

于 2012-08-27T22:09:02.557 回答
1

据我所知,不可能通过选择减少来指导解析器解决 S/R 冲突。虽然我可能是错的,但无论如何,这样做可能是不明智的。因此,唯一的可能性是要么重写语法,要么通过移位解决冲突。

以下右优先的用法THEN描述ELSEif-then-else语句的期望行为(即else与最里面的if语句相关联)。

%token IF THEN ELSE variable
%right THEN ELSE

%%

stmt
    : expr
    | if_stmt
    ;

if_stmt
    : IF expr THEN stmt
    | IF expr THEN stmt ELSE stmt
    ;

expr
    : variable
    ;

通过为上述标记选择正确的关联,以下序列:

IF expr1 THEN IF expr2 THEN IF expr3 THEN x ELSE y

被解析为:

IF expr1 THEN (IF expr2 THEN (IF expr3 THEN (x ELSE (y))))

野牛不再抱怨这个案子。

请记住,您始终可以运行bison file.y -r all并检查file.output以查看生成的解析器状态机是否正确。

于 2012-08-27T20:36:37.400 回答