野牛:修正了班次/减少错误,没有任何线索如何

时间:2013-06-01 20:56:04

标签: bison yacc shift-reduce-conflict

所以我的语法有可怕的转移/减少错误。这是一个最小的测试用例:

%token PLUS MINUS TIMES DIVIDE NUMBER
%token EQUAL NEQUAL GREATER LESS NOT

%left   EQUAL   NEQUAL
%left   GREATER LESS
%left   PLUS    MINUS
%left   TIMES   DIVIDE
%left   UMINUS  NOT

%%

exp             : exp binop exp
                | unop exp
                | NUMBER
                ;

binop           : MINUS
                | PLUS
                | TIMES
                | DIVIDE
                | EQUAL
                | NEQUAL
                | GREATER
                | LESS
                ;

unop            : MINUS %prec UMINUS
                | NOT
                ;

%%

但是,通过实验,我设法让问题消失了:

%token PLUS MINUS TIMES DIVIDE NUMBER
%token EQUAL NEQUAL GREATER LESS NOT

%left   EQUAL   NEQUAL
%left   GREATER LESS
%left   PLUS    MINUS
%left   TIMES   DIVIDE
%left   UMINUS  NOT

%%

exp             : binops
                | unops
                | NUMBER
                ;

unops           : MINUS exp %prec UMINUS
                | NOT exp
                ;

binops          : exp MINUS exp
                | exp PLUS exp
                | exp TIMES exp
                | exp DIVIDE exp
                | exp EQUAL exp
                | exp NEQUAL exp
                | exp GREATER exp
                | exp LESS exp
                ;

%%

任何人都可以解释为什么我首先要改变/减少错误以及为什么这有效?这是否是一个合适的解决方案?如果没有,那是什么?

1 个答案:

答案 0 :(得分:2)

在你的第一个语法中,优先级声明绝对没有任何作用。优先级仅适用于包含具有优先级的终端的备选方案;在你的第一个语法中,这将是binopunop的作品。但这些作品的替代品完全是明确的;决定将PLUS缩减为binop不需要优先级。

在你的第二个语法中,优先关系确实有效,因为竞争的模糊替代(binopsunops的产生)直接包括终端。

换句话说,优先级不会“调查”非终端。