编译技术课程设计江苏大学版本Word下载.docx
《编译技术课程设计江苏大学版本Word下载.docx》由会员分享,可在线阅读,更多相关《编译技术课程设计江苏大学版本Word下载.docx(20页珍藏版)》请在冰豆网上搜索。
(4)流程图…………………………………………………………………………14
五、程序运行结果…………………………………………………………………15
六、总结………………………………………………………………………………….18
一、目的
<
编译技术>
>
是理论与实践并重的课程,而其课程设计要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。
从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;
培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。
二、任务和要求
基本要求:
1.词法分析器产生下述小语言的单词序列
这个小语言的所有的单词符号,以及它们的种别编码和内码值如下表:
单词符号
种别编码
助记符
内码值
while
1
if
2
else
3
switch
4
case
5
标识符
6
id
符号表入口地址
常数
7
num
常数表入口地址
=
8
+
9
*
10
**
11
12
/
13
14
relop
MT
ME
LT
LE
==
EQ
!
UEQ
;
15
16
(
17
LB
)
RB
对于这个小语言,有几点重要的限制:
首先,所有的关键字(如if﹑while等)都是“保留字”。
所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。
例如,下面的写法是绝对禁止的:
if(5)=x
其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。
也就是说,对于关键字不专设对应的转换图。
但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。
当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。
再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。
例如,一个条件语句应写为
ifi>
0i=1;
而绝对不要写成
ifi>
0i=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.将中间代码翻译成汇编语言。
三、实验环境
开发环境:
VC++;
VisualStudio;
Java开发环境
语言:
C;
C++;
C#;
Java
说明:
课程设计可以使用任何一种语言工具,课程设计报告中请按照自己实际采用的开发工具及技术来写。
四、实现过程说明
1.词法分析器
(1)算法和数据结构描述
词法分析阶段的基本任务是从以字符串表示的源程序中识别出具有独立意义的单词符号。
通过DOS环境手动输入字符串序列(以’$’作为结束标志)作为带分析的源程序,调用词法扫描子程序将字符串以二元组的形式输出(若有不属于该语言单词符号出现,则进行出错处理),词法扫描子程序包括了对源程序的预处理(忽略、回车换行符等字符),以及对单词的识别和分类,以形成(单词种别,单词自身的值)形式的二元组。
具体思路如下:
首先建立关键字表,将关键字作为特殊标示符处理,把它们预先安排在char*keywords[13]中,将需要被识别出的关键字存入表中,当扫描程序识别出标识符时,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
在主函数中让用户输入要识别的符号串,然后将输入的符号串读入到program[500],遇$结束。
再依次扫描program[500]中的每一个符号,调用Scan()子函数分析每一个符号,再将分析的结果输出,也是遇$结束。
(2)函数说明
在Scan()子函数中,先全部初始化,然后读一个字符,分析它是什么类型:
a.如果是字母类型,则接着往下读,直到读到非字母的字符,存入words[10]中,依次对比关键字表中的元素,如果相同,则将flags[]置为相应的种别码,如果全都扫描后没发现相同的关键字,则为普通的标识符,返回主函数输出。
b.如果是数字类型,首先分析第一个符号,接着读下一个字符串,直到读到一个不是数字的字符串位置,每读一个数字字符,就将他们转化为相应的数字,使用辗转相乘法,每次都让number先自乘10,然后加上这个数字,这样就将字符串表示的数字转化成了相应的数,返回主函数输出。
c.如果是其他单词表的符号,则将他们的flags[]置为相应的种别码,并将字符存到words[]中返回主函数输出。
主要变量说明:
用words[10]存放构成单词符号的字符串,并且用于判断是否为关键字。
flags[500]存放单词符号的种别码。
Number存放整数值,words[]存放标识符,关键字或者其他符号。
cnt[num]按顺序存放读到的字符,为下面语义分析做准备。
Status用于判断是否为关键字,1是,0不是。
(3)流程图
2.语法分析器
(1)分析方法说明
本实验采用递归下降分析法,递归下降法又称递归子程序法。
在程序语言的语法定义中有许多采用递归定义。
我们在对它进行语法分析时,编制的处理程序也采取递归的方式,可使其结构简单易读。
但由于频繁地调用子程序大大地降低了分析速度。
其主要思想:
对每个非终结符按其产生式结构写出相应语法分析子程序。
因为文法递归相应子程序也递归,子程序的结构与产生式结构几乎一致。
所以称此种方法称为递归子程序法或递归下降法。
(2)文法
①消除左递归和回溯后改造的文法:
E→TE’
E’→+TE’|ε
T→FT’
T’→*FT’|ε
F→PF’
F’→^F|ε
②LL
(1)分析表:
i
)
^
#
E
E→TE’
E’
E’→+TE’
E’→ε
T
T→FT’
T’
T’→ε
T’→ε
F
F’
F’→ε
F’→^F
P
P→i
P→(E)
③递归子程序代码描述如下:
voide();
voide1();
voide2();
voidt();
voidt1();
voidt2();
voidf();
voidf1();
voidp();
voide()
{
cout<
"
E->
TE'
'
endl;
t();
e2();
}
voide1()
if(flags[temp]==9)
E'
->
+T"
temp++;
elseif(flags[temp]==12)
-T"
is_right=0;
voide2()
if(flags[temp]==9||flags[temp]==12){
cout<
e1();
e2();
}
elseif(flags[temp]!
=0||flags[temp]!
=18)
{
^"
return;
else
voidt()
T->
FT'
f();
t2();
voidt1()
if(flags[temp]==10)
cout<
T'
*F"
temp++;
f();
elseif(flags[temp]==13)
/F"
elseis_right=0;
voidt2()
if(flags[temp]==10||flags[temp]==13)
t1();
t2();
voidf()
F->
PF'