编译原理课设报告版_第1页
编译原理课设报告版_第2页
编译原理课设报告版_第3页
编译原理课设报告版_第4页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

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

文档简介

1、编译原理课程设计PL0 Experiment Report(燕山大学信息科学与工程学院)姓名班级 :计算机 *学生学号 :130104010*&*课程名称:编译原理指导教师:8882015年12月24日1/20一、设计目的研究、 改进或自行设计、开发一个简单的编译程序或其部分功能,加深对编译理论和编译过程的理解。编程语言不限。二、设计任务扩展 PL/0编译程序功能目的 :扩充 PL/0编译程序功能要求 : (1)阅读、研究 PL/0编译程序源文件。(2) 在上述工作基础上, 可有选择地补充、完善其中词法分析、语法分析、 语义分析、 目标代码生成、 目标代码解释执行等部分的功能。如以语法分析部分

2、为例,则可以增加处理更多语法成分的功能,如可处理一维数组、 +、- 、 +=、-= 、 *= 、 /= 、 %(取余 ) 、 !( 取反 ) 、 repeat 、 for 、else 、开方、处理注释、错误提示、标示符或变量中可以有下划线等。还可以增加类型,如增加字符类型、实数类型 ; 扩充函数如有返回值和返回语句的,有参数函数等 ;(3) 设计编制典型的运行实例, 以便能反映出自己所作的改进。三、设计思想:PL/0 语言可以看成PASCAL语言的子集, 它的编译程序是一个编译解释执行系统。 PL/0 的目标程序为假想栈式计算机的汇编语言,与具体计算机无关。 PL/0 的编译程序和目标程序的解

3、释执行程序都是用PASCAL语言书写 的,因此 PL/0 语言可在配备 PASCAL语言的任何机器上实现。其编译过程采用一趟扫描方式,以语法分析程序为核心,词法分析和代码生成程序都作为一个独立的过程,当语法分析需要读单词时就调用词法分析程序, 而当语法分析正确需要生成相应的目标代码时,则调用代码生成程序。用表格管理程序建立变量、常量和过程表示符的说明与引用之间的信息联系。当源程序编译正确时, PL/0 编译程序自动调用解释执行程序,对目标代码进行解释执行,并按用户程序的要求输入数据和输出运行结果。四、设计内容:1 扩充语句 for(; ; );2扩充语句 if then else ;3扩充语句

4、 repeat ; until ;4 增加自增自减运算 +和和 +=, -= 运算;5 修改不等号 #,为 != ;6 增加一维数组2/20声明格式: /:/;赋值格式: :=;调用格式: 五、程序结构:PL/0 源程序词法分析程序表出语法分析程序错格管管理理程程序序代码生成程序目标程序图 1 编译程序结构1. 功能模块作用如下:Pl0.c :主程序Error :出错处理,打印出错位置和错误编码Getsym:词法分析,读取一个单词Getch :漏掉空格,读取一个字符Gen:生成目标代码,并送入目标程序区 Test :测试当前符号是否合法Block :分程序分析处理过程,词法语法分析 Enter

5、 :登陆名字表Position:查找标识符在名字表中的位置程序 pl0程序 block语句 statement条件 condition表达式 expression项 term因子 factor图 2 功能模块调用3/20Constdeclaration:常量定义处理Vardeclaraction:变量说明处理Listcode:列出目标代码清单Statement :语句处理Expression :表达式处理Term:项处理Factor :因子处理Condition:条件处理Interpret:对目标代码的解释执行程序Base:通过静态链求出数据取得基地址增加两个功能:Arraydeclarati

6、on:数组声明处理Arraycoef:数组索引计算和“虚拟机”动作生成2. 保留字:enum symbol nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,period, becomes,beginsym,endsym,ifsym,thensym,elsesym,forsym, inc,dec,whilesym, writesym,readsym,dosym,callsym,constsym,varsym,procsym,repeatsym,

7、 untilsym, plusbk,minusbk,lbrack,rbrack,colon,共 43 个,其中补充保留字为: else, for, repeat, until, plusbk, minusbk,Lbrack, rbrack, colon3. 名字表中的类型enum object constant, variable, procedure, arrays, 共 4 个,扩充 arrays ,以便实现数组4. 虚拟机代码enum fct lit, opr, lod, sto, cal, inte, jmp, jpc,lda, sta, 共 10 个,补充的lda , sta 用于数

8、组操作4/206. 错误信息(1)const,var,procedure后应为标识符(2) 常数说明中的 =后应是数字(3) 常数说明中的标识符后应是 =(4) 常数说明中的 =写成了: =(5) 漏掉了,或;(6) 过程说明后的符号不正确(应是语句开始符,或过程定义符)(7) 应是语句开始符(8) 标识符未说明(9) 程序结尾丢了句号。(10) 语句之间漏了;(11)call后应为标识符(12) 赋值语句中,赋值号左部标识符属性应是变量(13) 赋值号左部标识符属性应是赋值号(14) 程序体内语句部分的后跟符不正确(15)call后标识符属性应为过程(16) 条件语句中丢了 then(17)

9、 丢了 end 或;(18)while循环语句中丢了do(19) 语句后的符号不正确6. 名字表结构struct tablestructchar nameal;enum object kind;int val;int level;int adr; int size;/ 扩充名字表结构 , 增加一个 data 域保存数组的下界int data;/*其他数据 , 对 arrays 来说是下界 */7. 语法描述图:分程序.程序图 3程序语法描述图5/20constident=number,;varident,;procedureident;分程序语句图 4 分程序语法描述图6/20incsincs

10、decsdecs语ident:=表达式句callidentbegin语句end语句;if条件then语句else语句while条件do语句repeat语句until表达式read(ident),write(表达式),for条件语句图 5 语句语法描述图7/20条件odd表达式表达式=#=图 6 条件语法描述图+表达式项项图 7 表达式语法描述图项因子%因子*/图 8 项语法描述图8/20decsincsincs因子identdecsnumber(表达式)图 9 因子语法描述图四、功能扩充1. 语句处理中加入for循环语句if(sym = forsym)getsymdo;if(sym != lp

11、aren) error(34);/没有左括号出错else getsymdo;statementdo(nxtlev, ptx, lev); /S1代码if(sym != semicolon) error(10); /语句缺少分号出错elsecx1=cx;getsymdo;conditiondo(nxtlev, ptx, lev);/E代码if(sym!=semicolon)error(10);/ 语句缺少分号出错 else cx2=cx;gendo(jpc,0,0);cx3=cx;gendo(jmp,0,0);getsymdo;cx4=cx;9/20statementdo(nxtlev, ptx

12、, lev);/S2 代码if(sym!= rparen) error(22);/缺少右括号出错else gendo(jmp,0,cx1);getsymdo;cx5=cx;statementdo(nxtlev, ptx, lev); /S3代码codecx3.a=cx5;gendo(jmp,0,cx4);codecx2.a=cx;2. 在语句处理中增加repeat-until语句if(sym = repeatsym)cx1 = cx;getsymdo;statementdo(nxtlev, ptx, lev);if(sym = untilsym)getsymdo;conditiondo(nxt

13、lev, ptx, lev);cx2=cx;gendo(jpc, 0, 0);codecx2.a=cx1; else error(33);/没有写 until出错3. 扩充 +和运算符对于 +和 - 运算符,扩充时要注意存在两个情况:1)作为语句的时候;2)作为表达式中的因子的时候。注 意 : 扩 充 时 增 加 因 子 开 始 符facbegsysincs=true和facbegsysdecs=true。扩充的语法描述见结构设计中的PL/0 分程序和主要语句的语法描述中的描述图,详细代码见程序。1)作为语句的时候,有四种情况:a+; a-; +a; -a;文法的 EBNF表示形式为::=+

14、|-|+|- 10/20文法分析过程大体如下图:语句开始符SYM=+或者 语句开始符SYM=ident读下个 SYM,如是 ident ,确读下个 SYM,如是 +或者 - ,定为自增自减语句确定为自增自减语句+a和 aa+和 a生成中间代码对于a+;+a; 和 a-;-a;语句的处理如下:先将变量的值取出放在栈顶,后将1 入栈,后执行加法或减法运算 oprv 指令的 2(加法 ) 、3(减法),后将运算后的栈顶值存回变量。a+; 和 +a; 语句的中间代码:lod 0 3;lit 0 1;opr 0 2;sto 0 3;a-;和 -a; 语句的中间代码:lod 0 3;lit 0 1;opr

15、 0 3;sto 0 3;2)作为因子的时候,有两种情况:a+和 a- 作为因子,比如:b:=a+*a-;语句+a 和 -a 作为因子,比如: b:=-a+2*+a; 语句文法的 EBNF表示形式为::=. +|-|+| -.其中的 .表示前后都可以有其他的项或因子生成中间代码A 对于因子 +a 和 -a的中间代码生成处理和a+; 等语句处理一样;B 对于因子 a+和 a的中间代码生成处理如下:a+:lod 0 3;lit 0 1;opr 0 2;sto 0 3;lod 0 3;lit 0 1;opr 0 3; a-:lod 0 3;lit 0 1;opr 0 3;sto 0 3;lod 0

16、3;lit 0 1;opr 0 2;先将变量的值取出放在栈顶,后将1 入栈,后执行加法或减法运算 opr 指令的 2( 加法 ) 、 3(减法),后将运算后的栈顶值存回变量,后将变量的值又取出来放入栈顶,后将1 入栈,如果是 a+就执行减法,如果是 a就执行加法,以实现先用a 的值后再加1。4. 语句处理中加入if-then-else语句在原有程序 if(sym=then).后加入下列代码:cx1 = cx;gendo(jpc, 0, 0);statementdo(fsys, ptx, lev);if(sym = elsesym)getsymdo;11/20cx2 = cx;gendo(jmp

17、, 0, 0);codecx1.a = cx;statementdo(fsys, ptx, lev);codecx2.a = cx;elsecodecx1.a = cx;5. 修改不等号 #为!=注释源程序中的ssym#= neq 语句,在getsym 中加入下列代码:/ 修改不等号为 !=else if(ch=!)getchdo;if(ch=)sym=neq;getchdo; else sym=nul; 6. 加入对一维数组的支持本程序将数组看做变量的一种,由var 声明函数调用array声明函数完成数组声明,这样就处加入文件输出的相关语句外,可以完全保留block 函数和 enter 函数

18、;通过改写factor函数使数组因子包括了后缀的索引号,这样就可以调用通用的表达式函数赋值数组了。为了方便完成数组相关功能,扩充了虚拟机处理代码。数组的越界及非法调用错误处理没有完善,仅给出了错误代码。在头文件pl0.h中:/* 定义两个全局变量,用来保存数组定义的下界和容量*/static int g_arrBase = 0;static int g_arrSize = 0;/*虚拟机代码 */增加 lda,sta专门由于数组的处理/ 增加两个虚拟机指令 lda,sta, 分别用来从数组中取数和存到数组中/ 数组元素的访问和存储,是将 () 后的当成表达式,先处理,得到元素的索引,放在栈顶/

19、 最后根据数组的首地址,得到某个元素的地址enum fct .lda, sta / 扩充名字表结构 , 增加一个 data 域保存数组的下界struct data; /*其他数据 , 对 arrays 来说是下12/20界 */*名字表中的类型*/enum object .arrays /添加数组类型 / 数组声明处理 , 下界和上界允许已经定义过的常量标识符int arraydeclaration(int* ptx, int lev, int* pdx);/ 数组元素索引计算与“虚拟机”生成int arraycoef(bool *fsys,int *ptx,i

20、nt lev);在源程序文件pl0.c中:编写相关的arraydeclaration,arraycoef两个功能函数:/*数组声明处理,下界和上界允许已经定义过的常量标识符*/int arraydeclaration(int* ptx, int lev, int* pdx)char arrIdal;/*暂存数组标识名, 避免被覆盖 */int cstId;/*常量标识符的位置*/int arrBase=-1, arrTop=-1; /*数组下界、上界的数值*/getsymdo;if(sym=lbrack) /*标识符之后是,则识别为数组*/strcpy(arrId, id);/*检查下界 */

21、getsymdo;if(sym=ident)if(cstId=position(id,(*ptx)!=0) arrBase=(constant=tablecstId.kind)?tablecstId.val:-1; elsearrBase=(sym=number)?num:-1;if(-1=arrBase)error(50);return -1; /*检查冒号 */getsymdo;if(sym!=colon)error(50);return -1;/*检查上界 */getsymdo;if(sym=ident)if(cstId=position(id,(*ptx)!=0) arrTop=(co

22、nstant=tablecstId.kind)?tablecstId.val:-1;elsearrTop=(number=sym)?num:-1;13/20if(arrTop=-1)error(50);/ 随意指定 , 因为原程序对错误号的规划极差!return -1;/*检查 */getsymdo;if(sym!=rbrack)error(50);return -1;/*上下界是否符合条件检查*/g_arrSize=arrTop-arrBase+1;g_arrBase=arrBase;if(g_arrSizen;write(a);write(b);end.当输入的n 为 3 时, repeat.until.语句中的循环体执行3 次,所以a=4,b=72. 测试增加的 +,- 功能测试文件: 2.txt测试结果:var a,b;begina:=1;b:=3;a+

温馨提示

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

评论

0/150

提交评论