2015广工编译原理课程设计报告(文档最后含源码下载地址)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程设计

课程名称___编译原理__________题目名称___PL/0编译器的扩充__学生学院___计算机学院_________专业班级_计算机科学与技术13(9)学号

学生姓名

指导教师___林志毅________________ 2016年1月2日

一、已完成的内容:

(1)扩充赋值运算:*=和/=

(2)扩充语句(Pascal的FOR语句)

FOR<变量>:=<表达式>STEP<表达式>UNTIL<表达式>Do<语句>(3)增加类型:①字符类型;②实数类型。

(4)增加注释;多行注释由/*和*/包含,单行注释为//

二、实验环境与工具

(1)计算机及操作系统:PC机,Windows7

(2)程序设计语言:C++

(3)使用软件Borland C++Builder6.0

(4)教学型编译程序: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(TABLE[i].KIND==VARIABLE||TABLE[i].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-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);

}

GetSym();

}else Error(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-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);

}

(4)运行测试(测试的PL0源码扩充单词的测试并贴运行结果截图)PL0源码:

PROGRAM EX01;

VAR A,B,C,D;

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);//结果为8

END.

(5)运行结果:

(6)出现的问题及解决

开始时在实现/=和*=操作时,*=的实现很顺利,而/=却一直没有得到理想的结果,通过与同学的讨论得知代码中除号指令的解析中,其实为除余操

作,于是将%改为/,但是结果还是错误,经过调试发现是两个相除的数在栈

相反了,正确的状态应该是除数位于次栈顶,而被除数位于栈顶。

解决:在调用EXPRESSION函数解析/=右边表达式前,先将其左边变量的值放入栈中。

2.扩充语句(Pascal的FOR语句)

FOR<变量>:=<表达式>STEP<表达式>UNTIL<表达式>Do<语句>

(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语句时跳过step语句

CX1=CX;//记录step后语句的代码位置

if(SYM==STEPSYM){

GetSym();

STATEMENT(SymSetUnion(SymSetNew(UNTILSYM),FSYS),LEV,TX);//处理

step后面的表达式

}else Error(8);

if(SYM==UNTILSYM){

CODE[CX3].A=CX;//回填第一次进入for循环时的直接跳转地址

GetSym();

}else Error(8);

CONDITION(SymSetAdd(DOSYM,FSYS),LEV,TX);//

相关文档
最新文档