编译原理课程设计基于表达式计算器_第1页
编译原理课程设计基于表达式计算器_第2页
编译原理课程设计基于表达式计算器_第3页
编译原理课程设计基于表达式计算器_第4页
编译原理课程设计基于表达式计算器_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、*工程学院编译原理课程设计课程设计题目 :表达式计算器姓 名 :*院(系) :计算机科学与工程学院 专业班级 :计算机科学与技术084班学 号 :200810214415指导教师 :*设计日期 :2010 年 12 月26日25目录表达式计算器11. 需求分析11.1.总述12. 概要设计12.1.开发环境12.2.总体设计22.2.1.模块结构图22.2.2.模块说明22.2.3.界面设计33. 详细设计43.1.词法分析模块:43.1.1.词法分析简介:43.1.2.词法分析模块的设计及实现43.2.语法分析模块113.2.1.语法分析简介113.2.2.语法分析器的实现113.3文法分析

2、19.1文法分析器生成工具yacc194.测试分析215课程总结246.参考文献25表达式计算器1. 需求分析1.1. 总述计算器是我们经常使用的小工具,它能帮我们对数据进行有效的运算,如通过四则运算能实现对输入数据的加减乘除。本课程设计结合了编译原理中的词法分析、语法分析及语义分析方法,给出了表达式计算器的系统设计过程,并在vc+6.0中使用面向对象的技术实现了计算器。1.2. 功能要求计算器的功能要求如下:可以支持加(+)、减(-)、乘(*)、除(/)运算,如3+4-5*2/2;支持括号运算,如(4+5)*5/8;判断用户输入的表达式是否正确,如3+-*3是一个错误的表达式,在计算时将提示

3、错误;用户输入表达式后,按下等号按钮执行计算。2. 概要设计2.1. 开发环境开发平台:windows xp + vc+6.0开发语言:c+2.2. 总体设计程序在vc+6.0中使用面向对象的技术实现了计算器。模块设计2.2.1. 模块结构图词法分析模块语法分析模块计算模块需要一个单词识别一个单词得到一个语法短语计算结果图1. 程序模块图2.2.2. 模块说明计算器分为三个功能模块:(1)词法分析模块:对输入的表达式从左到右扫描,识别出表达式中的单词(包括运算符和运算数),若单词的构成不符合词法规则(运算符和运算数的构成规则),则报错并停止计算。(2)语法分析模块:将单词分解为各类语法短语,若

4、存在不符合规则的语法短语,则报错并停止计算。(3)计算模块:对符合语法规则的语法短语进行计算,若计算不能进行,则报错并停止计算。计算器的三个功能模块中语法分析模块起到了核心作用,如图1所示。2.2.3. 界面设计图2表达式计算器3. 详细设计3.1. 词法分析模块:其词法分析器调用接口为lex()3.1.1. 词法分析简介:词法分析是编译原理程序的第一阶段,其任务是:从左至右逐个字符地对源程序扫描和分解,识别出一个个的单词(如标志符、常量、运算符、界符等),并判断单词的构成是否符合词法规则。可以使用上下文无关文法来描述词法规则,使用有限自动机来识别单词。3.1.2. 词法分析模块的设计及实现l

5、ex工具的基本使用方法和工作原理:lex工具是一种词法分析程序生成器,它可以根据词法规则说明书的要求来生成单词识别程序,由该程序识别出输入文本中的各个单词。 一般可以分为。其中规则部分是必须的,定义和用户子程序部分是任选的。(1)定义部分 定义部分起始于 % 符号,终止于 % 符号,其间可以是包括include语句、声明语句在内的c语句。这部分跟普通c程序开头没什么区别。% #include stdio.hint linenum;%(2) 规则部分 规则部分起始于%符号,终止于%符号,其间则是词法规则。词法规则由模式和动作两部分组成。模式部分可以由任意的正则表达式组成,动作部分是由c语言语句组

6、成,这些语句用来对所匹配的模式进行相应处理。需要注意的是,lex将识别出来的单词存放在yytext字符数据中,因此该数组的内容就代表了所识别出来的单词的内容。类似yytext这些预定义的变量函数会随着后面内容展开一一介绍。动作部分如果有多行执行语句,也可以用括起来。%title showtitle();n linenum+;0-9+ printf(int : %sn,yytext);0-9*.0-9+ printf(float : %sn,yytext);a-za-za-za-z0-9* printf(var : %sn,yytext);+-*/% printf(op : %sn,yytext

7、);. printf(unknown : %cn,yytext0);%a.规则部分的正则表达式规则部分是lex描述文件中最为复杂的一部分,下面列出一些模式部分的正则表达式字符含义:a-z, 0-9, a-z 构成模式部分的字符和数字。- 指定范围。例如:a-z 指从 a 到 z 之间的所有字符。 转义元字符。用来覆盖字符在此表达式中定义的特殊意义, 只取字符的本身。 表示一个字符集合。匹配括号内的任意字符。如果第一个字 符是那么它表示否定模式。例如: abc 匹配 a, b, 和c 的任何一个。 表示否定。* 匹配0个或者多个上述模式。+ 匹配1个或者多个上述模式。? 匹配0个或1个上述模式。

8、$ 作为模式的最后一个字符时匹配一行的结尾。 表示一个模式可能出现的次数。 例如: a1,3 表示 a 可 能出现1次或3次。a-z5 表示长度为5的,由a-z组成的 字符。此外,还可以表示预定义的变量。 . 匹配任意字符,除了 n。( ) 将一系列常规表达式分组。如:letter(letter|digit)* | 表达式间的逻辑或。一些符号 字符的字面含义。元字符具有。如:* 相当于 *。/ 向前匹配。如果在匹配的模式中的/后跟有后续表达式, 只匹配模版中/前面的部分。如:模式为 abc/d 输入 abcd, 时abc会匹配abc/d,而d会匹配相应的模式。输入abce的话, abce就不会

9、去匹配abc/d。b.规则部分的优先级规则部分具有优先级的概念,先举个简单的例子:%#include stdio.h%n ;a printf(onen);aa printf(twon);aaaa printf(threen);%此时,如果输入内容:rootlocalhost liweitest# cat file1.txtaaaaaaarootlocalhost liweitest# ./parser file1.txtthreetwoonelex分析词法时,是逐个字符进行读取,自上而下进行规则匹配的,读取到第一个a字符时,遍历后发现三个规则皆匹配成功,lex会继续分析下去,读至第五个字符时,

10、发现aaaa只有一个规则可用,即按行为进行处理,以此类推。可见lex会选择最长的字符匹配规则。如果将规则aaaa printf(threen);改为aaaaa printf(threen);./parser e+t2,$e,$e,$minus,$t,0,3,$e,$t,0,0,0,4,$t,$t,$mul,$f,0,5,$t,$t,$div,$f,0,6,$t,$f,0,0,0,7,$f,$lpar,$e,$rpar,0,8,$f,$int,0,0,0,0,0,0;/action表int action168 = / i,+,-,*,/,(,),# s+5,blank,blank,blank,b

11、lank,s+4,blank,blank,blank,s+6,s+7,blank,blank,blank,blank,acc,blank,r+3,r+3,s+8,s+9,blank,r+3,r+3,blank,r+6,r+6,r+6,r+6,blank,r+6,r+6,s+5,blank,blank,blank,blank,s+4,blank,blank,blank,r+8,r+8,r+8,r+8,blank,r+8,r+8,s+5,blank,blank,blank,blank,s+4,blank,blank,s+5,blank,blank,blank,blank,s+4,blank,bla

12、nk,s+5,blank,blank,blank,blank,s+4,blank,blank,s+5,blank,blank,blank,blank,s+4,blank,blank,blank,s+6,s+7,blank,blank,blank,s+15,blank,blank,r+1,r+1,s+8,s+9,blank,r+1,r+1,blank,r+2,r+2,s+8,s+9,blank,r+2,r+2,blank,r+4,r+4,r+4,r+4,blank,r+4,r+4,blank,r+5,r+5,r+5,r+5,blank,r+5,r+5,blank,r+7,r+7,r+7,r+7,

13、blank,r+7,r+7;/goto表int go163 = /e,t,f1,2,3,blank,blank,blank,blank,blank,blank,blank,blank,blank,10,2,3,blank,blank,blank,blank,11,3,blank,12,3,blank,blank,13,blank,blank,14,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank,blank;int slr1()/slr1分析

14、表入口int token;/输入符号int s,e;/状态栈顶、符号栈顶元素int *pr,pl;/产生式右部、左部int act;/动作/分析栈rstack slrstack(256);slrstack.push(0, $end);token = lex();while(true)if (token = $unknown)procerror();return fail;elseact = actionslrstack.top(s,e)token-1;if (act = blank)procerror();return fail;else if (act = acc)printf(接受!);r

15、eturn success;else if (act , );while(*pr != 0)if (*pr = 100)printf(%s , vn*);elseprintf(%s , vt*);slrstack.pop(s, e);pr+;printf(n);s = goslrstack.top(s,e)pl-100;slrstack.push(s, pl);/if (act = blank)/if (token = $unknown)/while3.3 文法分析.1 文法分析器生成工具yacc简单来说,yacc(yet an

16、other compiler-compiler)就是编译器的编译器。yacc是一个通用的工具,能够根据用户指定的规则,生成一个词法分析程序。yacc能识别lalr(1)且无歧义的文法,它的输入是词法分析器的输出。我们知道,生成词法分析器是lex分内的事,因此lex和yacc常常珠联璧合。先让我们看一下yacc文件的格式。和前面介绍的lex的格式类似:declarations%rules%programs声明%规则%其它程序其中声明段声明一些符号常量,可以为空。同lex一样,声明段中可以有出现在目标c程序中的代码,放在%中;还有一些yacc关键词可以指示出token的结合顺序:left左结合%r

17、ight右结合%nonassoc不结合%token声明token俗话说“没有规矩,不成方圆”。 规则段描述规则,自然是重中之重了。规则段的结构是如下,a : body ;a表示非终结符名,body表示产生式和动作。产生式包括非终结符和终结符,终结符用引用。一些转义字符,比如r,n等,和c里面的表示是一样的。动作(action)则是在输入被当前规则识别出来时而执行的。动作实际上就是c的代码,写在 中。为了沟通词法分析器和动作,yacc引入了形式变量,以$开头。如果希望获得词法分析器和前面的动作返回的值,我们可以使用$1,$2,。$i表示一条规则右侧第i个单元的值。比如有这样的一条规则,a : b

18、 c d ;c的返回值为$2,d为$3。依此类推。程序段放一些其它的程序,也可以省略,连%都可以不要。连接时需要指定连接库,gcc的参数为-ly。4. .测试分析功能测试:图2进行加法运算图3表达式进行减法运算图4表达式进行乘法运算图5表达式进行除法运算图6表达式进行四则运算图7表达式进行括号优先运算5 课程总结本课程设计基于程序设计语言的编译原理,给出了表达式计算器的设计过程,并在vc+6.0下将其进行了实现。其中由于时间问题,在词法分析与语义分析中分别运用了lex和yacc工具。所以本课程设计的核心内容在于语法分析阶段,语法分析采用自上而下分析法,确定相关的文法产生式,确定first和follow集合,对产生式进行移近和规约,构造action和goto表,最后进行代码的编写。通过本

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论