我目前是第一次玩 Flex 和 Bison。我已经阅读了Bison 手册页上的上下文优先级。试图在不使用%prec
指令的情况下构建一个最小的示例,因为我不太熟悉它的实际作用。这是我的最小示例。
弹性文件
%option noyywrap
%{
#include <iostream>
#include "parser.h"
int lineNum = 1;
%}
%%
[ \t]+ ;
\n { lineNum++; }
\/\/(.*) ;
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return MULTIPLY; }
[0-9]+ {
yylval.int_val = atoi(yytext);
return INT;
}
. { std::cout << "Unknown token " << yytext << " at line " << lineNum << std::endl; yyterminate(); }
%%
野牛文件
%{
#include <iostream>
#include <string>
extern int lineNum;
extern int yylex();
void yyerror(const char* e) { std::cerr << "ERROR ON LINE " << lineNum << ": " << e << std::endl; }
extern int eval;
%}
%union
{
int int_val;
}
%define parse.error verbose
%token <int_val> INT PLUS MINUS MULTIPLY
%type <int_val> expr
%left PLUS MINUS
%left MULTIPLY
%start expr
%%
expr : expr PLUS expr { $$ = $1 + $3; eval = $$; }
| expr MINUS expr { $$ = $1 - $3; eval = $$; }
| expr MULTIPLY expr { $$ = $1 * $3; eval = $$; }
| MINUS expr { $$ = -$2; eval = $$; }
| INT
;
%%
主 cpp 文件
#include <iostream>
int eval = 0;
extern int yyparse();
int main()
{
yyparse();
std::cout << eval << std::endl;
return 0;
}
我没有做过深度测试,但是对于我能想到的每一个使用一元减号的组合,我得到了正确的结果。我只是那么幸运,还是%prec
只在某些特殊情况下才需要该指令?当需要指令时,我也会欣赏示例,这样我就可以自己评估堆栈上的移位和减少。
谢谢