用Bison編寫逆波蘭式表達式計算器

下載並安裝Bisonhtml

# wget ftp://ftp.gnu.org/gnu/bison/bison-2.4.3.tar.gz 
# gzip -dc bison-2.4.3.tar.gz | tar xf - 
# cd bison-2.4.3 
# ./configure 
# make 
# make install

bison的詳細內容請參照 http://www.gnu.org/software/bison/。 爲了測試Bison的運行,能夠參照 http://www.gnu.org/software/bison/manual/bison.html#RPN-Calc 裏面的例子 rpcalc.y(一個逆波蘭式表達式計算器)來生成C語言代碼,編譯並執行。git

     /* Reverse polish notation calculator.  */ 
      
     
%{ 
       
#define YYSTYPE double 
       
#include <math.h> 
       
#include <stdio.h> 
       
int yylex (void); 
       
void yyerror (char const *); 
     
%} 
      
     
%token NUM 
 
     
%% /* Grammar rules and actions follow.  */ 
 
     input
:    /* empty */ 
             
| input line 
     
; 
      
     line
:     '\n' 
             
| exp '\n'      { printf ("\t%.10g\n", $1); } 
     
; 
      
     exp
:      NUM           { $$ = $1;           } 
             
| exp exp '+'   { $$ = $1 + $2;      } 
             
| exp exp '-'   { $$ = $1 - $2;      } 
             
| exp exp '*'   { $$ = $1 * $2;      } 
             
| exp exp '/'   { $$ = $1 / $2;      } 
             
/* Exponentiation */ 
             
| exp exp '^'   { $$ = pow ($1, $2); } 
             
/* Unary minus    */ 
             
| exp 'n'       { $$ = -$1;          } 
     
; 
     
%% 
 
     
/* The lexical analyzer returns a double floating point 
        number on the stack and the token NUM, or the numeric code 
        of the character read if not a number.  It skips all blanks 
        and tabs, and returns 0 for end-of-input.  */
 
      
     
#include <ctype.h> 
      
     
int 
     yylex
(void) 
     
{ 
       
int c; 
      
       
/* Skip white space.  */ 
       
while ((c = getchar ()) == ' ' || c == '\t') 
         
; 
       
/* Process numbers.  */ 
       
if (c == '.' || isdigit (c)) 
         
{ 
           ungetc
(c, stdin); 
           scanf
("%lf", &yylval); 
           
return NUM; 
         
} 
       
/* Return end-of-input.  */ 
       
if (c == EOF) 
         
return 0; 
       
/* Return a single char.  */ 
       
return c; 
     
} 
 
     
int 
     main
(void) 
     
{ 
       
return yyparse (); 
     
} 
 
     
#include <stdio.h> 
      
     
/* Called by yyparse on error.  */ 
     
void 
     yyerror
(char const *s) 
     
{ 
       fprintf
(stderr, "%s\n", s); 
     
}

運行如下命令把rpcalc.y轉化成解析文件測試

     # bison rpcalc.y

編譯spa

     ## 顯示當前文件 
     
# ls 
     rpcalc
.tab.c  rpcalc.
      
     
## 編譯Bison parser. 
     
##‘-lm’ tells compiler to search math library for pow. 
     
# cc -lm -o rpcalc rpcalc.tab.c 
      
     
## 編譯後在此顯示當前文件 
     
# ls 
     rpcalc  rpcalc
.tab.c  rpcalc.y

運行code

     #./rpcalc 
     
4 0 +                    //輸入 
       
4                      //運算結果 
     
3 7 + 3 4 5 *+           //輸入 
       
-13                    //運算結果 
     
3 7 + 3 4 5 * + - n      //輸入 
       
13                     //運算結果 
     
5 6 / 4 n +              //輸入 
       
-3.166666667           //運算結果
相關文章
相關標籤/搜索