2013-06-01 62 views
0

所以我用我的语法有可怕的移位/减少错误。这里有一个最小的测试用例:野牛:固定移位/减少错误,不知道如何

%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 
       ; 

%% 

任何人都可以解释为什么我有移进/归约摆在首位的错误和为什么这个工作?这甚至是一个合适的解决方案?如果不是,那是什么?

回答

2

在您的第一个语法中,优先级声明绝对没有任何作用。优先级仅适用于包含终端的替代方案,优先级为:在你的第一个语法中,这将是binopunop的作品。但是这些作品的替代品是完全不含糊的;优先顺序不需要决定将​​减少到binop

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

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