编译原理课程实验报告示例.docx
《编译原理课程实验报告示例.docx》由会员分享,可在线阅读,更多相关《编译原理课程实验报告示例.docx(46页珍藏版)》请在冰豆网上搜索。
![编译原理课程实验报告示例.docx](https://file1.bdocx.com/fileroot1/2022-11/16/fcce7be7-f7ba-4fb3-8f67-c1eb727d595d/fcce7be7-f7ba-4fb3-8f67-c1eb727d595d1.gif)
编译原理课程实验报告示例
1
完成日期:
2007-6-20
指导老师:
蒋宗礼
04070010张悦
编译原理实验报告
04070010张悦
2
<一>词法的正规式描述
标识符:
<字母>|(<字母>|<数字字符>)*(ε|_|.)(<字母>|<数字字符>)*
十进制数:
(0|(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*)(ε|.)(0|1|2|3|4|5|6|7|8|9)
五.系统实现
(一)词法分析器的实现
四.系统设计
完成整个系统,实现本个实验的要求,需要两个比较大的模块:
词法分析器和语法分析器。
词法分析器的功能是将输入的程序串分解成一个一个独立的单词,并且记录下每个单词的类型以及数值。
这里词法分析器的实现有两种方法:
调用一次词法分析器,返回一个词的类型以及数值,以此类推;还有一种方法是条用一次词法分析器将程序串的所有单词都分解出来并保存到一个地方(比如线形表)以便将来使用。
我采用的是前者,因为这样只需要对整个程序访问一遍
语法分析器的功能是将已经分解好的单词按照一定的规范(产生式)组合起来,由此来确定输入程序的意思。
我的设计是“语法分析器调用词法分析器”,当语法分析其分析进行不下去的时候调用词法分析器获取一个单词,继续进行分析。
而语义功能是镶嵌在语法分析其当中的,当语法分析器分析出用什么产生式的时候作相应的语义处理。
3.编写测试程序,反复调用函数scan(),输出单词种别和属性。
4.改写文法,构造语法分析程序,要求按照最左派生的顺序输出派生的产生式序列;
5.改写语法分析程序,构造三地址代码生成程序。
6.处理的源程序存放在文件中,它可以包含多个语句;
从键盘读入数据,分析出一个单词。
返回单词种别(用整数表示),返回单词属性(不同的属性可以放在不同的全局变量中)。
1)
2)
3)
三.实验要求
1.编制正规式以及正规文法,画出状态图;
2.根据状态图,设计词法分析函数intscan(),完成以下功能:
二.实验内容
1.编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。
2.用二维预约分析表,编制一个能够进行语法分析并生成派生的产生式序列的编译程序。
3.用递归子程序法,编制一个能够进行语法分析并生成三地址代码的微型编译程序。
一.实验目的
基本掌握计算机语言的词法分析程序的开发方法。
以及掌握计算机语言的语法分析程序设计与属性文法应用的实现方法。
锻炼自己的编程能力和逻辑思维能力,体会计算机编译器的奥妙之处
04070010张悦
3
<三>、状态图:
>->a|b|c|d|e|f|g|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
->(<字母>|<数字字符>)|ε
->(ε|_|.)
->(ε|.)
->(0|1|2|3|4|5|6|7)|ε
->(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)|ε
将状态合起来,得:
(0)-><1~9>
(1)|0(4)|<字母>(12)|<运算符和分隔符>(17)
(1)-><0~9>
(1)|.
(2)
(2)-><0~9>(3)(3)-><0~9>(3)
(4)->.
(2)|<1~7>(5)|0(13)|x(8)|X(8)(5)-><0~7>(5)|.(6)
(6)-><0~7>(7)(7)-><0~7>(7)
(8)-><1~9>(9)|(9)|0(14)(9)-><0~9>(9)|(9)|.(10)(10)-><0~9>(11)|(11)(11)-><0~9>(11)|(11)
(12)-><0~9>(12)|(12)|(12)|.(15)|_(15)(13)->.(6)
(14)->.(10)
(15)-><0~9>(16)|(16)|(16)(16)-><0~9>(16)|(16)|(16)
<
母
字
<二>、改变后的正规文法
<标识符>-><字母>
<十进制整数>-><数字字符><数字字符>
<八进制整数>->0
<十六进制整数>->0x
<运算符和分隔符>->+|-|*|/|>|<|=|(|)|;
<关键字>->if|then|else|while|do
(0|1|2|3|4|5|6|7|8|9)*
八进制数:
0(0|(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)*)(ε|.)(0|1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)*
十六进制数:
0x(0(|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*)(ε|.)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)*
运算符和分隔符:
+-*/<>=();
关键字:
ifthenelsewhiledo
04070010张悦
0~9
0~9
1
.
2
3
0~9
0~7
0~7
1~9
.
5
6
7
.
0~7
1~7
0
0
4
0
.
13
x|X
0~f
0~f
字母
8
1~f
9
.
10
0~f
11
12
分隔符
0
14
.
.|_
字母或数字
15
16
字母或数字
17
字母或数字
4
}
strcpy(node->type,"#");
strcpy(node->value,"_");
returnfalse;//表示文件结束
{
if(temp=='#')
读取一个字符到temp;
node=newCNode;
while
(1){
//返回的节点
//当前状态号
intstate=0;
intsi=0;//对于控制s的下标
//保留字符串
chars[100];
<五>、算法(伪码):
boolMyScan(FILE*fp,CNode*&node){
chartemp;//当前读取的字符
<四>、数据结构:
char*arrBao[5]={"if","then","else","do","while"};//保留字表
typedefstruct{
chartype[TYPE_MAX];
charvalue[VALUE_MAX];
}CNode;//词法分析的节点,保留分析出的token的种类和值
04070010张悦
5
;
添加当前字符
state=14;
;
state=9;
添加当前字符
if(temp为十六进制数)
continue;
if(temp为0)
else出错处理;returnfalse;
case8:
//状态8
returntrue;
保存为INT8;
if(temp为分隔符)
添加当前字符;continue;
添加当前字符;continue;
else出错处理;returnfalse;
case6:
//状态6
if(temp为0~7)state=7;
else出错处理;returnfalse;
case7:
//状态7
if(temp为0~7)state=7;
returntrue;
保存为INT8;
if(temp为分隔符)
if(temp为0~7)state=5;
state=6;
添加当前字符;continue;
添加当前字符;continue;
if(temp为小数点)
else出错处理;returnfalse;
case5:
//状态5
returntrue;
保存为INT10;
state=8;
if(temp为x或X)
if(temp为分隔符)
state=5;
state=13;
if(temp为1~7)
if(temp为0)
state=2;
添加当前字符;continue;
添加当前字符;continue;添加当前字符;continue;添加当前字符;continue;
if(temp为小数点)
else出错处理;returnfalse;
case4:
//状态4
returntrue;
保存为REAL10;
if(temp为分隔符)
添加当前字符;continue;
添加当前字符;continue;
else出错处理;returnfalse;
case2:
//状态2
if(temp为数字)state=3;
else出错处理;returnfalse;
case3:
//状态3
if(temp为数字)state=3;
保存为INT10;returntrue;
state=2;
if(temp为小数点)
if(temp为分隔符)
添加当前字符;continue;
添加当前字符;continue;
else出错处理;returnfalse;
case1:
//状态1
if(temp为数字)state=4;
和制表符
//忽略多个空格和回车
if(temp为空格或回车或tab)continue;
returntrue;
保存相应的分隔符到node;
state=4;
state=1;
state=12;
添加当前字符;continue;
添加当前字符;continue;
添加当前字符;continue;
switch(state){
case0:
//状态0if(temp为0)if(temp为1到9)if(temp为字母)if(temp为分隔符)
04070010张悦
6
添加当前字符;
state=16;
if(temp为数字或者字母)
case16:
//状态16
else出错处理;returnfalse;
returntrue;
else保存为IDN;
if(temp为分隔符)
if(为保留字)保存为保留字;returntrue;
continue;
state=16;
添加当前字符;
if(temp为数字或者字母)
//状态15
case15:
else出错处理;returnfalse;
保存为INT16;returntrue;
if(temp为分隔符)
添加当前字符;continue;
if(temp为.)state=10;
case14:
//状态14
else出错处理;returnfalse;
returntrue;
保存为INT8