野牛中一元运算符的规则
rules for unary operators in bison
我正在尝试为算术运算和一元运算符编写 bison 表达式。一元运算符的规则应该是
--6不接受,-(-6)接受
4--5 和 4+-5 不被接受,但 4-(-5) 被接受
不接受 4*-5 和 4/-5,但接受 4*(-5)
3-不被接受
-3*4 被接受
规则是
line
: assign '\n' {
long temp=eval();
LIST_EXPR[count-1].value=temp;
LIST_EXPR[count-1].flag=1;
printf(" %ld\n", LIST_EXPR[count-1].value);
}
;
assign
: VAR '=' expr { $$ = make_binop(EQUAL, BINOP_EXPR, make_var(), ); add_to_list_expr(,count); count++;}
| expr {add_to_list_expr(,count); count++;}
;
expr
: expr '+' term { $$ = make_binop(PLUS,BINOP_EXPR, , );}
| expr '-' term { $$ = make_binop(MINUS,BINOP_EXPR, , );}
| term
;
term
: term '*' factor { $$ = make_binop(TIME,BINOP_EXPR, , );}
| term '/' factor { $$ = make_binop(DIV,BINOP_EXPR, , ); }
| term '%' factor { $$ = make_binop(MOD,BINOP_EXPR, , ); }
| factor
| pre
;
pre:
'-' factor {$$=make_binop(UMINUS,BINOP_EXPR, , NULL);}
| '+' factor {$$=make_binop(UPLUS,BINOP_EXPR, , NULL);}
;
factor
: '(' expr ')' { $$ = ; }
| CONST { $$ = make_const(); }
| VAR { $$ = make_var(); }
| '#' factor {$$=make_binop(LINE_REF,BINOP_EXPR, , NULL);}
;
问题是一元数出现在右边就被接受,比如3--4就被接受,而应该不被接受。这个问题只发生在 + 和 - 操作上。
有谁知道怎么解决
你的语法有:
expr: expr '-' term
term: pre
pre : '-' factor
所以3--4必须接受; -4
缩减为 pre
然后 term
,然后 3--4
变成 expr - term
,缩减为 expr
.
同样-3*4
会将-3
缩小为pre
然后term
,之后可以用来将-3*4
缩小为term
], 通过使用 term: term '*' factor
.
我不清楚为什么你希望 3--4
无效,而你愿意接受 -3-4
和 -3*4
。恕我直言,3--4
不会比其他两个更令人困惑,并且不会产生任何歧义。
但如果那是你想要的,你可以通过区分可以是一元表达式的 term
和不能(未经测试)的
来实现:
expr : expr '+' rterm
| expr '-' rterm
| term
rterm: term '*' factor
| term '/' factor
| term '%' factor
| factor
term : rterm | pre
pre : '-' factor | '+' factor
factor: VAR | CONST | '#' factor | '(' expr ')'
我正在尝试为算术运算和一元运算符编写 bison 表达式。一元运算符的规则应该是
--6不接受,-(-6)接受
4--5 和 4+-5 不被接受,但 4-(-5) 被接受
不接受 4*-5 和 4/-5,但接受 4*(-5)
3-不被接受
-3*4 被接受
规则是
line
: assign '\n' {
long temp=eval();
LIST_EXPR[count-1].value=temp;
LIST_EXPR[count-1].flag=1;
printf(" %ld\n", LIST_EXPR[count-1].value);
}
;
assign
: VAR '=' expr { $$ = make_binop(EQUAL, BINOP_EXPR, make_var(), ); add_to_list_expr(,count); count++;}
| expr {add_to_list_expr(,count); count++;}
;
expr
: expr '+' term { $$ = make_binop(PLUS,BINOP_EXPR, , );}
| expr '-' term { $$ = make_binop(MINUS,BINOP_EXPR, , );}
| term
;
term
: term '*' factor { $$ = make_binop(TIME,BINOP_EXPR, , );}
| term '/' factor { $$ = make_binop(DIV,BINOP_EXPR, , ); }
| term '%' factor { $$ = make_binop(MOD,BINOP_EXPR, , ); }
| factor
| pre
;
pre:
'-' factor {$$=make_binop(UMINUS,BINOP_EXPR, , NULL);}
| '+' factor {$$=make_binop(UPLUS,BINOP_EXPR, , NULL);}
;
factor
: '(' expr ')' { $$ = ; }
| CONST { $$ = make_const(); }
| VAR { $$ = make_var(); }
| '#' factor {$$=make_binop(LINE_REF,BINOP_EXPR, , NULL);}
;
问题是一元数出现在右边就被接受,比如3--4就被接受,而应该不被接受。这个问题只发生在 + 和 - 操作上。
有谁知道怎么解决
你的语法有:
expr: expr '-' term
term: pre
pre : '-' factor
所以3--4必须接受; -4
缩减为 pre
然后 term
,然后 3--4
变成 expr - term
,缩减为 expr
.
同样-3*4
会将-3
缩小为pre
然后term
,之后可以用来将-3*4
缩小为term
], 通过使用 term: term '*' factor
.
我不清楚为什么你希望 3--4
无效,而你愿意接受 -3-4
和 -3*4
。恕我直言,3--4
不会比其他两个更令人困惑,并且不会产生任何歧义。
但如果那是你想要的,你可以通过区分可以是一元表达式的 term
和不能(未经测试)的
expr : expr '+' rterm
| expr '-' rterm
| term
rterm: term '*' factor
| term '/' factor
| term '%' factor
| factor
term : rterm | pre
pre : '-' factor | '+' factor
factor: VAR | CONST | '#' factor | '(' expr ')'