0

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を印刷し続けます...

ヘルパーに感謝します。

4

1 に答える 1

4

Your syntax for unary minus:

 '-' INTEGER %prec UMINUS

does not allow its argument to be an expression. So it unambiguously grabs the following INTEGER and the %prec rule is never needed.


<personal_opinion> The problem with %prec is that yacc/bison does not complain if the rule is not needed. So you never really know if it does anything or not. IMHO it's really better to just write an unambiguous grammar.

于 2013-11-15T03:16:41.283 に答える