所以我的语法有可怕的转移/减少错误。这是一个最小的测试用例:
%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
;
%%
任何人都可以解释为什么我首先要改变/减少错误以及为什么这有效?这是否是一个合适的解决方案?如果没有,那是什么?
答案 0 :(得分:2)
在你的第一个语法中,优先级声明绝对没有任何作用。优先级仅适用于包含具有优先级的终端的备选方案;在你的第一个语法中,这将是binop
和unop
的作品。但这些作品的替代品完全是明确的;决定将PLUS
缩减为binop
不需要优先级。
在你的第二个语法中,优先关系确实有效,因为竞争的模糊替代(binops
和unops
的产生)直接包括终端。
换句话说,优先级不会“调查”非终端。