用Bison编写逆波兰式表达式计算器

为什么80%的码农都做不了架构师?>>>   hot3.png

下载并安装Bison

# 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语言代码,编译并执行。

     /* Reverse polish notation calculator.  */ 
      
     
%{ 
       
#define YYSTYPE double 
       
#include  
       
#include  
       
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  
      
     
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  
      
     
/* Called by yyparse on error.  */ 
     
void 
     yyerror
(char const *s) 
     
{ 
       fprintf
(stderr, "%s\n", s); 
     
}

运行以下命令把rpcalc.y转化成解析文件

     # bison rpcalc.y

编译

     ## 显示当前文件 
     
# 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

运行

     #./rpcalc 
     
4 0 +                    //输入 
       
4                      //运算结果 
     
3 7 + 3 4 5 *+           //输入 
       
-13                    //运算结果 
     
3 7 + 3 4 5 * + - n      //输入 
       
13                     //运算结果 
     
5 6 / 4 n +              //输入 
       
-3.166666667           //运算结果

 

转载于:https://my.oschina.net/sec/blog/9478

你可能感兴趣的:(用Bison编写逆波兰式表达式计算器)