我正在使用 flex 和 bison 实现一个简单的计算器。
我希望以下输入给出 -4 而不是 4:
-2^2
为了实现-4,我不得不声明^运算符的优先级高于一元减号运算符的优先级,但这是行不通的。
这是 Bison 代码:
%{
#include <iostream>
#include <math.h>
using namespace std;
void yyerror(const char *s);
int yylex();
%}
%union {
int int_val;
char* string_val;
double double_val;
}
%token INTEGER
%left '+' '-'
%left '*' '/' '%'
%left UMINUS UPLUS
%right '^'
%type <int_val> expr_int INTEGER
%%
program: line '\n'
| '\n' { return 0; }
;
line: expr_int { cout<<$1<<endl; return 0; }
;
expr_int: expr_int '+' expr_int { $$ = $1 + $3; }
| expr_int '-' expr_int { $$ = $1 - $3; }
| expr_int '*' expr_int { $$ = $1 * $3; }
| expr_int '^' expr_int { $$ = pow($1,$3); }
| '-' INTEGER %prec UMINUS { $$ = -$2; }
| '+' INTEGER %prec UPLUS { $$ = $2; }
| INTEGER
;
%%
void yyerror(const char *s) {
printf("error");
}
int main(void) {
while(yyparse()==0);
return 0;
}
这是弹性代码:
%{
#include <iostream>
#include "calc.tab.h"
using namespace std;
void yyerror(const char *s);
%}
INTEGER [1-9][0-9]*|0
UNARY [+|\-]
BINARY [+|\-|*|^|]
WS [ \t]+
%%
{INTEGER} { yylval.int_val=atoi(yytext); return INTEGER; }
{UNARY}|{BINARY}|\n { return *yytext; }
{WS} {}
. {}
%%
//////////////////////////////////////////////////
int yywrap(void) { return 1; } // Callback at end of file
为什么 bison 不像我定义的那样先处理 2^2 然后加上一元减号? 它继续打印 4 而不是...
非常感谢帮助者。
最佳答案
一元减号的语法:
'-' INTEGER %prec UMINUS
不允许它的参数是一个表达式。因此它明确地获取了以下 INTEGER
并且永远不需要 %prec
规则。
<个人意见>
%prec
的问题是如果不需要规则,yacc/bison 不会提示。所以你永远不知道它是否有任何作用。恕我直言,只写一个明确的语法真的更好。
关于c++ - Bison %prec 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19991365/