Parsing 冲突:2班/减少
我正试图用GNU bison编写一个小的解释器。 我想问是否有人可以解释指令%right和%left之间的区别,以及我的错误在下面的代码中的位置Parsing 冲突:2班/减少,parsing,gnu,bison,yacc,Parsing,Gnu,Bison,Yacc,我正试图用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> e
%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 { $$ = $1; }
| NAME '(' ')' { $$ = ycall($1); }
| NAME '(' exp ')' { $$ = ycall($1, $3); }
| NAME '(' exp ',' exp ')' { $$ = ycall($1, $3, $5); }
| NAME '=' exp { $$ = 1; ysetvar($1, $3); }
| NAME %prec VAR { $$ = ygetvar($1); }
| '_' exp %prec ARG { $$ = ygetarg($2, args); }
| '(' exp ')' { $$ = $2; }
/* 1 Operand */
| '-' exp %prec NEG { $$ = - $2; }
| '~' exp %prec NOT { $$ = ~ static_cast<int>($2); }
| '!' exp %prec LOGIC_NOT { $$ = ! static_cast<int>($2); }
/* 2 Operands */
| exp '+' exp { $$ = $1 + $3; }
| exp '-' exp { $$ = $1 - $3; }
| exp '*' exp { $$ = $1 * $3; }
| exp '/' exp { $$ = $1 / $3; }
| exp '%' exp { $$ = static_cast<int>($1) % static_cast<int>($3); }
| exp '^' exp { $$ = pow($1, $3); }
| exp '&' exp { $$ = static_cast<int>($1) & static_cast<int>($3); }
| exp '|' exp { $$ = static_cast<int>($1) | static_cast<int>($3); }
| exp 'x' exp { $$ = static_cast<int>($1) ^ static_cast<int>($3); }
;
%token-FLO
%令牌名
%对“=”
%左'+''-'
%左'*''/''%
%左'&''|''x'
%左负非逻辑
%左“^”
%左ARG
%类型exp
%%
语言:/*无*/
|语言状态
声明:'\n'
|经验
|错误{yyerrok;}
;
exp:FLO{$$=$1;}
|名称“(“”){$$=ycall($1);}
|名称“('exp')”{$$=ycall($1,$3);}
|名称“('exp','exp')”{$$=ycall($1,$3,$5);}
|名称“=”exp{$$=1;ysetvar($1,$3);}
|名称%prec VAR{$$=ygetvar($1);}
|“u”exp%prec ARG{$$=YGETAG($2,args);}
|“('exp')”{$$=$2;}
/*1操作数*/
|“-”exp%prec NEG{$$=-$2;}
|“~”exp%prec NOT{$$=~static_cast($2);}
| '!' exp%prec LOGIC_NOT{$$=!static_cast($2);}
/*2个操作数*/
|exp'+'exp{$$=$1+$3;}
|exp'-'exp{$$=$1-$3;}
|exp'*'exp{$$=$1*$3;}
|exp'/'exp{$$=$1/$3;}
|exp“%”exp{$$=static_cast($1)%static_cast($3);}
|exp'^'exp{$$=pow($1,$3);}
|exp'&'exp{$$=static_cast($1)和static_cast($3);}
|exp'|'exp{$$=static_cast($1)| static_cast($3);}
|exp'x'exp{$$=static_cast($1)^ static_cast($3);}
;
查看yacc或bison使用-v参数生成的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)
在这种情况下,冲突发生在'(“
在名称
之后)——这是语法中的一种歧义,它可能是一个调用表达式,也可能是一个简单的名称
表达式,后跟一个括号表达式,因为您的语言中的语句之间没有分隔符
第二个冲突是:
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
可能是一个二进制减法语句,也可能是两个语句--一个名称后跟一元否定
如果在语句之间添加分隔符(如
;
),这两种冲突都会消失。代码段中没有%left
或%right
,也没有解释您认为程序有问题的原因。我忘了共享一些代码(flo是双精度代码)。我现在已经更正了。