编译原理课程实验报告示例(共27页).doc
《编译原理课程实验报告示例(共27页).doc》由会员分享,可在线阅读,更多相关《编译原理课程实验报告示例(共27页).doc(27页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上1完成日期:2007-6-20指导老师:蒋宗礼 张悦编译原理实验报告 张悦专心-专注-专业2词法的正规式描述标识符:|(|)*(|_|.) (|)*十 进 制 数 : (0|(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*)( |.)(0|1|2|3|4|5|6|7|8|9)五系统实现(一)词法分析器的实现四系统设计完成整个系统,实现本个实验的要求,需要两个比较大的模块:词法分析器 和语法分析器。词法分析器的功能是将输入的程序串分解成一个一个独立的单词,并且记录 下每个单词的类型以及数值。这里词法分析器的实现有两种方法:调用一次词法
2、分析器,返回一个词的类型以及数值,以此类推;还有一种方法是条用一次词法 分析器将程序串的所有单词都分解出来并保存到一个地方(比如线形表)以便将 来使用。我采用的是前者,因为这样只需要对整个程序访问一遍语法分析器的功能是将已经分解好的单词按照一定的规范(产生式)组合起 来,由此来确定输入程序的意思。我的设计是“语法分析器调用词法分析器”, 当语法分析其分析进行不下去的时候调用词法分析器获取一个单词,继续进行分 析。而语义功能是镶嵌在语法分析其当中的,当语法分析器分析出用什么产生式 的时候作相应的语义处理。3 编写测试程序,反复调用函数scan( ),输出单词种别和属性。4 改写文法,构造语法分析
3、程序,要求按照最左派生的顺序输出派生的产 生式序列;5 改写语法分析程序,构造三地址代码生成程序。6 处理的源程序存放在文件中,它可以包含多个语句;从键盘读入数据,分析出一个单词。返回单词种别(用整数表示), 返回单词属性(不同的属性可以放在不同的全局变量中)。1)2)3)三. 实验要求1 编制正规式以及正规文法,画出状态图;2 根据状态图,设计词法分析函数int scan( ),完成以下功能:二. 实验内容1编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法 分析程序。2用二维预约分析表,编制一个能够进行语法分析并生成派生的产生式序 列的编译程序。3用递归子程序法,编制一个能够进
4、行语法分析并生成三地址代码的微型 编译程序。一. 实验目的基本掌握计算机语言的词法分析程序的开发方法。以及掌握计算机语言的语 法分析程序设计与属性文法应用的实现方法。锻炼自己的编程能力和逻辑思维能 力,体会计算机编译器的奥妙之处 张悦3、状态图:-a|b|c|d|e|f|g|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z-0|1|2|3|4|5|6|7|8|9- (|)|- (|_|.)- (|.)- (0|1|2|3|4|5|6|7)|- (0|1|2|3|4|5|
5、6|7|8|9|a|b|c|d|e|f) |将状态合起来,得:(0)-(1)|0(4)|(12)|(17) (1)-(1)|. (2)(2)-(3) (3)-(3)(4)-.(2)|(5)|0(13)|x(8)|X(8) (5)-(5)|.(6)(6)-(7) (7)-(7)(8)-(9)|(9)|0(14) (9)-(9)|(9)|.(10) (10)-(11)|(11) (11)-(11)|(11)(12)-(12)|(12)|(12)|.(15)|_(15) (13)-.(6)(14)-.(10)(15)-(16)|(16)|(16) (16)-(16)|(16)|(16)母字、改变后的
6、正规文法- - 0 - 0x -+| - |* |/ | |= |( | ) |;-if| then| else |while |do(0|1|2|3|4|5|6|7|8|9)*八进制数:0(0|(1|2|3|4|5|6|7) (0|1|2|3|4|5|6|7)*) (|.)(0|1|2|3|4|5|6|7) (0|1|2|3|4|5|6|7)*十六进制数:0x(0(|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f) (0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*) (|.)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f) (0|1|2|3|
7、4|5|6|7|8|9|a|b|c|d|e|f)*运算符和分隔符:+ - * / = ( ) ;关键字:if then else while do 张悦09091.2309070719.567.07170040.13x|X0f0f字母81f9.100f1112分隔符014.|_字母或数字1516字母或数字17字母或数字4strcpy(node-type,#);strcpy(node-value,_);return false; /表示文件结束if(temp = #)读取一个字符到 temp;node = new CNode;while(1)/返回的节点/当前状态号int state = 0;i
8、nt si = 0; /对于控制 s 的下标/保留字符串char s100;、算法(伪码):bool MyScan(FILE* fp,CNode* &node)char temp; /当前读取的字符、数据结构:char* arrBao5 = if,then,else,do,while;/保留字表typedef structchar typeTYPE_MAX;char valueVALUE_MAX;CNode;/词法分析的节点,保留分析出的 token 的种类和值 张悦5;添 加 当 前 字 符state=14;state=9;添 加 当 前 字 符if(temp 为十六进制数)continue
9、;if(temp 为 0)else 出错处理; return false;case 8: /状态 8return true;保存为 INT8;if(temp 为分隔符)添加当前字符; continue;添加当前字符; continue;else 出错处理; return false;case 6: /状态 6if(temp 为 07) state=7;else 出错处理; return false;case 7: /状态 7if(temp 为 07) state=7;return true;保存为 INT8;if(temp 为分隔符)if(temp 为 07) state=5;state=6;
10、添加当前字符; continue;添加当前字符; continue;if(temp 为小数点)else 出错处理; return false;case 5: /状态 5return true;保存为 INT10;state=8;if(temp 为 x 或 X)if(temp 为分隔符)state=5;state=13;if(temp 为 17)if(temp 为 0)state=2;添加当前字符; continue;添加当前字符; continue; 添加当前字符; continue; 添加当前字符; continue;if(temp 为小数点)else 出错处理; return false;
11、case 4: /状态 4return true;保存为 REAL10;if(temp 为分隔符)添加当前字符; continue;添加当前字符; continue;else 出错处理; return false;case 2: /状态 2if(temp 为数字) state=3;else 出错处理; return false;case 3: /状态 3if(temp 为数字) state=3;保存为 INT10; return true;state=2;if(temp 为小数点)if(temp 为分隔符)添加当前字符; continue;添加当前字符; continue;else 出错处理;
12、 return false;case 1: /状态 1if(temp 为数字) state=4;和制表符/忽略多个空格和回车if(temp 为空格或回车或 tab) continue;return true;保存相应的分隔符到 node;state=4;state=1;state=12;添加当前字符; continue;添加当前字符; continue;添加当前字符; continue;switch(state)case 0: /状态 0 if(temp 为 0) if(temp 为 1 到 9) if(temp 为字母) if(temp 为分隔符) 张悦6添加当前字符 ;state=16;i
13、f(temp 为数字或者字母)case 16:/状态 16else 出错处理; return false;return true;else 保存为 IDN;if(temp 为分隔符)if(为保留字) 保存为保留字; return true;continue;state=16;添加当前字符 ;if(temp 为数字或者字母)/状态 15case 15:else 出错处理; return false;保存为 INT16; return true;if(temp 为分隔符)添加当前字符; continue;if(temp 为.) state=10;case 14:/状态 14else 出错处理; r
14、eturn false;return true;保存为 INT8;添加当前字符; continue;if(temp 为.) state=6;if(temp 为分隔符)case 13:/状态 13else 出错处理; return false;return true;else 保存为 IDN;state=15;添加当前字符 ;if(temp 为_或者.)continue;if(temp 为分隔符)if(为保留字) 保存为保留字; return true;continue;state=12;添加当前字符 ;if(temp 为数字或者字母)/状态 12case 12:else 出错处理; retur
15、n false;return true;保存为 INT16;if(temp 为分隔符)continue;符字前当添 加if(temp 为十六进制数)state=11;/状态 11case 11:;符字前当添 加if(temp 为十六进制数)state=11;continue;else 出错处理; return false;case 10:/状态 10else 出错处理; return false;return true;保存为 INT16;符字前当添 加state=10;if(temp 为小数点)continue;if(temp 为分隔符);符字前当添 加continue;else 出错处理;
16、 return false;case 9: /状态 9if(temp 为十六进制数)state=9;continue; 张悦7注:没有按照书上的程序框架进行编程,而且个人认为这种程序框架比书上的好:1,模块化比较强。2,更贴近状态图,可读性高,书上的程序是以“一个终极符得导出”作为 思路,而我是以“一个状态的变化”作为思路。所以只要有了正确的状 态图,不需要梳理复杂的状态的意义,只需要机械的按照每个状态的动 作编程即可。某种意义上来说这样可以让计算机自己生成程序(模块化 非常强)3,容易修改,比如在状态图上新增加或删除一个状态或者一条线,只需要 在相应的状态中作适当的修改即可,无须作大的改动。
17、比如开始我没有 注意标识符的附加要求,知道了之后整个程序已经编写完了,再改动的 时候只是在状态图上添加了两个状态,相应修改了一点点程序,就成功 了。因为各个状态的操作之间基本上没有交集,相对独立。个人比较崇尚这种编程风格。不过这种方式对状态图的正确性要求比较高。 注:算法中的分隔符+ - * / = ( )和空格还有回车。注:此法分析器 MyScan 返回值为 boolean,表示程序是否结束(在文件到最后 用#表示输入结束),而在错误的 token 中,CNode 指针会置为空,以此来表 示该处单词有错误。注:关于出错处理。我的出错处理仅仅是显示 ERROR+出错的状态号,相当于 给出一个出
18、错类型号,而没有实现续编译功能。因为在词法中的续编译功能 没有必要,原因如下:如果一个 token 不符合规范,那么在语法分析器中会fclose(fp); getchar(); return 0;else printf(n);printf(%st%sn,node-type,node-value);/分析成功/主函数源程序int main() FILE* fp; fp=fopen(code1.txt,r); CNode* node; while(MyScan(fp,node) if(node != NULL)else 出错处理; return false;/switch/whilereturn
19、true;else 保存为 IDN;if(temp 为分隔符)if(为保留字) 保存为保留字; return true;continue; 张悦8、思考题1 词法分析能否用空格来区分单词 不能光用空格来区分,比如 3+2,就要用+来分隔出 3、实验过程中遇到的问题我的程序的结构和状态转移图联系非常紧密,所以在最后编程的时候基本上 没有遇到什么困难,主要的问题还是集中在画状态图上。由于对十六进制和八进制数的结构定义不是非常清楚,在读正规式的时候有 了一些偏差,以至于我的状态转移图画了好几遍。而在转移图正确之后,编程过 程就没有什么太大困难了。、测试测试用例:0 92+data 0x3f 00 w
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 课程 实验 报告 示例 27
限制150内