2013-11-15 100 views
0

我正在實現一個簡單的計算器與flex和野牛。野牛%prec不起作用

我想下面的輸入給予-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; 
} 

這是Flex代碼:

%{ 

#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,而不是...

非常感謝助手。

+0

很高興看到你知道指數是正確聯合的。您並不需要詞法分析器中的UNARY規則。 – EJP

+2

'[+ | \ - ]'匹配'+',''''或'-'三個字符中的任何一個。我不認爲你想接受'|'。另外,如果它是字符類中的第一個或最後一個,則不需要轉義'-'。所以你可以只寫'[+ - ]'或'[ - +]'。 – rici

回答

4

您的一元減語法:

'-' INTEGER %prec UMINUS 

不允許它的參數是一個表達式。所以它明確地抓住以下INTEGER%prec規則是不需要的。


<personal_opinion> 與%prec的問題是,如果不需要規則的yacc /野牛不抱怨。所以你永遠不知道它是否做了任何事情。恕我直言,最好只寫一個毫不含糊的語法。

+0

+1看上去好了,我應該看到了。我同意你的評論。我更喜歡用術語和因素以及所有這些寫出標準表達式語法。 – EJP

+0

@rici:好吧,實際上Bison的確抱怨無用的'%prec'。除非你的意思是別的嗎?請參閱此處的「優先順序」:http://www.gnu.org/software/bison/manual/bison.html#Bison-Options – akim

+0

@akim:很酷。但是:你需要使用bison3,這在發行版中還不常見,*和*你需要特別要求野牛產生警告(或使用'-Wall'),這無疑是一個好主意,但不是常識。 (儘管如此,我會開始推薦它。)即便如此,它並不會抱怨「%prec」。它抱怨'UMINUS'和'UPLUS'的聲明。這無疑是向前邁進的一步。感謝您的關注。但我認爲「野牛*抱怨」有點誇大其辭。 「如果你很好地問他們,Bison的新版本會抱怨...」:) – rici