1、在描述这个过程中,要说清楚每个功能有哪个子程序的哪条语句来完成,说清楚语句和参数的含义和功能。四、实验结果及分析(一)程序标注levmax = 3; max depth of block nesting 最大允许的块嵌套层数 语法分析过程block 参数:lev:这一次语法分析所在的层次 tx:符号表指针 fsys:用于出错恢复的单词集合 procedure block(lev, tx: integer; fsys: symset);var dx: data allocation index 数据段内存分配指针,指向下一个被分配空间在数据段中的偏移位置 tx0: initial table i
2、ndex 记录本层开始时符号表位置 cx0: initial code index 记录本层开始时代码段分配位置 登陆符号表过程enter procedure enter(k: object1); begin enter object into table 参数:k:欲登陆到符号表的符号类型 tx := tx + 1; 符号表指针指向一个新的空位 with tabletx do 开始登录 begin name := id; name是符号的名字,对于标识符,这里就是标识符的名字 kind := k; 符号类型,可能是常量、变量或过程名 case k of 根据不同的类型进行不同的操作 cons
3、tant: 如果是常量名 if num amax then 在常量的数值大于允许的最大值的情况下 error(31); 抛出31号错误 num := 0; 实际登陆的数字以0代替 end; val := num 如是合法的数值,就登陆到符号表 variable: 如果是变量名 level := lev; 记下它所属的层次号 adr := dx; 记下它在当前层中的偏移量 dx := dx+1; 偏移量自增一,为下一次做好准备 procedur: 如果要登陆的是过程名 = lev 记录下这个过程所在层次 EndEnd end enter ; 登录符号过程没有考虑到重复的定义的问题。如果出现重复定
4、义,则以最后一次的定义为准。 在符号表中查找指定符号所在位置的函数position 参数:id:要找的符号 返回值:要找的符号在符号表中的位置,如果找不到就返回0 function position (id: alfa): var i: begin find identifier in table table0.name : 先把id放入符号表0号位置 i := tx; 从符号表中当前位置也即最后一个符号开始找 while tablei.name id do 如果当前的符号与要找的不一致 = i 1; 找前面一个 position := i 返回找到的位置号,如果没找到则一定正好为0 end
5、position ;(二)过程说明说明入口参数,返回值和过程的功能1、入口参数:过程体入口时的处理codetabletx0.adr.a:=cx;(cx为过程入口地址,填写在code中)with tabletx0 dobeginadr: (过程的入口填写在table表的过程名中)size:=dx; (过程需要的空间填写在table中)end;cxo: (保留过程在code中的入口地址在输出目标代码时用)gen(int,0,dx);(生成过程入口指令)2、返回值:(* 通过静态链求出数据区基地址的函数base *) (* 参数说明:l:要求的数据区所在层与当前层的层差 *) (* 返回值:要求的数
6、据区基址 *) function base(l: integer): var b1: b1 := b; (* find base 1 level down *) (* 首先从当前层开始 *) while l 0 do (* 如果l大于0,循环通过静态链往前找需要的数据区基址 *)= sb1; (* 用当前层数据区基址中的内容(正好是静态链SL数据,为上一层的基址)的作为新的当前层,即向上找了一层 *) l := l - 1 (* 向上了一层,l减一 *) base := b1 (* 把找到的要求的数据区基址返回 *) end(* base *);(三)程序静态结构图(四)PL0文法描述在计算机
7、科学中,文法是编译原理的基础,是描述一门程序设计语言和实现其编译器的方法。文法的描述多用BNF(巴克斯范式),而另一个重要的概念:正则表达式,也是文法的另一种形式。PL/0文法的表示::= .= 过程说明部分= const,=数字|= var, ;= procedure条件语句当循环语句过程调用语句复合语句读语句写语句空 表达式= +|-加法运算符因子乘法运算符| ( 关系运算符|odd= =|= ifthen= whiledo= call= beginend= read ( ) = write ( = a|b|c|d.x|y|z = 0|1|2|3.8|9(五)代码生成程序说明对分程序体人口
8、的处理(见程序文本block 的过程体) begin (*block*) dx:=3; tx0:=tx; (*保留当前table表指针值,实际为过程名在table表中的位置*) tabletx.adr:(*保留当前code指针值到过程名的adr域*) gen(jmp,0,0);(*生成转向过程体入口的指令,该指令的地址为cx已保留在过程名的adr域,真正的过程体入口地址,等生成过程体入口的指令时,再由tabletx.adr中取出 cx将过程体入口返填到cx所指目标代码,即:(jmp,0,0)的第3区域,同时填到tabletx.adr 中*)过程体入口时的处理table表格管理(六)代码生成程序
9、实例给出pl0源程序,中间代码和过程说明编写代码:program abc(input,output);begin= 10; writeln(i);end.运行程序如图:五、实验总结这次实验加深了我对编译过程的理解,无论是整体还是细节都有了更深入的体会,强化了基础知识的进一步学习,如活动记录、符号表、中间过程生成等。这次实验让我更深的认识到只是学习课本是远远不够的,我们还需要从实际的操作中体会所学知识。这次实验让我更好的理解了词法分析语法分析过程的区别。同时,这次实验我也存在着很多的不足,比如我不能完全靠自己的能力理解PL0程序的全部内容,自身知识的不足督促我们通过书籍、网络等途径完善对于知识的认知,扩展自身知识面,提升自身能力,让我们能更好的利用计算机以及编译原理这门课程的知识。教 师 评 价评定项目ABCD算法正确流程图正确语句语法格式正确源程序正确中间代码正确分析过程正确报告规范回答问题正确实验结果正确题解正确其他:评价教师签名:年 月 日
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1