2015广工编译原理课程设计报告16页_第1页
2015广工编译原理课程设计报告16页_第2页
2015广工编译原理课程设计报告16页_第3页
2015广工编译原理课程设计报告16页_第4页
2015广工编译原理课程设计报告16页_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

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

文档简介

1、课 程 设 计 课程名称_编译原理_ _题目名称_PL/0编译器的扩充 _学生学院_计算机学院_ _专业班级_ 计算机科学与技术13(9)学 号 学生姓名 指导教师_林志毅_2016 年 1 月 2 日一、 已完成的内容:(1) 扩充赋值运算:*= 和 /=(2) 扩充语句(Pascal的FOR语句)FOR :=STEP UNTILDo(3) 增加类型: 字符类型; 实数类型。(4) 增加注释; 多行注释由/*和*/包含,单行注释为/ 二、 实验环境与工具(1)计算机及操作系统:PC机,Windows7(2)程序设计语言:C+(3)使用软件Borland C+ Builder 6.0(4)教学

2、型编译程序:PL/0三、 具体实现:1. 扩充赋值运算:*= 和 /=(1) 语法树表达式*=(/=,-=,+=)变量(2) 修改GetSym()方法(写出修改的代码) else if(CH=*) GetCh(); if(CH=) SYM=TIMESBECOMES; GetCh(); else SYM=TIMES; else if(CH=/) GetCh(); if(CH=) SYM=SLASHBECOMES; GetCh(); (3) 修改STATEMENT()方法(写出修改的代码)case IDENT:i=POSITION(ID,TX);if (i=0) Error(11);else if

3、 (TABLEi.KIND=VARIABLE | TABLEi.KIND=FLOATTYPE) /*ASSIGNMENT TO NON-VARIABLE*/ GetSym(); if (SYM=BECOMES| SYM=TIMESBECOMES | SYM=SLASHBECOMES|SYM=PLUSBECOMES|SYM=MINUSBECOMES) RELOP=SYM; if(SYM!=BECOMES) /若为除等于(或其他类似符号)则先把符号左边的变量值放入栈中 GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GetSym(); else Error(

4、13); EXPRESSION(FSYS,LEV,TX); if(RELOP=TIMESBECOMES) GEN(OPR,0,4); else if(RELOP=SLASHBECOMES) GEN(OPR,0,5); else if(RELOP=PLUSBECOMES) GEN(OPR,0,2); else if(RELOP=MINUSBECOMES) GEN(OPR,0,3); GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); (4) 运行测试(测试的PL0源码扩充单词的测试并贴运行结果截图)PL0源码:PROGRAM EX01;VAR A,B,C,D;

5、BEGIN A:=16; A/=2; WRITE(A); /结果为8 B:=4; B*=2; WRITE(B); /结果为8 C:=6; C+=2; WRITE(C); /结果为8 D:=10; D-=2; WRITE(D); /结果为8END.(5) 运行结果:(6) 出现的问题及解决开始时在实现/=和*=操作时,*=的实现很顺利,而/=却一直没有得到理想的结果,通过与同学的讨论得知代码中除号指令的解析中,其实为除余操作,于是将%改为/,但是结果还是错误,经过调试发现是两个相除的数在栈中的位置相反了,正确的状态应该是除数位于次栈顶,而被除数位于栈顶。解决:在调用EXPRESSION函数解析/

6、=右边表达式前,先将其左边变量的值放入栈中。2. 扩充语句(Pascal的FOR语句)FOR :=STEP UNTILDo(1) 语法图(2) 修改GetSym()方法(写出修改的代码)此处无修改,FOR、STEP、UNTIL及DO等关键字已放置关键字数组中,通过该数组便可识别。(3) 修改STATEMENT()方法(写出修改的代码)case FORSYM: GetSym(); STATEMENT(SymSetUnion(SymSetNew(STEPSYM),FSYS),LEV,TX); /处理for后面的赋值语句 CX3=CX; GEN(JMP,0,0); /用于第一次执行for语句时跳过s

7、tep语句 CX1=CX; /记录step后语句的代码位置 if(SYM=STEPSYM) GetSym(); STATEMENT(SymSetUnion(SymSetNew(UNTILSYM),FSYS),LEV,TX); /处理step后面的表达式 else Error(8); if(SYM=UNTILSYM) CODECX3.A=CX; /回填第一次进入for循环时的直接跳转地址 GetSym(); else Error(8); CONDITION(SymSetAdd(DOSYM, FSYS),LEV,TX); /处理条件语句 if(SYM=DOSYM) GetSym(); else E

8、rror(8); CX2=CX; GEN(JPC,0,0); /条件跳转,栈顶若为非真,则跳转到参数三位置,该位置待回填 STATEMENT(FSYS,LEV,TX); /处理do后面内容 GEN(JMP,0,CX1); /执行完for语句内的语句则重新跳回step处 CODECX2.A=CX; /回填条件跳转 break;(4) 运行测试PL0源码:PROGRAM EX01;VAR A,SUM;BEGIN SUM:=0; FOR A:=1 STEP A+=1 UNTIL A=0 & CH=0 & CH=0 & CH=9) /以下获取小数点后的值 J=0; M=(CH-0)*0.1; whil

9、e(JLMAX) Error(30); /LMAX为小数点后数字最大度 fprintf(FOUT,%f, NUM); (2) 修改Block中的方法运行测试if (SYM=CHARSYM) GetSym(); do CharDeclaration(LEV,TX,DX); while (SYM=COMMA) GetSym(); CharDeclaration(LEV,TX,DX); if (SYM=SEMICOLON) GetSym(); else Error(5); while(SYM=IDENT);if (SYM=FLOATSYM) GetSym(); do FloatDeclaration

10、(LEV,TX,DX); while (SYM=COMMA) GetSym(); DoubleDeclaration(LEV,TX,DX); if (SYM=SEMICOLON) GetSym(); else Error(5); while(SYM=IDENT); (3) 修改STATEMENT中的方法case IDENT: GetSym();i=POSITION(ID,TX);if (i=0) Error(11);else if (TABLEi.KIND=CHARTYPE | TABLEi.KIND=VARIABLE | TABLEi.KIND=FLOATTYPE) /*ASSIGNMENT

11、 TO NON-VARIABLE*/if (SYM=BECOMES | SYM=TIMESBECOMES | SYM=SLASHBECOMES | SYM=PLUSBECOMES| SYM=MINUSBECOMES) RELOP=SYM; if(SYM!=BECOMES) /若为除等于(或其他类似)。则先把符号左边的变量值放入栈中 GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); GetSym(); else Error(13); EXPRESSION(FSYS,LEV,TX); if(RELOP=TIMESBECOMES) GEN(OPR,0,4); e

12、lse if(RELOP=SLASHBECOMES) GEN(OPR,0,5); else if(RELOP=PLUSBECOMES) GEN(OPR,0,2); else if(RELOP=MINUSBECOMES) GEN(OPR,0,3); GEN(STO,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); else Error(12); i=0; break;case WRITESYM:/根据不同类型进行相应输出GetSym();if (SYM=LPAREN) do GetSym();EXPRESSION(SymSetUnion(SymSetNew(RPAREN,C

13、OMMA),FSYS),LEV,TX); i=POSITION(ID,TX); switch (TABLEi.KIND) case CHARTYPE:GEN(OPR,0,17); break; case FLOATTYPE:GEN(OPR,0,18); break; default:GEN(OPR,0,14); while(SYM=COMMA); if (SYM!=RPAREN) Error(SBNUM); else GetSym();GEN(OPR,0,15);break; /*WRITESYM*/(4) 修改FACTOR中的方法(包含字符的识别处理)while (SymIn(SYM,FAC

14、BEGSYS) if (SYM=IDENT) i=POSITION(ID,TX); if (i=0) Error(11); elseswitch (TABLEi.KIND) case CONSTANT: GEN(LIT,0,TABLEi.VAL); break; case VARIABLE: GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); break; case PROCEDUR: Error(21); break; case FLOATTYPE: GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); break; ca

15、se CHARTYPE: GEN(LOD,LEV-TABLEi.vp.LEVEL,TABLEi.vp.ADR); break; GetSym(); else if (SYM=NUMBER) if (NUMAMAX) Error(31); NUM=0; GEN(LIT,0,NUM); GetSym(); /将表达式中的数字置于栈顶 else if (SYM=LPAREN) /左 括 号 GetSym(); EXPRESSION(SymSetAdd(RPAREN,FSYS),LEV,TX);if (SYM=RPAREN) GetSym();else Error(22); else if (SYM=

16、CHARACTER) GEN(LIT,0,NUM); /将字符放入栈顶 GetSym(); (5) 修改ENTER中的方法case CHARTYPE: TABLETX.vp.LEVEL=LEV; TABLETX.vp.ADR=DX; DX+; break; case FLOATTYPE: TABLETX.vp.LEVEL=LEV; TABLETX.vp.ADR=DX; DX+; break;(6) 在Interpret指令OPR中增加字符输出和实数输出case 17: Form1-printcs(ST); fprintf(FOUT,%cn,ST); T-; /增加字符输出 break;case

17、 18: Form1-printrs(,ST); fprintf(FOUT,%dn,ST); T-; /增加实数型输出 break;(7) 其它修改1) 增加相应的关键字char和float;2) 由于增加实型,因此将模拟栈的数组类型改为double型;另目标指令结构体INSTRUCTION中的A,及全局变量NUM也改为double型(8) 运行测试:PL0源码:PROGRAM EX01;CHAR A,B;FLOAT C,D,SUM;BEGIN A:=A; B:=B+2; WRITE(A); WRITE(B); WRITE(B+2); C:=123.321; D:=321.123; SUM:=

18、C+D+0.0004; WRITE(SUM); END.(9) 运行结果:(10) 出现的问题及解决字符型的实现主要问题是在赋值、字符表达式的处理及输出三个方面。赋值刚开始没有思路,之后借鉴VAR型的赋值,才清楚需要使用到栈这个媒介进入赋值:先把字符值放入栈中,在将栈顶值传给字符型变量。而字符表达式的处理在Factor里进行识别处理。关于输出则需要在WRITESYM的识别处理中进行类型判断采取不同输出方式,并需新建一条指令专门用于字符输出实数型的实现主要问题为:1、数据获取:小数点后的值的获取需要用到循环帮助实现;2、变量更改:在没有引入实数型前,用来模拟栈的数组类型为int型,而引入后,则需

19、要将其更改为实数型,在程序中与栈值有关的那些变量类型也同样改为实数型。4. 增加注释; 多行注释由/*和*/包含,单行注释为/ (1) 修改GetSym()方法(写出修改的代码)else if(CH=/) GetCh(); if(CH=) SYM=SLASHBECOMES; GetCh(); else if(CH=*) GetCh(); i=CH; while(i!=* | CH!=/) i=CH; GetCh(); / Form1-printcs(CH); if(i!=*&CH!=/) Error(19); else GetCh();/不能忽略,为下一次调用GetSym提供第一个字符,用于switch语句 GetSym(); else if(CH=/) /单行注释功能 i=CX;/记录当前行 while(CC!=LL) GetCh(); /CC为当前字符在行中位置,LL为当前行的字数 GetSym(); /滤去注释后继续获取后面的字符串 else SYM=SLASH; (2) 运行测试PL0源码:PROGRAM EX01;VAR A,SUM;BEGIN /*下面代码求解1到100的之间 每个整数的相加之和*/ SUM:=0; FOR A:=1 STEP A+=1 UNTIL A=100 DO /求1100的和SUM+=A; WRITE(SUM); END.(3) 运行结

温馨提示

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

评论

0/150

提交评论