如何解决转移/减少冲突迫使转变或减少?

时间:2012-08-22 01:09:50

标签: grammar bison yacc shift-reduce-conflict

当Yacc / Bison发生转移/减少冲突时,是否有可能强制解决冲突?换句话说:是否有可能明确强制它优先考虑转变或减少?

对于我所读过的内容,如果您对默认分辨率感到满意,可以将生成器告诉not complain about it。我真的不喜欢这个,因为它混淆了你理性的选择。

另一种选择是重写语法来解决问题。我不知道这是否总是可行的,而且往往这使得理解起来更加困难。

最后,我已经阅读了优先规则可以解决这个问题。我无知在很多方面尝试过,我无法使它发挥作用。是否可以使用优先规则?怎么样?

虽然我的模糊语法非常不同,但我可以使用Bison manual中的经典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
 ;

2 个答案:

答案 0 :(得分:1)

据我所知,通过选择reduce来指示解析器解决S / R冲突是不可能的。虽然我可能错了,但无论如何都不应该这样做。因此,唯一的可能性是重写语法,或通过转移来解决冲突。

THENELSE的正确的早期使用的以下用法描述了if-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不再抱怨此案。

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

答案 1 :(得分:1)

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

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