编译原理课程设计报告-pl0语言编译程序扩展.doc

上传人:bao****ty 文档编号:132077428 上传时间:2020-05-12 格式:DOC 页数:9 大小:65.04KB
返回 下载 相关 举报
编译原理课程设计报告-pl0语言编译程序扩展.doc_第1页
第1页 / 共9页
编译原理课程设计报告-pl0语言编译程序扩展.doc_第2页
第2页 / 共9页
编译原理课程设计报告-pl0语言编译程序扩展.doc_第3页
第3页 / 共9页
编译原理课程设计报告-pl0语言编译程序扩展.doc_第4页
第4页 / 共9页
编译原理课程设计报告-pl0语言编译程序扩展.doc_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《编译原理课程设计报告-pl0语言编译程序扩展.doc》由会员分享,可在线阅读,更多相关《编译原理课程设计报告-pl0语言编译程序扩展.doc(9页珍藏版)》请在金锄头文库上搜索。

1、1. 设计任务1、 PL/0语言解读2、 PL/0语言增加C语言形式的/*/的注释3、 给PL/0语言增加输入输出语言4、 给PL/0语言增加布尔类型,并且布尔类型的表达式按短路方式计算。2. 设计思想和实现方法1、PL/0语言增加C语言形式的/*/的注释在getch函数中,如果找到/*字符串,则将ll - 2的值保存到lbuffer中,将szFlag标记,继续通过getc函数从文件中读取字符,并赋值到line数组中(这里的字符都是注释),直到我们从文件中读取到*/字符串,我们将szFlag标记置回原值,并将lbuffer中的值赋给ll,然后我们找到的n,则退出这次while循环取值,这样就在

2、PL/0语言中实现了C语言形式的/*/的注释。实现代码:2、给PL/0语言增加输入输出语言首先在word数组和wsym数组中添加read,write关键字和readsym,writesym宏,然后再statement函数中添加read和write关键字的处理if-else子分支。在处理处理read关键字函数中,首先同getsym函数取得下个字符的sym,如果是lparen(代表左括号),如果不是,则输出响应的错误代码,在通过getsym函数取得下个标记符,并判断类型,如果sym是ident(变量),找到变量在table中的位置,判断table中的类型,生成代码,然后getsym继续去标识符。处

3、理write函数的方式跟read函数相似。3、给PL/0语言增加布尔类型,并且布尔类型的表达式按短路方式计算。首先爱word数组中和wsym数组中添加true,false,boolean关键字和truesym,falsesym,booleansym宏,并在factor函数中添加处理boolean的if-else子分支,在分支中通过判断值得内容,并生成相应的代码。3. 程序说明1、 添加注释while(!feof(infile)/ & (ch=getc(infile)!=n) ch=getc(infile);if (szFlag = y)if (ch =n)break;printf(%c, ch

4、);ll = ll + 1;linell = ch;if (ll = 1 )& (linell - 1 = /) & linell = *)lbuffer = ll - 2;szFlag = n;if (ll = 1) & (linell - 1 = *) & (linell = /)ll = lbuffer;szFlag = y; 2、 添加输入输出else if (sym=writesym)getsym();if(sym=lparen)dogetsym();if (sym=ident)i=position(id);if(i=0)error(11);else if(tablei.kind!=

5、variable)/ assignment to non-variableerror(12); i=0;gen(opr, 0, 15);getsym();elseerror(8);while(sym = comma);if (sym!=rparen)error(22);getsym();else if(sym=readsym)getsym();if (sym=lparen)do getsym();if (sym=ident)i=position(id);if(i=0)error(11);else if(tablei.kind!=variable)/ assignment to non-vari

6、ableerror(12); i=0;gen(opr, 0, 14);if (i != 0)gen(sto,lev-tablei.level,tablei.addr);getsym();elseerror(8); while (sym=comma);if (sym=rparen)getsym();elseerror(22);3、 添加布尔类型else if (sym=truesym | sym=falsesym)if (sym=truesym)gen(lit,0, 0);elsegen(lit,0, 1);getsym();4. 程序运行结果5. 测试报告在pl0语言中添加了一个多行注释,用/

7、*/。使用输入输出语句,read和write在代码解释执行时输入输出。定义boolean类型变量,并赋值。6. 存在问题及分析在interpret函数的case 15中,输出后,t如果自减一次,那么程序会陷入死循环,但是还没有找到解决方法,我想可能是在某次case语句中多自增了一次。7. 总结在刚拿到课设资料时,都无从下手,后来老师说先解读pl0的代码,然后看着一大串代码,感觉很头痛,大体看了一会,发现还真没什么捷径可走,那就Debug跟踪代码一步步走吧,后来发了一天时间才把代码看完,才理解了个大致,但是我觉得我应该开始动手试试添加一些代码,把第一个添加C语言形式注释试试,开始我想了我自己觉得

8、挺巧妙的办法去处理,后来经同学一点拨,发现自己的方法实在是笨到家了,转换方法后只用半个多小时就搞定了注释。然后我开始输入输出,做到这里的时候,我才发现我其实并没有把代码看懂,而已犯一个很愚蠢的错误,那就是把读代码过程,编译过程,代码解释执行过程弄混淆了,并没有在这个程序上真正理解这三者的关系,也是同过输入输出的完成,才得以把代码读懂,所以后面做布尔型就没发多少时间了。参考文献1 李建中 姜守旭,编译原理,机械工业出版社 附录:PL/0源代码解读词法分析子程序分析: 词法分析子程序名为getsym,功能是通过getch函数从源程序中读出一个字符,讲它们分类放入,a数组,line数组, num中,

9、字符变量放入ch中,语法分析器需要单词时,直接从这三个变量中获得。getch读出的字符在getsym中还需要进行拼合等,讲数字的字符转换成数字。词法分析器的分析过程:调用getsym函数,函数从getch函数中获得一个字符,如果这个字符不是空格和制表符,那么将停止从getch中取得字符,如果不是,将继续从getch中去字符,直到取得的字符不是上述两者,取出字符并判断是字母、数字、还是其他字符,如果是字母,将继续从getch中取得字符,直到取出的字符不是字母为止,将这些取出来的字母放入a数组中,并将a数组中其他为用的位置置为空格,然后再work数组中比对字符串,如果找到,将在wsym数组相应的宏

10、赋值给sym,如果没有找到,将sym赋值为ident,表示是变量。如果取出来的是数字,那么继续从getch中取字符,是数字则进行ASCII转换,并将数字组合,将拼合后的数字保存到num中,将sym赋值为number,如果是其它字符,则将sym赋值为响应wsym数组中的宏。如果找到不合法的字符,则将sym赋值为nul。语法分析子程序分析:语法分析子程序采用了自顶向下的递归子程序法,语法分析同时也根据程序的语义生成相应三元代码,并提供了出错处理的机制。语法分析主要由分程序分析过程(block)、常量定义分析过程(constdeclaration)、变量定义分析过程(vardeclaration)、

11、语句分析过程(statement)、表达式处理过程(expression)、项处理过程(term)、因子处理过程(factor)和条件处理过程(condition)构成。这些过程在结构上构成一个嵌套的层次结构。除此之外,还有出错报告过程(error)、代码生成过程(gen)、测试单词合法性及出错恢复过程(test)、登录名字表过程(enter)、查询名字表函数(position)。由PL/0的语法图可知:一个完整的PL/0程序是由分程序和句号构成的。因此,本编译程序在运行的时候,通过主程序中调用分程序处理过程block来分析分程序部分(分程序分析过程中还可能会递归调用block过程),然后,判

12、断最后读入的符号是否为句号。如果是句号且分程序分析中未出错,则是一个合法的PL/0程序,可以运行生成的代码,否则就说明源PL/0程序是不合法的,输出出错提示即可。下面按各语法单元分析PL/0编译程序的运行机制。常量定义过程:通过循环,反复获得标识符和对应的值,存入符号表。符号表中记录下标识符的名字和它对应的值。变量定义过程:与常量定义类似,通过循环,反复获得标识符,存入符号表。符号表中记录下标识符的名字、它所在的层及它在所在层中的偏移地址。赋值语句的处理:首先获取赋值号左边的标识符,从符号表中找到它的信息,并确认这个标识符确为变量名。然后通过调用表达式处理过程算得赋值号右部的表达式的值并生成相

13、应的指令保证这个值放在运行期的数据栈顶。最后通过前面查到的左部变量的位置信息,生成相应的STO指令,把栈顶值存入指定的变量的空间,实现了赋值操作。返回函数值也是用赋值语句进行返回值的储存。对函数与过程调用的处理:首先判断读入的标识符属性为procedure,从符号表中找到此标识符,获得其所在层次和偏移地址。然后生成相应的cal指令。至于调用子过程所需的保护现场等工作是由类PCODE解释程序在解释执行cal指令时自动完成的。如果此标识符不在第0层而且是该层函数的函数名则作为返回值返回。read语句的处理:确定read语句语法合理的前提下(否则报错),由变量的类型生成相应的指令:对于整型,第一条是14号操作的opr指令,实现从标准输入设备上读一个整数值,放在数据栈顶。如果读入是实数就报错,第二条是sto指令,把栈顶的值存入read语句括号中的变量所在的单元。write语句的处理:在语法正确的前提下,生成指令:通过循环调用表达式处理过程分析write语句括号中的每一个表达式,生成相应指令保证把表达式的值算

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号