、打开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 /home

Administrator@2012-20121224HD /home

$ cd flexlinux

Administrator@2012-20121224HD /home/flexlinux

$ flex test1.l

Administrator@2012-20121224HD /home/flexlinux

$

可以看到目录中的lex.yy.c就是刚生成的C源码,可分析词法。

Administrator@2012-20121224HD /home/flexlinux

$ ls

lex.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.l

Administrator@2012-20121224HD /home/flexlinux

$ gcc lex.yy.c -lfl

3、运行

Administrator@2012-20121224HD /home/flexlinux

$ ./a

  • 12 66

260

258=12

258=66

264

Administrator@2012-20121224HD /home/flexlinux

$ ./a

/ 56 2 + |32

262

258=56

258=2

259

263

258=32

264

Administrator@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.y
t$ ls

test2.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^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)

我们接着完善这个计算器程序,让算式能显示出来,修改calculator.l

我们接着完善这个计算器程序,让算式能显示出来,修改calculator.l

通过加入printf语句,打印词法分析器解析到的字符。比如 :

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

\n {return EOL;}

[ \t] /blank/

. /invalid char/

%%

然后编译执行。

root@myhaspl:~/test/4# make

bison -d calculator.y

flex calculator.l

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

root@myhaspl:~/test/4# ./a.out

12+66

12+66=78

^C

root@myhaspl:~/test/4# ./a.out mycpt1.cpt mycpt2.cpt

12*66/(10-5)=158

77/(10+1)-15=-8

接下来加上读取的行号,将结果的显示更加人性化

flex文件要改:

\n {printf(“line:M”,yylineno);yylineno++;return EOL;}

然后,bison文件也改:

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

最后 ,编译运行测试一下。

root@myhaspl:~/test/4# make
bison -d calculator.y
flex calculator.l
gcc calculator.tab.c lex.yy.c -lfl
root@myhaspl:~/test/4# ./a.out mycpt1.cpt mycpt2.cpt
1266/(10-5)<line: 1>the result is:158
12/22-8<line: 2>the result is:-8
77(6-2)<line: 3>the result is:308
77/(10+1)-15<line: 4>the result is:-8
root@myhaspl:~/test/4#

C指针原理(10)-编译原理-小型计算器实现相关推荐

  1. 计算机编译原理ppt,编译原理课件.ppt

    文档介绍: 高级语言 汇编语言 SOURCE PROGRAM Assemble PROGRAM ?翻译程序? TRANSLATER 为什么要学****编译原理 程序设计语言是计算机软件专业的重要核心 ...

  2. 深入理解计算机原理与编译原理,【底层原理:深入理解计算机系统】#1 一切从'hello world'说起 (一)...

    计算机系统是由硬件和系统软件组成的,他们共同工作来运行应用程序.虽然系统的具体实现方式随着时间不断的在变化,但是系统的内在概念却没有改变的. 所有的计算机硬件和软件有着相似的结构和功能.这个系列专题便 ...

  3. 【编译原理】编译原理系统学习与实践系列文章汇总目录(持续更新中)

    本文属于「编译原理」系列文章的汇总目录,这一系列正式开始于2021/10/22,着重于「编译原理的学习与实践」.众所周知,编译原理难学难精,因此本系列将至少持续到作者本人「精通编译原理」为止(笑).由 ...

  4. python编译原理_编译原理实战课 带你吃透编译技术核心概念与算法

    编译原理实战课,我们到底要学些什么? 在这门课程里,宫老师精选出了Java.Java JIT.Python.JavaScript.Julia.Go.MySQL这7种真实编程语言的编译器,带你阅读它们的 ...

  5. [编译原理]吉林大学编译原理csf课件下载(1-64) 主讲:康辉 (附破解补丁)

    下载地址: http://dec-vod.jlu.net.cn/csmedia/计算机科学与技术专业(高起本)/编译原理/第01讲.csf?tod_key=lvqdt1QZ8OldtWBRjvNxUY ...

  6. linux系统的编译原理,GCC编译原理_Linux编程_Linux公社-Linux系统门户网站

    一.编译过程 使用gcc编译程序时,编译过程可被细分为四个阶段: (1)预处理 (2)编译 (3)汇编 (4)链接 例如hello.c程序 hello.c: #include int main(voi ...

  7. 程序设计语言编译原理_编译原理学习笔记(二):高级程序设计语言

    高级程序设计语言 一.语言概述 1.1 语法 v.s. 语义 程序本质上是一定字符集上的字符串 语法:一组规则,用它可以形成和产生一个合式(well-formed)的程序 定义了程序的形式结构 定义语 ...

  8. 【编译原理】符号表的实现C语言

    最近在学习编译原理这门课.实验课老师让我们完成简易的符号表.内容是读出源程序中的标识符,并在符号表中进行查找,若存在则输出该标识符及其编号和位置.否则将其填入符号表,并分配编号,确定位置,输出标识符表 ...

  9. micropython编译原理_C语言嵌入式Linux高级编程第9期:CPU和操作系统入门视频课程...

    嵌入式开发是一门交叉学科. 它要求我们的嵌入式工程师,不仅学习C语言.汇编.软件工程等软件层面的知识技能,还要求对CPU内部工作机制.计算机系统架构.操作系统原理.编译器等都有一个全局的认识和把握. ...

最新文章

  1. 深度学习 Caffe 初始化流程理解(数据流建立)
  2. 循环神经网络——裁剪梯度(应对梯度爆炸)
  3. [转]PDB——Python调试利器详解
  4. 【hadoop各个节点的意思】
  5. traceroute tracert
  6. 8086可以用c语言编程吗,[求助]如何将C程序反汇编成8086汇编程序
  7. DSP,从入门到入土
  8. 达梦数据库工程师培训实战教程(主备集群、读写分离、共享集群)
  9. 百度api翻译html,帮助文档首页
  10. 邮箱smtp服务-QQ邮箱163邮箱(保姆级图文)【杂记】
  11. Gos ——操作键盘
  12. html5如何实现无序排列,无序列表让li横排
  13. 考研复试—软件工程(一)
  14. 手机点餐系统 电脑服务器,手机点餐系统_手机点餐软件大全【最新】-太平洋电脑网...
  15. python画彩色立体柱状图
  16. php 打开文件方式
  17. 服务端渲染SSR与客户端渲染
  18. SD卡误删了照片怎么恢复?照片恢复教程分享
  19. ORACLE和MYSQL的九大区别
  20. 如何查看路由器的mac和计算机的mac

热门文章

  1. CXF 入门:创建一个基于SOAPHeader的安全验证(CXF拦截器使用)
  2. 通过日志恢复MS SQL数据案例
  3. Android自定义顶部栏及侧滑菜单和fragment+viewpag滑动切换的实现
  4. 设置宿舍路由器为多账号登录的方法
  5. cms-幻灯片的实现
  6. Mysql导出函数、存储过程
  7. psd页面切割成html技巧总结
  8. 字节 字符 utf-8 unicode 以及提交表单验证字符长度 .......
  9. POJ 3750 小孩报数问题
  10. 熟悉Python Interpreter解释器