C指針原理(12)

轉自:http://blog.csdn.net/myhaspl/article/details/14644629

(2)擴充計算器

加入對括號和註釋的支持,

首先修改flex文件,在第二部分加入更多的詞法規則(對於註釋直接忽略)

"("   {return LEFTBRACKET;}

")"   {return RIGHTBRACKET;}

"#".* /*忽略註釋*/

然後,修改bison文件,在第二部分加入更多的語法規則:

term:NUMBER {$$=$1;}

  |ABS term {$$=$2>=0?$2:-$2;}

  |LEFTBRACKET exp RIGHTBRACKET {$$=$2;}

  ;

 

我們的註釋以“#”表示

測試結果

myhaspl@myhaspl:~/flex_bison/2$ make

bison -d calculator.y

flex calculator.l

gcc calculator.tab.c  lex.yy.c -lfl

myhaspl@myhaspl:~/flex_bison/2$ ls

a.out         calculator.tab.c  calculator.y  makefile

calculator.l  calculator.tab.h  lex.yy.c

myhaspl@myhaspl:~/flex_bison/2$ ./a.out

12-36*10/(1+2+3)#compute

=-48

^C

myhaspl@myhaspl:~/flex_bison/2$ 

前面都是以鍵盤輸入 的方式進行計算器運算,我們下面以文件方式提供給該解釋器進行計算,首先,將flex文件改爲(將其中中文去除,然後對於非法字符的出現進行忽略):

%{
#include "calculator.tab.h"
%}


%%
"+"   {return ADD;}
"-"   {return SUB;}
"*"   {return MUL;}
"/"   {return DIV;}
"|"   {return ABS;}
"("   {return LEFTBRACKET;}
")"   {return RIGHTBRACKET;}
"#".* /*comment*/
[0-9]+ {yylval=atoi(yytext);return NUMBER;}
\n  {return EOL;}
[ \t] /*blank*/
. /*invalid char*/
%

接着,改bison文件,加入對文件的讀寫

%{
#include <stdio.h>
%}


%token NUMBER
%token ADD SUB MUL DIV ABS LEFTBRACKET RIGHTBRACKET
%token EOL 


%%


calclist:/**/
  |calclist exp EOL{printf ("=%d\n",$2);}
  ;
  
exp:factor {$$ = $1;}
  |exp ADD factor{$$=$1+$3;}
  |exp SUB factor{$$=$1-$3;}
  ;
 
 
factor:term {$$=$1;}
  |factor MUL term{$$=$1*$3;}
  |factor DIV term{$$=$1/$3;}
  ;
term:NUMBER {$$=$1;}
  |ABS term {$$=$2>=0?$2:-$2;}
  |LEFTBRACKET exp RIGHTBRACKET {$$=$2;}
  ;
%%
main(int argc,char **argv){
int i;
if (argc<2){
   yyparse();
}
else{
   for(i=1;i<argc;i++)
       {
       FILE *f=fopen(argv[i],"r");
       if (!f){
          perror(argv[i]);
          return (1);
       }
      yyrestart(f);
      yyparse();
      fclose(f);
   }
}
}


yyerror(char *s)
{
  fprintf(stderr,"error:%s\n",s);
}


最後 測試一下

root@myhaspl:~/test/3# make
bison -d calculator.y
flex calculator.l
gcc calculator.tab.c  lex.yy.c -lfl
root@myhaspl:~/test/3# ./a.out mycpt1.cpt mycpt2.cpt
=158
=-8
root@myhaspl:~/test/3# 

其中兩個CPT文件內容類似 爲:

12*66/(10-5)



發佈了15 篇原創文章 · 獲贊 22 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章