亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

C指針原理教程之編譯原理-小型計算器實現

2020-01-26 13:32:36
字體:
來源:轉載
供稿:網友

1、打開cygwin,進入home目錄,home目錄在WINDOWS系統的cygwin安裝目錄映射為home目錄。

2、首先,在home目錄中新建文件夾,在文件夾中放置如下內容的test1.l

/*統計字數*/%{int chars=0;int words=0;int lines=0;%}%%[a-zA-Z]+ {words++;chars+=strlen(yytext);}/n {chars++;lines++;}.  {chars++;}%%main(int argc,char**argv){  yylex();  printf("%d%d%d/n",lines,words,chars);}

然后調用flex生成詞法分析器

Administrator@2012-20121224HD /home/flexlinux$ cd /homeAdministrator@2012-20121224HD /home$ cd flexlinuxAdministrator@2012-20121224HD /home/flexlinux$ flex test1.lAdministrator@2012-20121224HD /home/flexlinux$

可以看到目錄中的lex.yy.c就是剛生成的C源碼,可分析詞法。

Administrator@2012-20121224HD /home/flexlinux$ lslex.yy.c test1.l

二、flex和bison聯合工作

1 、我們開始構造一個計算器程序。

創建flex代碼

/*計算器*/%{enum yytokentype{   NUMBER=258, ADD=259, SUB=260, MUL=261, DIV=262, ABS=263, EOL=264};int yylval;%}%%"+"  {return ADD;}"-"  {return SUB;}"*"  {return MUL;}"/"  {return DIV;}"|"  {return ABS;}[0-9]+ {yylval=atoi(yytext);return NUMBER;}/n {return EOL;}[ /t] {/*空白忽略*/}. {printf("非法字符 %c/n",*yytext);}%%main(int argc,char**argv){  int tok;  while(tok=yylex()){   printf("%d",tok); if (tok==NUMBER) printf("=%d/n",yylval); else printf("/n");  }}

2、編譯

Administrator@2012-20121224HD /home/flexlinux$ flex test2.lAdministrator@2012-20121224HD /home/flexlinux$ gcc lex.yy.c -lfl

3、運行

Administrator@2012-20121224HD /home/flexlinux$ ./a- 12 66260258=12258=66264Administrator@2012-20121224HD /home/flexlinux$ ./a/ 56 2 + |32262258=56258=2259263258=32264Administrator@2012-20121224HD /home/flexlinux$

(2)計算器的BISON程序

%{#include <stdio.h>%}%token NUMBER%token ADD SUB MUL DIV ABS%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;} ;%%main(int argc,char **argv){yyparse();}yyerror(char *s){ fprintf(stderr,"error:%s/n",s);}$ bison -d test2.yt$ lstest2.tab.c test2.tab.h test2.y test2.y~

然后,修改剛才的flex文件,將其命名為test21.l

test2.tab.h中包含了記號編號的定義和yylval的定義,因此,將其第一部分的相關定義刪除,并改為:

/計算器/

%{

  #include "test2.tab.h"

%}

然后刪除,其第三部分的main函數。

最后,進行編譯。

bison -d test2.yflex test21.lgcc test2.tab.c lex.yy.c -lfl

可以測試一下

root@myhaspl:~# ./a.out12 + 36 * 2=8412 / 6 + 2 * 3=8

(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$ makebison -d calculator.yflex calculator.lgcc calculator.tab.c lex.yy.c -lflmyhaspl@myhaspl:~/flex_bison/2$ lsa.out     calculator.tab.c calculator.y makefilecalculator.l calculator.tab.h lex.yy.cmyhaspl@myhaspl:~/flex_bison/2$ ./a.out12-36*10/(1+2+3)#compute=-48^Cmyhaspl@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# makebison -d calculator.yflex calculator.lgcc calculator.tab.c lex.yy.c -lflroot@myhaspl:~/test/3# ./a.out mycpt1.cpt mycpt2.cpt=158=-8root@myhaspl:~/test/3# 

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

12*66/(10-5)

我們接著完善這個計算器程序,讓算式能顯示出來,修改calculator.l

通過加入printf語句,打印詞法分析器解析到的字符。比如 :

..................

[0-9]+ {yylval=atoi(yytext);printf("%d",yylval);return NUMBER;}

/n  {return EOL;}

[ /t] /blank/

. /invalid char/

%%

然后編譯執行。

root@myhaspl:~/test/4# makebison -d calculator.yflex calculator.lgcc calculator.tab.c lex.yy.c -lflroot@myhaspl:~/test/4# ./a.out12+6612+66=78^Croot@myhaspl:~/test/4# ./a.out mycpt1.cpt mycpt2.cpt  12*66/(10-5)=15877/(10+1)-15=-8

接下來加上讀取的行號,將結果的顯示更加人性化

flex文件要改:

/n  {printf("<line:%4d>",yylineno);yylineno++;return EOL;}

然后,bison文件也改:

calclist:/**/
  |calclist exp EOL{printf ("the result is:%d/n",$2);}
  ;

最后 ,編譯運行測試一下。

root@myhaspl:~/test/4# makebison -d calculator.yflex calculator.lgcc calculator.tab.c lex.yy.c -lflroot@myhaspl:~/test/4# ./a.out mycpt1.cpt mycpt2.cpt1266/(10-5)<line:  1>the result is:15812/22-8<line:  2>the result is:-877(6-2)<line:  3>the result is:30877/(10+1)-15<line:  4>the result is:-8root@myhaspl:~/test/4# 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲欧洲美洲在线综合| 久久久久这里只有精品| 91地址最新发布| 91国内精品久久| 亚洲午夜未满十八勿入免费观看全集| 91大神福利视频在线| 亚洲午夜精品视频| 日韩欧美一区二区三区| 美女av一区二区三区| 亚洲偷欧美偷国内偷| 亚洲毛片在线观看| 亚洲福利视频免费观看| 欧美综合国产精品久久丁香| 久久精品久久久久久国产 免费| 久久91精品国产91久久跳| 亚洲qvod图片区电影| 日韩欧美一区二区三区久久| 国产在线不卡精品| 国产免费亚洲高清| 97人人爽人人喊人人模波多| 亚洲激情在线视频| 欧美性xxxxxxx| 欧美成人精品在线播放| 日韩中文字幕在线视频播放| 国产成人精品久久亚洲高清不卡| 久热精品视频在线观看一区| 国产欧亚日韩视频| 亚洲综合日韩中文字幕v在线| 91精品国产91| 中文字幕在线日韩| 精品视频在线播放色网色视频| 中文字幕亚洲欧美日韩在线不卡| 欧美高清视频免费观看| 久久久免费高清电视剧观看| 欧美一区二区三区艳史| 欧美另类69精品久久久久9999| 成人妇女淫片aaaa视频| 欧美最顶级丰满的aⅴ艳星| 日本国产一区二区三区| 亚洲老头同性xxxxx| 欧美成人中文字幕| 欧美大人香蕉在线| 国产精品亚洲自拍| 国产精品99久久久久久久久| 国产精品丝袜白浆摸在线| 国产精品久久久久福利| 日韩中文理论片| 日韩黄色av网站| 91精品国产免费久久久久久| 热re99久久精品国产66热| 一区二区三区国产在线观看| 日韩在线视频观看正片免费网站| 色综合久久中文字幕综合网小说| 亚洲国产91精品在线观看| 国产91在线播放| 欧美精品中文字幕一区| 欧美日韩爱爱视频| 久久久亚洲国产天美传媒修理工| 久久精品这里热有精品| 国产亚洲美女精品久久久| 成人激情在线观看| 久久久久久69| 91久久在线播放| 国产亚洲一区二区在线| 深夜福利91大全| 亚洲无亚洲人成网站77777| 国产精品极品尤物在线观看| 久久精品国产久精国产思思| 国产在线观看精品一区二区三区| 中文字幕亚洲在线| 国产视频精品xxxx| 久久久精品影院| 国产精品久久999| 91久久久久久久久久久久久| 国产精品电影观看| 2018中文字幕一区二区三区| 国产成人久久精品| 亚洲欧美成人一区二区在线电影| 日韩精品有码在线观看| 精品综合久久久久久97| 狠狠色狠狠色综合日日小说| 日日狠狠久久偷偷四色综合免费| 国产日韩中文在线| 日韩大胆人体377p| 亚洲丝袜av一区| 亚洲精品一区二区网址| 亚洲美女视频网| 日韩欧美成人免费视频| 欧美成年人在线观看| 久久久人成影片一区二区三区观看| 日韩在线观看网址| 久久久久久久久网站| 亚洲精品国产成人| 久久亚洲精品成人| 91久久精品久久国产性色也91| 国产精品成人一区| 久久久91精品国产一区不卡| 亚洲国产精品99久久| 欧美在线观看www| 欧美激情精品久久久久久黑人| 伦理中文字幕亚洲| 日韩av手机在线观看| 国产精品视频大全| 国产91精品黑色丝袜高跟鞋| 在线观看成人黄色| 精品日本高清在线播放| 久久久久久久色| 成年无码av片在线| 欧美日韩亚洲精品一区二区三区| 91亚洲一区精品| 日韩成人中文字幕在线观看| 91欧美精品午夜性色福利在线| 日韩黄色在线免费观看| 尤物yw午夜国产精品视频明星| 久久视频在线播放| 尤物九九久久国产精品的特点| 国产午夜精品理论片a级探花| 91国内揄拍国内精品对白| 成人黄色av播放免费| 日韩精品中文字幕久久臀| 欧美日韩在线观看视频小说| 色偷偷888欧美精品久久久| 精品久久久久久久久久国产| 国产成人亚洲综合青青| 国产精品日韩在线| 色悠悠国产精品| 久久精品中文字幕一区| 精品久久久久久久久久国产| 欧美在线播放视频| 日韩风俗一区 二区| 亚洲毛片在线观看.| 一区二区三区回区在观看免费视频| 青青草99啪国产免费| 92国产精品久久久久首页| 亚洲自拍小视频免费观看| 欧美激情视频网| 在线观看国产欧美| 超碰日本道色综合久久综合| 精品中文字幕乱| 91久久久久久久久久久| 亚洲精品资源美女情侣酒店| 青青青国产精品一区二区| 欧美中文字幕在线播放| 亚洲免费电影一区| 亚洲美女在线观看| 中文字幕国产亚洲2019| 亚洲老板91色精品久久| 国产中文字幕亚洲| 欧美精品久久久久a| 国产精品夜色7777狼人| 成人观看高清在线观看免费| 国产免费久久av| 亚洲精品自拍第一页| 国产精品日韩精品| 91超碰中文字幕久久精品| 久久精品2019中文字幕| 精品久久久久久久久久| 欧美大片欧美激情性色a∨久久| 97色在线视频| 欧美亚洲成人免费| 中文字幕亚洲图片| 国产日韩欧美成人| 国产综合久久久久| 日韩高清电影好看的电视剧电影|