Compiler construction 野牛-一元运算符何时真正需要%prec?
我现在第一次玩Flex和Bison。我读过关于上下文优先权的文章。尝试在不使用Compiler construction 野牛-一元运算符何时真正需要%prec?,compiler-construction,bison,lalr,Compiler Construction,Bison,Lalr,我现在第一次玩Flex和Bison。我读过关于上下文优先权的文章。尝试在不使用%prec指令的情况下构建一个最小的示例,因为我不太熟悉它的实际功能。这是我的最小示例 Flex文件 %option noyywrap %{ #include <iostream> #include "parser.h" int lineNum = 1; %} %% [ \t]+ ; \n { lineNum++; } \/\/(.*) ; "
%prec
指令的情况下构建一个最小的示例,因为我不太熟悉它的实际功能。这是我的最小示例
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(); }
%%
%{
#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
;
%%
#include <iostream>
int eval = 0;
extern int yyparse();
int main()
{
yyparse();
std::cout << eval << std::endl;
return 0;
}
%选项noyywrap
%{
#包括
#包括“parser.h”
int lineNum=1;
%}
%%
[\t]+;
\n{lineNum++;}
\/\/(.*) ;
“+”{return PLUS;}
“-”{返回减号;}
“*”{返回乘法;}
[0-9]+ {
yylval.int_val=atoi(yytext);
返回INT;
}
. {std::cout您的代码生成了错误的解析,但却是正确的结果,因为一元减号运算符等于乘以-1,并且乘法是关联的。因此,即使它将-2*3
解析为-(2*3)
而不是(-2)*3
,结果也是相同的
对于像-2-3
这样的表达式,您得到了正确的解析,因为您已经声明-
是左关联的,所以(-2)-3
比-(2-3)
更受欢迎,就像(1-2)-3
比1-(2-3)
更受欢迎一样
那么什么时候不需要声明一元负号的优先级呢?如果
- 唯一同时作为前缀和中缀的运算符是−
- 每个操作员⊕ 优先级高于(二进制)−, −(一)⊕(b)=(−(a)⊕b
- 你不在乎得到一个正确的解析树
这适用于*,但通常不适用于(整数)/和%。谢谢你的解释。不知何故,我没有想到一个错误的派生树。我还找到了一种方法,如何将bison转换为调试模式,在我看到堆栈上发生的一切之后,我看到了差异。我将试着用它来看看%prec
是如何工作的。它没有给出-2+3
的正确答案。它确实存在并且我看不出有任何理由不应该这样做。正如rici所说,它没有生成正确的解析树,但是它给出了正确的答案。基于-和+具有相同的优先级并且是左关联的事实,这个甚至生成了右解析树。