【问题标题】:Bison %prec doesn't work野牛 %prec 不起作用
【发布时间】:2013-11-15 00:39:05
【问题描述】:

我正在用 flex 和 bison 实现一个简单的计算器。

我希望以下输入给出 -4 而不是 4:

-2^2

为了达到-4,我不得不声明^运算符的优先级高于一元减号运算符的优先级,但它不起作用。

这是野牛代码:

%{

#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

为什么野牛不先处理 2^2 然后添加一元减号,就像我定义的那样? 它继续打印 4...

非常感谢帮助。

【问题讨论】:

  • 很高兴看到您知道求幂是右结合的。您实际上并不需要词法分析器中的 UNARY 规则。
  • [+|\-] 匹配三个字符 +|- 中的任何一个。我认为您不想接受|。此外,如果 - 在字符类中是第一个或最后一个,则不需要转义它。所以你可以写[+-][-+]

标签: c++ bison flex-lexer


【解决方案1】:

一元减号的语法:

 '-' INTEGER %prec UMINUS

不允许其参数是表达式。所以它明确地抓住了以下INTEGER,并且永远不需要%prec规则。


%prec 的问题在于,如果不需要该规则,yacc/bison 不会抱怨。所以你永远不知道它是否有任何作用。恕我直言,最好只写一个明确的语法。

【讨论】:

  • +1 很好看,我应该看到的。我同意你的评论。我更喜欢用术语和因素等写出标准表达式语法。
  • @rici:嗯,实际上 Bison 确实抱怨无用的 %prec。除非你的意思是别的?在此处查看“优先级”:gnu.org/software/bison/manual/bison.html#Bison-Options
  • @akim:这很酷。但是:您需要使用 bison3,这在发行版中还不是很常见,并且您需要专门要求 bison 产生警告(或使用 -Wall),这无疑是个好主意,但是不是常识。 (不过我会开始推荐它。)即便如此,它也不会抱怨“%prec”;它抱怨UMINUSUPLUS 的声明。这当然是一个进步。感谢您引起我的注意。但我认为“野牛确实抱怨”有点言过其实。 “如果你问得好,新版本的 Bison 会抱怨......” :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 2013-08-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多