编译原理课 程 设 计 报 告.docx
《编译原理课 程 设 计 报 告.docx》由会员分享,可在线阅读,更多相关《编译原理课 程 设 计 报 告.docx(16页珍藏版)》请在冰豆网上搜索。
编译原理课程设计报告
课程设计报告
设计题目:
一个简单文法的编译器前端的设计与实现
班级:
物联网1303班
组长学号:
********
组长姓名:
方俊超
指导教师:
肖桐
设计时间:
2014年12月
设计分工
组长学号及姓名:
********方俊超
分工:
语法分析器设计实现
组员1学号及姓名:
********程国鹏
分工:
中间代码生成
组员2学号及姓名:
********郝萌萌
分工:
扫描器设计实现
摘要
本次课程设计主要是完成了编译前端的工作,一个编译程序前端的工作过程一般可以划分为四个阶段:
词法分析、语法分析、语义分析与中间代码生成。
每个阶段都是从上一个阶段得到结果,对他进行分析,并且根据一些外部环境(例如符号表等)得到最终的输出结果。
要构造一个编译程序,可以按照这样的阶段来分别构造,最后来连调。
本次课设的词法分析主要完成两个任务,识别单词和翻译单词。
根据用户输入的源程序,有限自动机所识别出的对象完成从单词串到单词的TOKEN串的翻译。
语法分析和中间代码主要采用递归下降子程序法。
实现了语法的正确分析,最终生成了四元式序列。
关键字:
编译原理,词法分析,语法分析,中间代码生成
摘要
1.概述
2.课程设计任务及要求
2.1设计任务
2.2设计要求
3.算法及数据结构
3.1算法的总体思想(流程)
3.2词法分析模块
3.2.1功能
3.2.2数据结构
3.2.3算法
3.3语法分析模块模块
3.3.1功能
3.3.2数据结构
3.3.3算法
3.4目标代码生成模块
3.4.1功能
3.4.2数据结构
3.4.3算法
4.程序设计与实现
4.1程序流程图
4.2程序说明
4.3实验结果
5.结论
6.参考文献。
7.收获、体会和建议。
1.概要
本次课程设计主要是完成了编译前端的工作,一个编译程序前端的工作过程一般可以划分为四个阶段:
词法分析、语法分析、语义分析与中间代码生成。
每个阶段都是从上一个阶段得到结果,对他进行分析,并且根据一些外部环境(例如符号表等)得到最终的输出结果。
要构造一个编译程序,可以按照这样的阶段来分别构造,最后来连调。
本次课设的词法分析主要完成两个任务,识别单词和翻译单词。
根据用户输入的源程序,有限自动机所识别出的对象完成从单词串到单词的TOKEN串的翻译。
语法分析和中间代码主要采用递归下降子程序法。
实现了语法的正确分析,最终生成了四元式序列。
2.课程设计任务及要求
2.1设计任务
编译原理课程兼有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,在系统软件中占有十分重要的地位。
编译原理课程设计是本课程重要的综合实践教学环节,是对平时实验的一个补充。
通过编译器相关子系统的设计,使学生能够更好地掌握编译原理的基本理论和编译程序构造的基本方法和技巧,融会贯通本课程所学专业理论知识;培养学生独立分析问题、解决问题的能力,以及系统软件设计的能力;培养学生的创新能力及团队协作精神。
在下列内容中任选其一:
1、一个简单文法的编译器前端的设计与实现。
2、一个简单文法的编译器后端的设计与实现。
3、一个简单文法的编译器的设计与实现。
。
4、自选一个感兴趣的与编译原理有关的问题加以实现,要求难度相当。
2.2设计要求
1、在深入理解编译原理基本原理的基础上,对于选定的题目,以小组为单位,先确定设计方案;
2、设计系统的数据结构和程序结构,设计每个模块的处理流程。
要求设计合理;
3、编程序实现系统,要求实现可视化的运行界面,界面应清楚地反映出系统的运行结果;
4、确定测试方案,选择测试用例,对系统进行测试;
5、运行系统并要通过验收,讲解运行结果,说明系统的特色和创新之处,并回答指导教师的提问;
6、提交课程设计报告。
3.算法及数据结构
3.1算法的总体思想(流程)
1、词法分析
(1)扫描器
作为独立一遍的扫描器
源程序TOKEN序列
(字符串)(单词串)
(2)自动机
其中:
ℓ(字母)d(数字)
?
(空格、换符、回车),需要滤掉
(泛指单词的后继符)
.....(表示省略了其他界符的处理)
(3)关键字表
单词
编码
program
3
var
4
integer
5
begin
6
if
7
else
8
do
9
while
10
end
11
(4)界符表
界符
编码
,
13
:
14
;
15
:
=
16
(
17
>
18
)
19
=
20
+
21
*
22
-
23
/
24
<
25
标识符用编码1表示,常数用编码2表示
2、语法分析
3、中间代码生成
3.2词法分析模块
3.2.1功能
词法分析模块主要是在源程序中切出单词,生成Token序列,为之后语法分析、语义分析做准备。
即
(1)识别单词
——从用户的源程序中把单词分离出来;
(2)翻译单词
——把单词转换成机内表示,便于后续处理。
3.2.2数据结构
charch;//当前字符
charstrToken[];//当前单词
char*keywords[]
={“program”,“procedure”,“begin”,……};
//关键字表、界符表
charID[][];//符号表
intCons[];//常数表
structTokenType
{intcode,value;}
structTokenTypeToken[];//Token数组
3.2.3算法
Step1:
初始化;
Step2:
滤除空格,读取第一个非空字符到ch;
Step3:
if(ch是一个字母)
Step4:
处理关键字或标识符;
Step5:
elseif(ch是一个数字)
Step6:
处理常数;
else
Step7:
处理界符或错误处理;
3.3语法分析模块
3.3.1功能
3.3.2数据结构
3.3.3算法
3.4目标代码生成模块
3.4.1功能
3.4.2数据结构
3.4.3算法
4.程序设计与实现
4.1程序流程图
4.2程序说明
(1)词法分析(扫描器)
#include
#include
#include
#include
#include
usingnamespacestd;
char*kt[9]={"program","var","integer","begin","if","else","do","while","end"},TOKEN[120],ch;//kt关键字
char*pt[13]={",",":
",";",":
=","(",">",")","=","+","*","-","/","<"};//pt界符
typedefstruct//存储标识符
{
charit[100];
}IT;
ITit[100];//it标识符
typedefstruct//存储常数
{
charct[100];//ct常数
}CT;
CTct[100];
intn,L;//n表示标识符的最后一个位置
//L表示常数的最后一个位置
intsearch(char*TOKEN){//关键字匹配函数
inta,b;
for(b=0;b<=9;b++){
if((a=strcmp(TOKEN,kt[b]))==0)
returnb+4;
}
return0;
}
intsearchit(char*TOKEN){//标识符匹配函数
inta,b;
for(b=0;bif((a=strcmp(TOKEN,it[b].it))==0)
returnb;
}
return-1;
}
intsearchnum(char*TOKEN){
inta,b;//常数匹配函数
for(b=0;b{
if((a=strcmp(TOKEN,ct[b].ct))==0)
returnb;
}
return-1;
}
voidout(char*TOKEN,intin){//输出函数
cout<<"("<}
voidscanner(FILE*fp){//扫描函数
charTOKEN[100]={'\0'};
charch;
inti,c,w,v;
ch=fgetc(fp);//获取字符,指针fp并自动指向下一个字符
if(isalpha(ch)){//判断该字符是否是字母
TOKEN[0]=ch;
ch=fgetc(fp);
i=1;
while(isalnum(ch)){//判断该字符是否是字母或数字
TOKEN[i]=ch;
i++;
ch=fgetc(fp);
}
TOKEN[i]='\0';
c=search(TOKEN);
fseek(fp,-1,1);//从当前位置开始回退一个字符
if(c==0)
{v=searchit(TOKEN);
if(v==-1)
{strcpy(it[n].it,TOKEN);
n++;
out(TOKEN,1);
}
elseout(TOKEN,1);
}//输出标识符
elseout(TOKEN,c);//输出关键字
}
elseif(isdigit(ch)){//判断是否是数字
TOKEN[0]=ch;
ch=fgetc(fp);
i=1;
while(isdigit(ch)){
TOKEN[i]=ch;
i++;
ch=fgetc(fp);
}
if(ch=='.')//判断是否是小数
{TOKEN[i]=ch;
i++;
ch=fgetc(fp);
while(isdigit(ch)){
TOKEN[i]=ch;
i++;
ch=fgetc(fp);}
}
else//不是小数
{TOKEN[i]='\0';
fseek(fp,-1,1);
w=searchnum(TOKEN);
if(w==-1)
{strcpy(ct[L].ct,TOKEN);
L++;
out(TOKEN,2);}
elseout(TOKEN,3);}
}
else//不是数字也不是字符
{
TOKEN[0]=ch;
switch(ch){
case',':
{out(TOKEN,13);break;}
case':
':
{out(TOKEN,14);break;}
case';':
{out(TOKEN,15);break;}
case':
=':
{out(TOKEN,16);break;}
case'(':
{out(TOKEN,17);break;}
case'>':
{out(TOKEN,18);break;}
case')':
{out(TOKEN,19);break;}
case'=':
{out(TOKEN,20);break;}
case'+':
{out(TOKEN,21);break;}
case'*':
{out(TOKEN,22);break;}
case'-':
{out(TOKEN,23);break;}
case'/':
{out(TOKEN,24);break;}
case'<':
{out(TOKEN,25);break;}
}
}
}
intmain()//主函数
{
FILE*fp;
if((fp=fopen("E:
\\hmm\\source.txt","r"))==NULL){
fprintf(stderr,"erroropening.\n");
exit
(1);
}
cout<<"关键字:
";//识别关键字
for(intj=0;j<9;j++){
cout<}
cout<cout<<"界符:
";//识别界符
for(inti=0;i<13;i++){
cout<}
cout<cout<<"标识符:
";//识别标识符
for(intm=0;mcout<}
cout<cout<<"常数:
";//识别常数
for(intk=0;kcout<}
cout<cout<<"扫描结果:
"<do{
ch=fgetc(fp);
if(ch=='#')
break;
if(ch=='')
scanner(fp);
else{
fseek(fp,-1,1);
scanner(fp);
}
}while(ch!
='#');
return0;
}
(2)语法分析
(3)中间代码生成
4.3实验结果
(1)词法分析(扫描器)
(2)语法分析
(3)中间代码生成
5.结论
6.参考文献
1、陈火旺.《程序设计语言编译原理》(第3版).北京:
国防工业出版社.2000.
2、美AlfredV.AhoRaviSethiJeffreyD.Ullman著.李建中,姜守旭译.《编译原理》.北京:
机械工业出版社.2003.
3、美KennethC.Louden著.冯博琴等译.《编译原理及实践》.北京:
机械工业出版社.2002.
4、金成植著.《编译程序构造原理和实现技术》.北京:
高等教育出版社.2002.
7.收获、体会和建议
郝萌萌:
经过这两周的编译原理课程设计,收获很多。
书本上学到的知识有限,需要我们自己理解并用到实践中去。
课设中在写代码阶段受到了很大的阻碍,由于对C++不理解,只能从头到尾查资料借图书,一点一点的理解并写出适合扫描器的代码,最后还需要调试运行。
在应用中,我对编译原理也有了进一步的理解和认识,对基本知识也掌握了很多。
总的来说,通过这次课程设计,还算是小有成果,组员之间互帮互助,共同进步,对以后的学习也奠定了基础。