编译技术课程设计报告

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

编译技术课程设计
班级软件1001
学号
姓名
指导老师
2013年 6 月
目录
一、目的 (2)
二、任务及要求 (2)
三、实验环境 (4)
四、实现过程说明 (4)
1.词法分析器 (4)
(1)单词符号表 (4)
(2)数据结构 (4)
(3)函数说明 (5)
(4)流程图 (5)
2.语法分析器 (7)
(1)分析方法说明 (7)
(2)文法 (7)
(3)数据结构 (9)
(4)函数说明 (10)
3.中间代码生成器 (10)
(1)属性文法 (10)
(2)数据结构 (10)
(3)函数说明 (11)
(4)流程图 (11)
五、程序运行结果 (12)
六、总结 (19)
一、目的
<<编译技术>>是理论与实践并重的课程,而其课程设计要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。

从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。

二、任务及要求
基本要求:
1.词法分析器产生下述小语言的单词序列
这个小语言的所有的单词符号,以及它们的种别编码和内码值如下表:
对于这个小语言,有几点重要的限制:
首先,所有的关键字(如if﹑while等)都是“保留字”。

所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。

例如,下面的写法是绝对禁止的: if(5)=x
其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。

也就是说,对于关键字不专设对应的转换图。

但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。

当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。

再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。

例如,一个条件语句应写为 if i>0 i= 1;
而绝对不要写成
ifi>0 i=1;
因为对于后者,我们的分析器将无条件地将ifi看成一个标识符。

这个小语言的单词符号的状态转换图,如下图:
2.语法分析器能识别由加+ 乘* 乘方** 括号()操作数所组成的算术表达式,其文法如下:
E→E+T|T
T→T*F|F
F→P**F|P
P→(E)|i
使用的算法可以是:预测分析法;递归下降分析法;LR分析法等。

3.中间代码生成器产生上述算术表达式的中间代码(四元式序列)
较高要求:
1.扩充上述小语言的单词;
2.增加语法分析器的功能,能识别条件语句和循环语句等;
3.增加中间代码生成器的功能,能产生条件语句和循环语句等的中间代码(四元式序列)
4.报错基础上增加错误信息;
5.将中间代码翻译成汇编语言。

三、实验环境
开发环境:VisualStadio2010
语言:C++
四、实现过程说明
1.词法分析器
(1)单词符号表
/* 若对单词扩充需给出单词符号表 */
(2)数据结构
词法分析程序主要通过使用scaner()函数对用户输入的语句进行单词符号的分析,然后以(单词符号,种别编码)的二元式形式输出,在函数中使用到的表主要有如下:符号表:list1;//存放标示符
常数表:list2;//存放数字
/* 单词的二元式、符号表、常数表等 */
/* 若定义类,给出类图及说明 */
(3)函数说明
Scaner函数从左到右依次对输入的语句进行分析,每次读员工字符,分析它是什么类型:如果是字母类型,则接着往下读,如果是字母或数字,则把第一个和第二个字符连起来放在token数组中,将他们依次对比关键字表中的元素,如果相同,把sny中置相应的种别编码,如果不同,则字符为标示符,则将标示符放入list1表中;若读到数字,首先分析第一个符号,接着读下一个字符串,直到读到一个不是数字的字符串位置,每读一个数字字符,就将他们转化为相应的数字,使用辗转相乘法,每次都让number先自乘10,然后加上这个数字,这样就将字符串表示的数字转化成了相应的数,返回主函数输出,则将数字放入list2表中;如果是其他单词表的符号,则将他们的sny置为相应的种别码。

(4)流程图
主流程图
2.语法分析器
(1)分析方法说明
语法分析阶段的基本任务是将词法分析阶段产生的二元组作为输入,根据语言的语法规则,识别出各种语法成分,并判断该单词符号序列是否是该语言的一个句子。

程序采用的是递归下降分析法,这是一种自上而下的分析方法,文法的每个非终结符对应一个递归过程。

分析过程就是从文法开始符号出发执行一组递归过程,这样向下推导直到推出句子;或者从跟节点出发,自上而下输入串寻找一个最左匹配序列,建立一棵语法树。

/* 预测分析法;递归下降分析法;LR分析法 */
(2)文法
文法:
E→E+T|T
T→T*F|F
F→F-P|P**F|P
P→(E)|i
改造后的文法:
E→TE’
E’→+TE’
T→FT’
T’→*FF’
F→P**FF’
F→PF’
F’→-PF’
P→(E)
P→i
递归子程序:
void match(int t)
{
if(lookahead==t)
{
lookahead=nexttoken();
}
else
{
error1();
}
}
void E()
{
T();
E'();
}
void E'()
{
if(lookahead=='+')
{
match('+');
T();
E'();
}
}
void T()
{
F();
T'();
}
void T'()
{
if(lookahead=='*')
{
match('*');
F();
F'();
}
else error();
}
void F()
{
P();
if(lookahead=='*'){
if(lookahead=='*')
{
F();
F'();
}
}
else
F'();
}
void F'()
{
if(lookahead=='-')
{
P();
F'();
}
else error();
}
void P()
{
if(lookahead=='(')
{
match('(');
E();
if(lookahead==')')
match(')');
}
else if(lookahead=='i')
match('i');
else error();
}
(3)数据结构
语法分析是在词法分析的基础上加上判断是否符合语法规则的语句。

语法分析的基本任务是使用词法分析的结果,使用递归下降算法分析是否符合语法规则,如果符合,则输出“分析成功”,若果不符合,则输出“分析失败”。

S()函数:判断语句第一个标示符是否为关键字while或者if,即语句为while型或if型语句;
A()函数:判断是否有逻辑关系表达式,并调Op()和B()函数;
Op()函数:判断逻辑关系为&& 还是||;
B()函数:若右边产生式为一个大小判断语句,调用E()函数、relop()函数、E()函数;
relop()函数:识别是六种大小判断符号的哪一种;
E()函数:调用T()函数和E1()函数;
E1()函数:识别左边有+号的表达式,并调用T()函数和E1()函数,这里有递归调用;
T()函数:调用F()函数和T1()函数;
T1()函数:识别左边有*号的表达式,并调用F()函数和T1()函数,这里有递归调用;
F()函数:主要用来识别**运算的表达式,并调用P()函数;
P()函数:识别含终结i的产生式,识别含()的产生式;
error1()函数:输出语法分析错误;
3.中间代码生成器
(1)属性文法
产生式语义规则
S→E print(E.val)
E→E(1)+T E.val=E(1).val+T.val
E→T E.val=T.val
T→T(1)*F T.val=T(1).val
T→F T.val=F.val
F→F(1)-P F.val=F(1).val-P.val
F→P**F(1) F.val=P.val**F(1).val
F→P F.val=P.val
P→(E) P.val=E.val
P→i P.val=i.lexval
(2)数据结构
二位数组(第二维有四个区段,分别存放对应字符在符号表中的下标)
int e[20][4];
递归子程序:
S1()函数:语义分析主函数,主要用来分析是while型语句还是if型语句
A1()函数:
Op1()函数:
B1()函数:
Relop1()函数:
E2()函数:
T2()函数:
F1()函数:
P1()函数:
Error2()函数:
Scaner1()函数:扫描数组中存放的下一个字符;
Emit(a,b,c,d)函数:产生四元式;
Newtemp()函数:新建员工参数;
Merge(p1,p2)函数:把以p1,和p2为链首的两条链合并为以p2为首的链(返回链首值p2);
Backpatch(p,t)函数:把链首p所链接的每个四元式的第四区段都改写为地址t;
Show()函数:输入对应的四元式序列;
(4)流程图
五、程序运行结果
将关键字定义为标示符,报错;如 if=3;#
ifi>0 i=1;分析器将无条件地将ifi看成一个标识符。

能识别条件语句和循环语句,如if else和while,增加了新单词&&,能识别由加+ 乘* 乘方** 括号()操作数所组成的算术表达式,生成四元式序列;
如while(a>0&&b>0) if(x>y) m=m+m*2; else m=m**2;#
新加了单词||,
If(a>b||c>d) m=m+1; else m=m+2;#
报错基础上增加错误信息;If(x>0) m=m+1#
六、总结
本次课设的内容涵盖了词法分析、语法分析、语义分析、中间代码的生成和目标代码生成五个部分。

可以说涵盖了编译原理这学期所学的绝大部分内容。

没有平时认真学习、经验总结的前提,是无法胜任本次的课设的。

它也更巩固了我们平时所学的知识,加深我们对编译原理的认识。

编译原理是一门很抽象的学科,它的入门很难。

我也记得我在本书的第二章花了大量的时间自己看书学习才最终理解。

如果平时上课不好好听老师将,在临考前才抱佛脚是不可能考出好成绩的,而且,你还得花大量的时间。

虽然本次实验做完了,但我还是对某些东西认识很模糊。

在课上学习的是一些理论的知识,只有去实践了才能把知识变为自己的;在实践中不断发现问题,发现自己的不足,然后去解决问题,完善自己的不足,使自己对知识的把捉更加自信。

本次实验的代码因为之前做过俩次实验了,词法分析和语法分析都是之前的,而这次多出的语义分析我是参考了同学的,但自己也都理解了每个函数的意思。

比较遗憾自己没有把主要的函数编写出来,我想自己在编程方面还是有待好好的提高的。

老师不反对“拿来主义”,但必须自己要完全理解,不然做这个课设也就没有了意义,课设就是为了锻炼我们的编程能力,我想,个人的编程能力以后能在很大的程度上决定我们工作的薪酬。

所以在这个暑假也要好好的练练编程。

毕竟自己的短期目标还是要考研的,而考研的学校还是要求复试要上机的;而从长远来看,以后工作的头几年也就只能当个程序员之类的,没有很好的编程能力如何养家糊口。

最后在这里感谢任课老师对我们的教导。

注意:
1.课程设计报告着重说明个人所做工作、成果和体会,报告不得与他人雷同,否则影响成绩,严重者无成绩。

2.课程设计报告无须加入完整的程序源代码。

相关文档
最新文档