编译技术课程设计指导书.docx
《编译技术课程设计指导书.docx》由会员分享,可在线阅读,更多相关《编译技术课程设计指导书.docx(13页珍藏版)》请在冰豆网上搜索。
编译技术课程设计指导书
编译技术
课程设计指导书
题目:
L语言编译器的设计与实现
院系:
计算机学院
2010年11月1日
第一节概述
1课程设计的目的和任务
编译技术是一门实践性很强的课程,只有通过实践,才能真正掌握。
实际的编译程序是十分复杂的,有时由多达十几万条指令组成。
为此,编译原理的实践教学,采用简化高级程序设计语言文法的办法,重点针对词法分析、语法分析、语义分析和中间代码生成以及目标代码生成等几个关键环节进行编程和调试训练。
每个环节可作为一个独立的实践课题,分别编程调试,然后再连接在一起总调,从而实现一个完整的编译器。
2实践方法
任何一个实用的高级语言,其语法都比较复杂,如选其作为源语言,很难实践全过程,故本实践将定义一个简化的类PASCAL语言——L语言作为源语言,设计调试出它的编译程序。
因任务具有一定的难度和工作量,且时间有限,因此,分组进行实验,每组2人,分别承担词法分析/目标代码生成以及语法/语义分析两部分中的一个,具体分工由组内协商进行,并且整个代码的链接工作由承担词法分析任务的同学完成。
可使用C、VC++等语言编程实现。
3实践报告的规范和要求
每位学生完成承担任务后写出格式规范的实验报告,包括封面、任务说明、程序设计时考虑的算法和方法、流程图、主要代码说明、运行结果分析等。
4L语言定义
程序定义:
〈程序〉→program〈标识符〉〈程序体〉.
〈程序体〉→〈变量说明〉〈复合句〉
变量定义:
〈变量说明〉→var〈变量定义〉|ε
〈变量定义〉→〈标识符表〉:
〈类型〉;|〈标识符表〉:
〈类型〉;〈变量定义〉
〈标识符表〉→〈标识符〉,〈标识符表〉|〈标识符〉
语句定义:
〈复合句〉→begin〈语句表〉end
〈语句表〉→〈执行句〉;〈语句表〉|〈执行句〉
〈执行句〉→〈简单句〉|〈结构句〉
〈简单句〉→〈赋值句〉
〈赋值句〉→〈变量〉:
=〈表达式〉
〈变量〉→〈标识符〉
〈结构句〉→〈复合句〉|〈if句〉|〈WHILE句〉
〈if句〉→if〈布尔表达式〉then〈执行句〉|if〈布尔表达式〉then〈执行句〉else〈执行句〉
〈while句〉→while〈布尔表达式〉do〈执行句〉
表达式定义:
〈表达式〉→〈算术表达式〉|〈布尔表达式〉
〈算术表达式〉→〈算术表达式〉+〈项〉|〈算术表达式〉-〈项〉|〈项〉
〈项〉→〈项〉*〈因子〉|〈项〉/〈因子〉|〈因子〉
〈因子〉→〈算术量〉|(〈算术表达式〉)
〈算术量〉→〈标识符〉|〈整数〉|〈实数〉
〈布尔表达式〉→〈布尔表达式〉or〈布尔项〉|〈布尔项〉
〈布尔项〉→〈布尔项〉and〈布尔因子〉|〈布尔因子〉
〈布尔因子〉→not〈布尔因子〉|〈布尔量〉
〈布尔量〉→〈布尔常数〉|〈标识符〉|(〈布尔表达式〉)|〈关系表达式〉
〈关系表达式〉→〈标识符〉〈关系运算符〉〈标识符〉
〈关系运算符〉→〈|〈=|=|〉=|〉|〈〉
类型定义:
〈类型名〉→integer|bool|real
单词定义:
〈标识符〉→〈字母〉|〈标识符〉〈字母〉|〈标识符〉〈数字〉
〈整数〉→〈数字〉|〈整数〉〈数字〉
〈实数〉→〈整数〉.|〈实数〉〈数字〉
〈布尔常数〉→true|false
字符定义:
〈字母〉→A│B│C│D│E│F│G│H│I│J│K│L│M│N│O│P│Q│R│S│T│
U│V│W│X│Y│Z│a│b│c│d│e│f│g│h│i│j│k│l│m│n│o│
p│q│r│s│t│u│v│w│x│y│z
〈数字〉→0│1│2│3│4│5│6│7│8│9
5源程序书写格式规定
(1)单词必须在一行内写完,即:
一个单词不能分两行写;
(2)源程序语句的书写采用自由格式,即:
一行可写多个语句,一个语句也可分多行写;
(3)源程序不含注释;
(4)语句以“;”结束,“end”前的一个语句的“;”不可以省略。
第二节词法分析
6目的
通过设计调试词法分析程序,实现从源程序中分出各种单词的方法;加深对课堂教学的理解;提高词法分析方法的实践能力;掌握词法分析器作为子程序以及一遍的处理过程。
7任务
(1)能对任何L语言源程序进行分析;
(2)采用问答方式输入源程序文件名,然后进行词法分析;
(3)分割单词并转换成机内表示形式,形成token文件(单词序列)、符号表文件;
(4)删除空格等无用符号;
(5)错误处理
●给出的错误信息包括:
总的出错个数,每个错误所在行号,错误编号及说明;
●只处理以下两种错误,其它可不必考虑
1.非法字符:
删除,即,不写入token文件
2.错误单词
a)包括三种形式:
i.数字开头的数字、字母串,如:
3a56
ii.实数中出现两个小数点,如:
3.14.15
iii.实数的小数部分出现字母,如:
5.26B78
b)处理方式:
截去后面出错部分,使其成为一个正确单词(即:
常数)。
如:
3a56转换为3,3.14.15转换为3.14,5.26B78转换为5.26
8数据结构
8.1输入
L源程序,为文本文件。
8.2输出
一个单词序列文件(即:
token文件)和一个符号表文件,并输出错误信息。
(1)token文件结构
typedefstructtoken
{
intlabel;//单词序号
charname[30];//单词本身
intcode;//单词的机内码
intaddr;//地址,单词为保留字时为-1,为标识符或常数时为大于0的数值,即在符号表中的入口地址。
}token;
单词的机内码表示:
单词
编码
单词
编码
单词
编码
单词
编码
and
1
or
11
(
21
:
=
31
begin
2
program
12
)
22
=
32
bool
3
real
13
+
23
<=
33
do
4
then
14
-
24
<
34
else
5
true
15
*
25
<>
35
end
6
var
16
/
26
>
36
false
7
while
17
.
27
>=
37
if
8
标识符
18
,
28
integer
9
整数
19
:
29
not
10
实数
20
;
30
(2)符号表文件结构
符号表用来存放L语言源程序中出现的标识符和常数,文件结构如下:
typedefstructsymble
{
intnumber;//序号
inttype;//类型
charname[30];//名字
}symble;
9词法分析程序流程图
第三节语法/语义分析
10目的
通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。
11任务
在词法分析程序产生的token文件、符号表文件基础上,完成语法和语义分析,产生相应的中间代码——四元式序列。
在此,可把语法/语义分析作为独立的一遍进行处理。
采用如下四元式:
操作码助记符
四元式
意义
:
=
(51,a,0,r)
r←a
+
(43,a,b,r)
r←a+b
-
(45,a,b,r)
r←a-b
*
(41,a,b,r)
r←a*b
/
(48,a,b,r)
r←b/a
j<
(53,a,b,n)
若a
j<=
(54,a,b,n)
若a<=b转至第n个四元式
j>
(57,a,b,n)
若a>b转至第n个四元式
j>=
(58,a,b,n)
若a>=b转至第n个四元式
j=
(56,a,b,n)
若a=b转至第n个四元式
j
(52,0,0,n)
转至第n个四元式
j<>
(55,a,b,n)
若a<>b转至第n个四元式
12数据结构
12.1输入
token文件、符号表文件,其数据结构与词法分析产生的文件相同。
12.2输出
●四元式序列文件,其纪录结构如下:
typedefstructequ
{
intop;//四元式操作码
intop1;//操作数在符号表中的入口地址
intop2;//操作数在符号表中的入口地址
intresult;//结果变量在符号表中的入口地址
}equ;
●程序中可用数组Equ存放四元式序列,定义为:
equEqu[EQU_LEN]
●可用变量intLineOfEqu做指针,指向下一个即将产生的四元式
●符号表文件的结构与输入相同,语法分析中对于符号表不做操作,只是在文件头部增加一个记录变量多少的数据。
13程序结构说明
为方便编程,将语言文法整理如下:
L→S|S;L
S→id:
=E
S→ifBthenS
S→ifBthenSelseS
S→whileBdoS
S→beginLend
变量说明语句的文法:
S→varD|ε
D→L:
K;|L:
K;D
L→i,L|i
K→integer|bool|real
其中,B表示布尔表达式,E表示算术表达式
可采用递归下降分析法或其它方法进行语法分析。
语法/语义分析程序可划分为三个模块,结构如下:
parser为主程序模块,Declear为说明语句分析模块,L_begin为复合语句分析模块。
其中L_begin结构图如下:
经常使用的过程和函数:
●gen(intop,inta,intb,intr):
生成一个四元式
●NewTemp():
产生一个临时变量,返回其在符号表中的入口地址
●BackPatch(intaddr,intaddr2):
回填函数,完成四元式转移目标的回填
第四节目标代码生成
14目的
实践目标代码的生成方法。
15任务
编写一个目标代码生成程序,将L语言的中间代码程序翻译为目标代码程序(汇编语言程序),如下图:
目标机说明:
●以8086微处理机为目标机,生成8086汇编指令
●8086是16位微处理器,数据总线为16位,地址总线为20位,可寻址1MB的空间
●8086有8个16位通用寄存器和一个标志寄存器。
这8个寄存器AX-DI都可以用作累加器。
其中,BX和BP(基地址指针)寄存器通常用于指定数据区的基址,称为基址寄存器,SI和DI大多用来表示相对基址的偏移量,称为变址寄存器
●8086的地址空间是分段的,每段64KB
●简单起见,本实验不涉及段间寻址,数据与代码都放在一个段内
●实验中选用以下寻址功能,圆括号表示取其内容:
⏹寄存器寻址:
MOVAX,BX;
功能:
AX←(BX)
⏹直接寻址:
MOVAX,DATA;
功能:
AX←(DATA)
●常用指令:
⏹传送指令:
r表示寄存器,m表示内存单元
MOVr,r/mr←(r/m),r/m表示r或m
MOVr/m,rr/m←(r)
MOVr/m,immr/m←imm,imm是立即数
⏹运算指令:
包括ADD,SUB,MUL,DIV,CMP等。
下面以ADD为例说明其用法:
ADDr,r/mr←(r)+(r/m)
ADDr/m,r/immr/m←(r/m)+(r)或imm
⏹CMP只影响标志位,不影响操作数的大小
⏹转移指令:
Z是标志位,S是符号位,O是溢出位
指令码
意义
条件
JZ,JE
结果为0或相等则转
Z=1,(A)=(B)
JNZ,JNE
结果不为0或不相等则转
Z=0,(A)≠(B)
JNL,JGE
大于等于转
(S∨O)=0,(A)≥(B)
JL,JNGE
小于转
(S∨O)=1,(A)<(B)
JG,JNLE
大于转
(S∨O∨Z)=0,(A)>(B)
JMP
无条件转移
16数据结构
16.1输入
四元式序列文件和符号表文件,其结构与语法/语义分析程序的输出一致。
16.2输出
一个汇编代码文件,并无特殊数据结构。
17程序参考结构:
将中间代码程序(四元式序列)翻译成汇编程序可按以下步骤进行:
(1)划分基本块
(2)对每个基本块生成基本块的目标代码
为了划分和记录基本块,对四元式结构作以下修改:
typedefstructGenStruct
{
intlabel;
charop[4];
intcode;
intaddr1;
intaddr2;
intresult;
intout_port;//记录该四元式是否为一个基本块的入口,是则为1,否则为0。
}GenStruct;
18寄存器分配策略
主要采用四个通用寄存器:
ax,bx,cx,dx,其中,ax,cx的作用固定,ax用作累加器,cx用作循环计数器,在四元式翻译时直接应用不再分配。
所以分配策略只用于bx与dx,具体算法如下:
if(bx未被使用或已分配给了变量a){
bx分配给变量a;
}
else{
if(dx未被使用或已分配给了变量a){
dx分配给变量a;
}
else{
其它策略;
}
}
注:
a为变量在符号表的入口地址。
19代码生成器的模块结构及说明
实现时,整个程序的四元式表和目标代码文件说明为全局数据。
调用划分基本块模块之后,返回新的四元式序列(带入口标记)。
先根据基本块的入口,再查找下一入口,两个入口之间就是该基本块。