冲突:2 shift/reduce
conflicts: 2 shift/reduce
我正在尝试用 GNU bison 编写一个小解释器。
我想问一下是否有人可以解释指令%right 和%left 之间的区别以及我在下面的代码中的错误。
%token <flo> FLO
%token <name> NAME
%right '='
%left '+' '-'
%left '*' '/' '%'
%left '&' '|' 'x'
%left NEG NOT LOGIC_NOT
%left '^'
%left ARG
%type <flo> exp
%%
language: /* nothing */
| language statment
statment: '\n'
| exp
| error { yyerrok; }
;
exp: FLO { $$ = ; }
| NAME '(' ')' { $$ = ycall(); }
| NAME '(' exp ')' { $$ = ycall(, ); }
| NAME '(' exp ',' exp ')' { $$ = ycall(, , ); }
| NAME '=' exp { $$ = 1; ysetvar(, ); }
| NAME %prec VAR { $$ = ygetvar(); }
| '_' exp %prec ARG { $$ = ygetarg(, args); }
| '(' exp ')' { $$ = ; }
/* 1 Operand */
| '-' exp %prec NEG { $$ = - ; }
| '~' exp %prec NOT { $$ = ~ static_cast<int>(); }
| '!' exp %prec LOGIC_NOT { $$ = ! static_cast<int>(); }
/* 2 Operands */
| exp '+' exp { $$ = + ; }
| exp '-' exp { $$ = - ; }
| exp '*' exp { $$ = * ; }
| exp '/' exp { $$ = / ; }
| exp '%' exp { $$ = static_cast<int>() % static_cast<int>(); }
| exp '^' exp { $$ = pow(, ); }
| exp '&' exp { $$ = static_cast<int>() & static_cast<int>(); }
| exp '|' exp { $$ = static_cast<int>() | static_cast<int>(); }
| exp 'x' exp { $$ = static_cast<int>() ^ static_cast<int>(); }
;
查看带有 -v 参数的 yacc 或 bison 生成的 y.output 文件。第一个冲突在状态 5:
State 5
7 exp: NAME . '(' ')'
8 | NAME . '(' exp ')'
9 | NAME . '(' exp ',' exp ')'
10 | NAME . '=' exp
11 | NAME .
'=' shift, and go to state 14
'(' shift, and go to state 15
'(' [reduce using rule 11 (exp)]
$default reduce using rule 11 (exp)
在这种情况下,冲突是在 NAME
之后有一个 '('
—— 这是语法中的歧义,它可能是一个调用表达式,或者它可能是一个简单的NAME
表达式后跟一个带括号的表达式,因为在您的语言中语句之间没有分隔符。
第二个冲突是:
State 13
4 statment: exp .
17 exp: exp . '+' exp
18 | exp . '-' exp
19 | exp . '*' exp
20 | exp . '/' exp
21 | exp . '%' exp
22 | exp . '^' exp
23 | exp . '&' exp
24 | exp . '|' exp
25 | exp . 'x' exp
'+' shift, and go to state 21
'-' shift, and go to state 22
'*' shift, and go to state 23
'/' shift, and go to state 24
'%' shift, and go to state 25
'&' shift, and go to state 26
'|' shift, and go to state 27
'x' shift, and go to state 28
'^' shift, and go to state 29
'-' [reduce using rule 4 (statment)]
$default reduce using rule 4 (statment)
本质上是同一个问题,这次是 '-'
——输入 NAME - NAME
可能是一个二进制减法语句,也可能是两个语句——一个 NAME 后跟一元否定。
如果您在语句之间添加一个分隔符(例如 ;
),这些冲突都会消失。
我正在尝试用 GNU bison 编写一个小解释器。 我想问一下是否有人可以解释指令%right 和%left 之间的区别以及我在下面的代码中的错误。
%token <flo> FLO
%token <name> NAME
%right '='
%left '+' '-'
%left '*' '/' '%'
%left '&' '|' 'x'
%left NEG NOT LOGIC_NOT
%left '^'
%left ARG
%type <flo> exp
%%
language: /* nothing */
| language statment
statment: '\n'
| exp
| error { yyerrok; }
;
exp: FLO { $$ = ; }
| NAME '(' ')' { $$ = ycall(); }
| NAME '(' exp ')' { $$ = ycall(, ); }
| NAME '(' exp ',' exp ')' { $$ = ycall(, , ); }
| NAME '=' exp { $$ = 1; ysetvar(, ); }
| NAME %prec VAR { $$ = ygetvar(); }
| '_' exp %prec ARG { $$ = ygetarg(, args); }
| '(' exp ')' { $$ = ; }
/* 1 Operand */
| '-' exp %prec NEG { $$ = - ; }
| '~' exp %prec NOT { $$ = ~ static_cast<int>(); }
| '!' exp %prec LOGIC_NOT { $$ = ! static_cast<int>(); }
/* 2 Operands */
| exp '+' exp { $$ = + ; }
| exp '-' exp { $$ = - ; }
| exp '*' exp { $$ = * ; }
| exp '/' exp { $$ = / ; }
| exp '%' exp { $$ = static_cast<int>() % static_cast<int>(); }
| exp '^' exp { $$ = pow(, ); }
| exp '&' exp { $$ = static_cast<int>() & static_cast<int>(); }
| exp '|' exp { $$ = static_cast<int>() | static_cast<int>(); }
| exp 'x' exp { $$ = static_cast<int>() ^ static_cast<int>(); }
;
查看带有 -v 参数的 yacc 或 bison 生成的 y.output 文件。第一个冲突在状态 5:
State 5
7 exp: NAME . '(' ')'
8 | NAME . '(' exp ')'
9 | NAME . '(' exp ',' exp ')'
10 | NAME . '=' exp
11 | NAME .
'=' shift, and go to state 14
'(' shift, and go to state 15
'(' [reduce using rule 11 (exp)]
$default reduce using rule 11 (exp)
在这种情况下,冲突是在 NAME
之后有一个 '('
—— 这是语法中的歧义,它可能是一个调用表达式,或者它可能是一个简单的NAME
表达式后跟一个带括号的表达式,因为在您的语言中语句之间没有分隔符。
第二个冲突是:
State 13
4 statment: exp .
17 exp: exp . '+' exp
18 | exp . '-' exp
19 | exp . '*' exp
20 | exp . '/' exp
21 | exp . '%' exp
22 | exp . '^' exp
23 | exp . '&' exp
24 | exp . '|' exp
25 | exp . 'x' exp
'+' shift, and go to state 21
'-' shift, and go to state 22
'*' shift, and go to state 23
'/' shift, and go to state 24
'%' shift, and go to state 25
'&' shift, and go to state 26
'|' shift, and go to state 27
'x' shift, and go to state 28
'^' shift, and go to state 29
'-' [reduce using rule 4 (statment)]
$default reduce using rule 4 (statment)
本质上是同一个问题,这次是 '-'
——输入 NAME - NAME
可能是一个二进制减法语句,也可能是两个语句——一个 NAME 后跟一元否定。
如果您在语句之间添加一个分隔符(例如 ;
),这些冲突都会消失。