编译课程设计Word格式文档下载.docx
《编译课程设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《编译课程设计Word格式文档下载.docx(12页珍藏版)》请在冰豆网上搜索。
![编译课程设计Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2023-1/3/fc3591a7-5c90-4c8e-baa6-5664181e2dcd/fc3591a7-5c90-4c8e-baa6-5664181e2dcd1.gif)
①字符类型;
②实数类型。
(3)扩充函数:
①有返回值和返回语句;
②有参数函数。
(4)增加一维数组类型(可增加指令)。
(5)其他典型语言设施。
三、实验环境与工具
(1)计算机及操作系统:
PC机,Windows2000,WindowsXP
(2)程序设计语言:
C++Builder5,VC6.0
(3)教学型编译程序:
PL/0
4、设计原理与方案
1.PL0语言结构图如下
2.各功能模块描述
模块名:
主函数模块(即:
void__fastcallTForm1:
ButtonRunClick(TObject*Sender))
输入:
PL/0源程序
输出:
目标程序和运行结果
功能:
主程序初始化编译环境,建立关键字表,调用分程序Block对源文件进行编译,当源程序编译正确时,自动调用解释执行程序,对目标代码进行解释执行。
Error(即:
voidError(intn))
出错位置CC和错误性质编号N
显示出错信息
出错处理,打印出错位置和错误性质编号。
GetSym(即:
voidGetSym())
源程序的字符流
单词符号
词法分析,读取一个单词
Gen(即:
voidGEN(FCTX,intY,intZ))
伪操作码F;
层次差L;
立即数或位移量或功能号A
类PCODE指令
生成目标代码,并送入目标程序区。
Test(即:
voidTEST(SYMSETS1,SYMSETS2,intN))
进入或退出某一语法单元时当前单词应属合法的集合S1;
在某一出错状态时,可恢复分析工作的补充单词符号集合S2;
出错信息编号
调用Error显示出错信息
测试当前单词是否是合法
Block(即:
voidBlock(intLEV,intTX,SYMSETFSYS))
分程序层次LEV;
符号表索引TX;
退出时当前符号应属的集合FSYS;
生成分程序的目标代码
分程序分析处理过程。
Enter(即:
voidENTER(OBJECTSK,intLEV,int&
TX,int&
DX))
单词类别K;
层次L;
地址指针DX;
更新的符号表
登录过程说明对象包括变量、常量和过程名的属性信息到符号表。
Position(即:
intPOSITION(ALFAID,intTX))
标识符ID;
符号表索引TX
标识符在符号表中的位置
查找标识符在符号表中的位置。
Constdeclaration(即:
voidConstDeclaration(intLEV,int&
TX,int&
常量定义处理,收集常量信息并登录到符号表。
Vardeclaration(即:
voidVarDeclaration(intLEV,int&
变量定义处理,收集变量信息并登录到符号表。
Listcode(即:
voidListCode(intCX0))
当前分程序在目标代码区的起始索引CX
打印当前分程序的目标代码
列出目标代码清单。
Factor(即:
voidFACTOR(SYMSETFSYS,intLEV,int&
TX))
<
因子>
编译结果与<
类型Ftype;
因子分析处理。
Term(即:
voidTERM(SYMSETFSYS,intLEV,int&
项>
类型Ttype;
项分析处理过程。
Expression(即:
voidEXPRESSION(SYMSETFSYS,intLEV,int&
表达式编译结果与表达式类型Etype;
表达式分析处理。
Condition(即:
voidCONDITION(SYMSETFSYS,intLEV,int&
条件>
条件处理。
Statement(即:
voidSTATEMENT(SYMSETFSYS,intLEV,int&
相应语句编译结果;
语法分析,语句部分处理。
Block(即voidBlock(intLEV,intTX,SYMSETFSYS))
Lev:
当前分程序所在层
Tx:
名字表当前尾指针
Fsys:
当前模块后跟符号集合
Base(即:
intBASE(intL,intB,intS[]))
层差L;
基地址B;
运行数据区S;
与当前数据区相差为L的数据区的首地址;
通过静态链求数据区首地址。
Interpret(即:
voidInterpret())
目标代码;
用户程序执行结果;
对目标代码进行解析执行。
3.程序修改部分如下:
修改部分用黑斜体表明显示
(1).扩充赋值运算:
+=,++,--,-=
1).增加保留字以及运算符的类别表示
在枚举类型SYMBOL中添加元素PLUSEQ,MINEQ,ADDSEL,DECSEL,
分别代表+=,-=,++,--。
typedefenum{NUL,IDENT,NUMBER,PLUS,MINUS,TIMES,
SLASH,ODDSYM,EQL,NEQ,LSS,LEQ,GTR,GEQ,
PLUSEQ,MINEQ,ADDSEL,DECSEL,
LPAREN,RPAREN,COMMA,SEMICOLON,PERIOD,
BECOMES,BEGINSYM,ENDSYM,IFSYM,THENSYM,
WHILESYM,WRITESYM,READSYM,DOSYM,CALLSYM,
CONSTSYM,VARSYM,PROCSYM,PROGSYM,ELSESYM,
REPEATSYM,DOWHILESYM,RETURRNSYM}SYMBOL;
char*SYMOUT[]={"
NUL"
"
IDENT"
NUMBER"
PLUS"
MINUS"
TIMES"
"
SLASH"
ODDSYM"
EQL"
NEQ"
LSS"
LEQ"
GTR"
GEQ"
"
PLUSEQ"
"
MINEQ"
ADDSEL"
DECSEL"
"
LPAREN"
RPAREN"
COMMA"
SEMICOLON"
PERIOD"
BECOMES"
BEGINSYM"
ENDSYM"
IFSYM"
THENSYM"
WHILESYM"
WRITESYM"
READSYM"
DOSYM"
CALLSYM"
CONSTSYM"
VARSYM"
PROCSYM"
PROGSYM"
ELSESYM"
REPEATSYM"
DOWHILESYM"
RETURNSYM"
};
2).增加保留字的个数:
constNORW=22;
3).改变所有的分配空间
把原先的“33”全都改为“41”
SYMSETSymSetUnion(SYMSETS1,SYMSETS2){
SYMSETS=(SYMSET)malloc(sizeof(int)*41);
for(inti=0;
i<
41;
i++)
if(S1[i]||S2[i])S[i]=1;
elseS[i]=0;
returnS;
}
4)修改GetSym()以使PL/0语言能够识别新增的运算符。
画出扩充条件语句的语法描述图如下(词法分析)
if(CH=='
'
)
{GetCh();
if(CH=='
='
){SYM=LEQ;
GetCh();
}
else
if(CH=='
>
){SYM=NEQ;
elseSYM=LSS;
elseif(CH=='
)
{GetCh();
if(CH=='
){SYM=GEQ;
elseSYM=GTR;
elseif(CH=='
+'
if(CH=='
){SYM=PLUSEQ;
SYM=MINEQ;
elseSYM=PLUS;
-'
){GetCh();
SYM=ADDSEL;
SYM=DECSEL;
elseSYM=MINUS;
else{SYM=SSYM[CH];
}/*GetSym()*/
5)在voidSTATEMENT(SYMSETFSYS,intLEV,int&
TX)函数中作出以下修改(语法分析)
inti,CX1,CX2;
switch(SYM){
caseIDENT:
i=POSITION(ID,TX);
if(i==0)Error(11);
elseif
(TABLE[i].KIND!
=VARIABLE){/*ASSIGNMENTTONON-VARIABLE*/
Error(12);
i=0;
GetSym();
if(SYM==BECOMES)
{GetSym();
EXPRESSION(FSYS,LEV,TX);
if(i!
=0)GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
elseif(SYM==PLUSEQ)//实现+=功能
EXPRESSION(FSYS,LEV,TX);
表达式分析
GEN(LOD,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
生成目标代码
GEN(OPR,0,2);
GEN(STO,LEV-TABLE[i].vp.LEVEL,TABLE[i].vp.ADR);
elseif(SYM==ADDSEL)//实现++功能
GEN(OPR,0,3);
elseif(SYM==MINEQ)//实现-=功能
GEN(LIT,0,1);
elseif(SYM==DECSEL)//实现――功能
{GetSym();
elseError(13);
break;
至此赋值运算--,++,+=,-=的操作扩展完成。
5、测试结果分析
(1)实现++功能测试
*****PL/0CompilerDemo*****
===COMPILEPL0===
0PROGRAMEX01;
0VARA;
1BEGIN
2READ(A);
4A++;
8WRITE(A)
10END.
0JMP01
1INI04
2OPR016
3STO03
4LOD03
5LIT01
6OPR02
7STO03
8LOD03
9OPR014
10OPR015
11OPR00
~~~RUNPL0~~~
?
8
9
~~~ENDPL0~~~
(2)实现--功能测试
0PROGRAMEX02;
4A--;
6OPR03
7
(3)实现+=功能测试
0PROGRAMEX03;
4A+=5;
4LIT05
5LOD03
13
(4)实现-=功能测试
0PROGRAMEX04;
4A-=5;
5LIT05
3
6、完成情况
基本内容(必做)没有完成扩充for语句。
选做内容完成了++,--。
心得体会
这是一次在原有程序的基础上,对原有程序进行修改,增加一些原来没有的功能。
并在已有程序的基础上作出一定的添加,实现了“++――+=”-=“的基本功能。
通过这次PL0语言的扩充实验,深入学习了词法分析程序、语法分析程序和语义处理程序的功能以及实现。
对整个编译程序有了一定的了解,也更好的学习到编译程序的整体结构和实现过程。