广工2014编译原理实验报告_第1页
广工2014编译原理实验报告_第2页
广工2014编译原理实验报告_第3页
广工2014编译原理实验报告_第4页
广工2014编译原理实验报告_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

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

文档简介

实 验 报 告 课程名称 编译原理 题目名称 PL/0编译器的扩充 学生学院 计算机学院 专业班级 计算机科学与技术12(4)学 号 学生姓名 柏石先 指导教师 李杨 程序功能完成情况测试用例全面程度学生对所编程序熟悉程度报告格式是否与要求相符报告内容是否准确、全面2014 年 12 月 20日一、 实验目的与要求对PL/0作以下修改扩充:(1) 增加单词:保留字 ELSE,FOR,STEP,UNTIL,DO,RETURN运算符 *=,/=,&,|,!(2)修改单词:不等号# 改为 (3)增加条件语句的ELSE子句,要求:写出相关文法,语法描述图,语义描述图。二、 实验环境与工具1、源语言:PL/0语言,PL/0语言是PASCAL语言的子集,它的编译程序是一个编译解析执行系统,后缀名为.PL0;2、目标语言:生成文件后缀为*.COD的目标代码3、实现平台:Borland C+Builder 64、运行平台:Windows 8.1三、 结构流程1、 结构设计说明(1)PL/0 语言编译器 PL/0语言可看成是PASCAL语言的子集,它的编译程序是一个编译解释执行系统。PL/0的目标程序为假想栈式计算机的汇编语言,与具体计算机无关。出错处理函数表格管理函数PL/0 源程序目标代码生成程序程序目标代码生成程序程序目标代码生成程序程序目标代码生成程序程序目标代码生成程序程序 2、 词法分析程序的设计四、 开发过程(一) 增加单词:保留字 ELSE,FOR,STEP,UNTIL,DO , RETURN运算符 *=,/=,&,|,!新增6个保留字和5个运算符,合计11个单词。其中保留字ELSE,FOR,STEP,UNTIL,DO, RETURN 分别对应ELSESYM,FORSYM, STEPSYM, UNTILSYM,DOSYM,RETURNSYM;运算符 *= ,/= ,& ,| , ! 分别对应 TIMESBECOMES, SLASHBECOMES, ANDSYM, ORSYM, NOTSYM。注:要求只做词法分析部分,不做语义分析处理,实验的结果只是识别新增的保留字和运算符,并且将其打印显示出来。运算符*=/=&|!SYM表示TIMESBECOMESSLASHBECOMESANDSYMORSYMNOTSYM1 首先考虑需要增加保留字的个数,以及如何命名,再将新增的保留字添加对应的保留字的集合中。具体实现的语句如下所示:typedef enum NUL, IDENT, NUMBER, PLUS, MINUS, TIMES, SLASH, ODDSYM, EQL, NEQ, LSS, LEQ, GTR, GEQ, LPAREN, RPAREN, COMMA, SEMICOLON, PERIOD, BECOMES, BEGINSYM, ENDSYM, IFSYM, THENSYM, WHILESYM, WRITESYM, READSYM, DOSYM, CALLSYM, CONSTSYM, VARSYM, PROCSYM, PROGSYM, ELSESYM, FORSYM, STEPSYM, STEPSYM, RETURNSYM, TIMESBECOMES, SLASHBECOMES, ANDSYM, ORSYM, NOTSYM SYMBOL;2 这里需要注意,一定要参照已有的保留字,进行相应的命名和添加规范。具体实现的语句如下所示:char *SYMOUT = NUL, IDENT, NUMBER, PLUS, MINUS, TIMES, SLASH, ODDSYM, EQL, NEQ, LSS, LEQ, GTR, GEQ, LPAREN, RPAREN, COMMA, SEMICOLON, PERIOD, BECOMES, BEGINSYM, ENDSYM, IFSYM, THENSYM, WHILESYM, WRITESYM, READSYM, DOSYM, CALLSYM, CONSTSYM, VARSYM, PROCSYM, PROGSYM, ELSESYM, FORSYM, STEPSYM, STEPSYM, RETURNSYM, TIMESBECOMES, SLASHBECOMES, ANDSYM, ORSYM, NOTSYM ;3 将新增的保留字按照字母表升序的方式添加,运算符参照已有的运算符来进行添加,注意好符号与SYM的对应。具体实现的语句如下所示:特别注意点:此处一定要考虑到PLO编译器采用了折半查找算法来进行操作,如果新增的保留字没有按照既定的升序规则来插入,会造成在编译过程中,编译器无法识别某些保留字。strcpy(KWORD 1,BEGIN); strcpy(KWORD 2,CALL); strcpy(KWORD 3,CONST); strcpy(KWORD 4,DO); strcpy(KWORD 5,ELSE); strcpy(KWORD 6,END); strcpy(KWORD 7,FOR); strcpy(KWORD 8,IF); strcpy(KWORD 9,ODD); strcpy(KWORD 10,PROCEDURE); strcpy(KWORD 11,PROGRAM); strcpy(KWORD12,READ); strcpy(KWORD13,RETURN); strcpy(KWORD14,STEP); strcpy(KWORD15,THEN); strcpy(KWORD16,UNTIL); strcpy(KWORD17,VAR); strcpy(KWORD18,WHILE); strcpy(KWORD19,WRITE); WSYM 1=BEGINSYM; WSYM 2=CALLSYM; WSYM 3=CONSTSYM; WSYM 4=DOSYM; WSYM 5=ELSESYM; /*增加保留字符号elsesym*/ WSYM 6=ENDSYM; WSYM 7=FORSYM; WSYM 8=IFSYM; WSYM 9=ODDSYM; WSYM 10=PROCSYM; WSYM 11=PROGSYM; WSYM12=READSYM; WSYM13=RETURNSYM; WSYM14=STEPSYM; WSYM15=THENSYM; WSYM16=UNTILSYM; WSYM17=VARSYM; WSYM18=WHILESYM; WSYM19=WRITESYM; SSYM+=PLUS; SSYM-=MINUS; SSYM*=TIMES; SSYM/=SLASH; SSYM(=LPAREN; SSYM)=RPAREN; SSYM=EQL; SSYM,=COMMA; SSYM.=PERIOD; SSYM;=SEMICOLON; SSYM&=ANDSYM; SSYM!=NOTSYM;4 在完成保留字的添加以后,在void STATEMENT(SYMSET FSYS,int LEV,int &TX)函数中增加相应的语句,注意满足语法规则。这是用来检验保留字是否添加成功的标志。具体实现的语句如下所示:case FORSYM: GetSym(); Form1-printfs(保留字:FORSYM); break;case STEPSYM: GetSym(); Form1-printfs(保留字:STEPSYM); break;case UNTILSYM: GetSym(); Form1-printfs(保留字:UNTILSYM); break;case RETURNSYM: GetSym(); Form1-printfs(保留字:RETURNSYM); break;case DOSYM: GetSym(); Form1-printfs(保留字:DOSYM); break; 5 新增的运算符需要被编译器识别,必须满足编译器做词法分析时,能够正确得到对于的SYM,因此在GetSym()函数中在相应位置增加相应的运算符分析判断,具体实现如下面所示的语句:else if (CH=:) GetCh();if (CH=) SYM=BECOMES; GetCh(); else SYM=NUL; else if(CH = *) GetCh(); if(CH = =) SYM = TIMESBECOMES; GetCh(); else SYM=SSYM*; else if(CH = /) GetCh(); if(CH = =) SYM = SLASHBECOMES; GetCh(); else SYM=SSYM/; else /* THE FOLLOWING TWO CHECK WERE ADDED BECAUSE ASCII DOES NOT HAVE A SINGLE CHARACTER FOR = */ if (CH=) SYM=NEQ; GetCh(); /不等号加 else SYM=LSS;else if (CH=) GetCh(); if (CH=) SYM=GEQ; GetCh(); else SYM=GTR; else if (CH=&) SYM=ANDSYM; GetCh(); else if (CH=|) GetCh(); if (CH=|) SYM=ORSYM; GetCh(); else Error(19); else if (CH=!) SYM=NOTSYM; GetCh(); else SYM=SSYMCH; GetCh(); 6 完成运算符语义分析之后,按照增加保留字的方法一样,同样在void STATEMENT(SYMSET FSYS,int LEV,int &TX)函数中增加相应语句,这是用来检验运算符是否添加成功的标志。具体实现的语句如下所示:case TIMESBECOMES: GetSym(); Form1-printfs(运算符:*= ); break; case SLASHBECOMES: GetSym(); Form1-printfs(运算符: /= ); break; case ANDSYM: GetSym(); Form1-printfs(运算符:& ); break; case ORSYM: GetSym(); Form1-printfs(运算符:| ); break; case NOTSYM: GetSym(); Form1-printfs(运算符:! ); break;7 特别需要注意的两点,这个是很容易被忽略的地方,就是在完成保留字和运算符的增加以后,一定要对PLO编译器对保留字个数已经单词总数定义进行相应的修改。保留字总数比如说在不添加任何保留字的情况下,PL0编译器的原保留字应该是14个,所以在Unit1.CPP中有定义const NORW = 14; /* # OF RESERVED WORDS */而在实验中因为新增加保留字5个,故此处应改为:const NORW = 19; /* # OF RESERVED WORDS */单词总数与保留字总数一样,我们增加完保留字和运算符以后,要修改单词总是,比如原单词总数是33,因为原编译器中并未定义一个常量来进行统一管理,所以需要对所有“i33”的地方进行修改。因为实验中新增加单词10个,故应改为“i43”。(二) 修改运算符:不等号 # 改为 1. 因为原先的不等于在编译器中是用单字符#表示的,如今改成的双字符形式,所以需要做的词法分析过程不一样。首先把源代码中的程序段 SSYM#=NEQ; 语句删除或注释消去。 2. 在GetSym()过程中把分析到的定义为不等号,从“”的if判断语句进行相应的修改。 else /* THE FOLLOWING TWO CHECK WERE ADDED BECAUSE ASCII DOES NOT HAVE A SINGLE CHARACTER FOR = */ if (CH=) SYM=NEQ; GetCh(); /更改不等号为“” else SYM=LSS;(三) 增加条件语句的ELSE子句,要求:写出相关文法,语法图,语义规则。1. 相关文法规则G(S): Sif S else S | if S | a2. 语法描述图3. IFELSE语句的语义分析4. 代码修改首先明白if语句的处理,按if语句的语法,首先调用逻辑表达式处理过程处理if语句的条件,把相应的真假值放到数据栈顶。接下去记录下代码段分配位置(即下面生成的jpc指令的位置),然后生成条件转移jpc指令(遇0或遇假转移),转移地址未知暂时填0。然后调用语句处理过程处理then语句后面的语句或语句块。then后的语句处理完后,当前代码段分配指针的位置就应该是上面的jpc指令的转移位置。通过前面记录下的jpc指令的位置,把它的跳转位置改成当前的代码段指针位置。在void STATEMENT(SYMSET FSYS,int LEV,int &TX)中加入ELSE的实现语句,如下所示的实现方式:case IFSYM: GetSym(); /* 条件语句*/CONDITION(SymSetUnion(SymSetNew(THENSYM,DOSYM),FSYS),LEV,TX);if (SYM=THENSYM) GetSym();else Error(16); CX1=CX; GEN(JPC,0,0); STATEMENT(FSYS,LEV,TX); if (SYM=ELSESYM) /* 如果THAN后面跟ELSE,ELSE可有可无,不影响IF语句 */ GetSym(); CX2=CX; GEN(JMP,0,0);/*无条件跳转语句*/ CODECX1.A=CX; /*cx即为else语句的位置,回填之前的JPC语句跳转的语句*/ STATEMENT(FSYS,LEV,TX); /*else中的语句体*/ CODECX2.A=CX; /*执行完ELSE中的语句体后的地址,把它回填JMP中的跳转地址*/ else /*如果than语句后面没有发现else*/ CODECX1.A=CX; /*执行JPC语句跳转到此地址,当前地址为then后面Statement语句执行完的地址*/ break;五、 关于测试用例说明:六、 实验结果 1实例代码:可测试实验中所有增加的内容。(使用的测试用例:E01.PL0)PROGRAM E01;VAR A,B,C;BEGIN B:=8; C:=2; READ(A); IF A1 THEN WRITE(B) ELSE WRITE(C); FOR; DO; UNTIL; RETURN; *=; /=;

温馨提示

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

评论

0/150

提交评论