广工204编译原理实验报告.docx
- 文档编号:8294452
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:12
- 大小:223.26KB
广工204编译原理实验报告.docx
《广工204编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《广工204编译原理实验报告.docx(12页珍藏版)》请在冰豆网上搜索。
广工204编译原理实验报告
实验报告
课程名称编译原理
题目名称PL/0编译器的扩充
学生学院计算机学院
专业班级计算机科学与技术12(4)
学号01
学生姓名柏石先
指导教师李杨
程序功能完成情况
测试用例全面程度
学生对所编程序熟悉程度
报告格式是否与要求相符
报告内容是否准确、全面
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、实现平台:
BorlandC++Builder6
4、运行平台:
Windows
三、结构流程
1、结构设计说明
(1)PL/0语言编译器
PL/0语言可看成是PASCAL语言的子集,它的编译程序是一个编译解释执行系统。
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表示
TIMESBECOMES
SLASHBECOMES
ANDSYM
ORSYM
NOTSYM
1.首先考虑需要增加保留字的个数,以及如何命名,再将新增的保留字添加对应的保留字的集合中。
具体实现的语句如下所示:
typedefenum{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(KWORD[12],"READ");
strcpy(KWORD[13],"RETURN");
strcpy(KWORD[14],"STEP");
strcpy(KWORD[15],"THEN");
strcpy(KWORD[16],"UNTIL");
strcpy(KWORD[17],"VAR");
strcpy(KWORD[18],"WHILE");strcpy(KWORD[19],"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;WSYM[12]=READSYM;
WSYM[13]=RETURNSYM;
WSYM[14]=STEPSYM;
WSYM[15]=THENSYM;
WSYM[16]=UNTILSYM;
WSYM[17]=VARSYM;
WSYM[18]=WHILESYM;WSYM[19]=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.在完成保留字的添加以后,在voidSTATEMENT(SYMSETFSYS,intLEV,int&TX){}函数中增加相应的语句,注意满足语法规则。
这是用来检验保留字是否添加成功的标志。
具体实现的语句如下所示:
caseFORSYM:
GetSym();
Form1->printfs("保留字:
FORSYM~~~~");
break;
caseSTEPSYM:
GetSym();
Form1->printfs("保留字:
STEPSYM~~~~");
break;
caseUNTILSYM:
GetSym();
Form1->printfs("保留字:
UNTILSYM~~~~");
break;
caseRETURNSYM:
GetSym();
Form1->printfs("保留字:
RETURNSYM~~~~");
break;
caseDOSYM:
GetSym();
Form1->printfs("保留字:
DOSYM~~~~");
break;
5.新增的运算符需要被编译器识别,必须满足编译器做词法分析时,能够正确得到对于的SYM,因此在GetSym()函数中在相应位置增加相应的运算符分析判断,具体实现如下面所示的语句:
else
if(CH==':
'){
GetCh();
if(CH=='='){SYM=BECOMES;GetCh();}
elseSYM=NUL;
}
else
if(CH=='*'){
GetCh();
if(CH=='='){
SYM=TIMESBECOMES;
GetCh();
}elseSYM=SSYM['*'];
}
else
if(CH=='/'){
GetCh();
if(CH=='='){
SYM=SLASHBECOMES;
GetCh();
}elseSYM=SSYM['/'];
}
else/*THEFOLLOWINGTWOCHECKWEREADDED
BECAUSEASCIIDOESNOTHAVEASINGLECHARACTERFOR<=OR>=*/
if(CH=='<'){
GetCh();
if(CH=='='){SYM=LEQ;GetCh();}
elseif(CH=='>'){SYM=NEQ;GetCh();}
=CX;/*cx即为else语句的位置,回填之前的JPC语句跳转的语句*/
STATEMENT(FSYS,LEV,TX);/*else中的语句体*/
CODE[CX2].A=CX;/*执行完ELSE中的语句体后的地址,把它回填JMP中的跳转地址*/
}
else/*如果than语句后面没有发现else*/{
CODE[CX1].A=CX;/*执行JPC语句跳转到此地址,当前地址为then后面Statement语句执行完的地址*/
}
break;
五、关于测试用例说明:
六、实验结果
1.实例代码:
可测试实验中所有增加的内容。
(使用的测试用例:
)
PROGRAME01;
VARA,B,C;
BEGIN
B:
=8;
C:
=2;
READ(A);
IFA<>1THEN
WRITE(B)
ELSE
WRITE(C);
FOR;
DO;
UNTIL;
RETURN;
*=;
/=;
&;
||;
!
;
2.实验结果截图
测试修改不等于和增加保留字运算符
截图1:
截图2:
3.目标代码生成情况:
0JMP01
1INI06
2LIT08
3STO04
4LIT02
5STO05
6OPR016
7STO03
8LOD03
9LIT01
10OPR09
11JPC016
12LOD04
13OPR014
14OPR015
15JMP019
16LOD05
17OPR014
18OPR015
19OPR00
4.结果输出情况
七、心得体会
编译原理课程实验,总的来说,我体会到的觉得不仅仅是说对编译器进行了什么修改完成了什么功能了收获感,觉得更多的是在理解编译原理这门课程的基础上,对编译器执行代码编译的过程有了一个全新的认识。
对于高级语言,可能在之前的编程学习和训中更多的是对高级语言如何进行代码功能实现进行考虑,只是说只要我满足语法规则,知道如何按照既定的需求完成功能上的实现而已。
但是学习编译原理,而且切实的进行编译器编程之后,对这个编译器如何实现我们的代码转换有了新的认识,站在这个基础上去理解高级语言的语法分析的过程,去想象高级语言的语义分析的思路,对自己的编程感悟也有了一些提高。
而对于实验内容来说增添保留字和运算符以及修改单词是很基本的操作。
只要明白词法分析的过程就很容易完成,对于ELSE语句的添加,更多的是体现在ELSE语句体的语义分析上面,这个需要我们对语义衔接跳转回调的理解。
总之,个人觉得还是收获颇丰的,也感谢在学习过程中李扬老师的耐心讲解。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 204 编译 原理 实验 报告