В настоящее время я играю с Flex и Bison в первый раз. Я прочитал о контекстуальном приоритете на Bison manual page. Попытался создать минимальный пример, не используя директиву %prec
, поскольку я не знаю, что он на самом деле делает. Вот мой минимальный пример.Bison - когда действительно необходимо для унарных операторов?
Flex файл
%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(); }
%%
Bison файл
%{
#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;
}
я не сделал d eep, но для каждой отдельной комбинации с использованием унарного минуса я мог придумать, я получил правильный результат. Мне просто повезло, или директива %prec
нужна только в некоторых особых случаях? Кроме того, я был бы признателен, если потребуется директива, чтобы я мог самостоятельно оценивать сдвиги и сворачивать в стек.
Благодаря
Он не дает правильного ответа для '-2 + 3'. – EJP
Он делает, и я не вижу причин, почему это не должно. Как сказал Ричи, он не создает правильное дерево разбора, однако он дает правильный ответ. И исходя из того, что - и + имеют одинаковые приоритеты и остаются ассоциативными, этот даже создает правильное дерево разбора. –