编译原理实验报告.docx
- 文档编号:23791760
- 上传时间:2023-05-20
- 格式:DOCX
- 页数:36
- 大小:287.82KB
编译原理实验报告.docx
《编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告.docx(36页珍藏版)》请在冰豆网上搜索。
编译原理实验报告
编译原理实验报告
姓名:
学号:
班级:
学院:
南昌大学信息工程学院计算机系
2014年6月
实验一………………………………………………………3
实验二………………………………………………………8
实验三………………………………………………………15
实验1词法分析程序的设计
学生姓名:
学号:
专业班级:
实验类型:
□验证□综合□设计□创新实验日期:
实验成绩:
一、实验目的
掌握计算机语言的词法分析程序的开发方法。
二、实验内容
编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。
三、实验要求
1、根据以下的正规式,编制正规文法,画出状态图;
标识符<字母>(<字母>|<数字字符>)*
十进制整数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)(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)*
运算符和界符+-*/><=<=>=();{}
关键字mainifthenelsewhiledoint(可根据需要添加)
2、根据状态图,设计词法分析函数intscan(),完成以下功能:
1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词,
2)以二元式形式输出单词<单词种类,单词属性>
其中单词种类用整数表示:
0:
标识符
1:
十进制整数
2:
八进制整数
3:
十六进制整数
运算符和界符,关键字采用一字一符,不编码
其中单词属性表示如下:
标识符,整数由于采用一类一符,属性用单词表示
运算符和界符,关键字采用一字一符,属性为空
3、编写测试程序,反复调用函数scan(),输出单词种别和属性。
四、实验环境
PC微机
DOS操作系统或Windows操作系统
TurboC程序集成环境或VisualC++程序集成环境
五、实验步骤
1.根据正规式,画出状态转换图;
2.根据状态图,设计词法分析算法;
3.采用C语言,设计函数scan(),实现该算法;
4.编制测试程序(主函数main);
代码如下:
#include
#include
#include
#defineSYMBOL_CODE0
//标识符编码0
#defineNUM_CODE1
//数字编码1
//可识别的关键字
charkeywordstab[8][30]=
{{"main"},{"if"},{"then"},{"else"},{"int"},{"return"},{"void"},{"while"}};
charch;//接受字符
charname[30]={""};
FILE*sourceFile;//源文件
FILE*outputFile;//输出文件
voidisNumber();
voidisOthers();
voidisKeyword();
voidoutput_keyword()
{
printf("关键字:
<%s,%s>\n",name,"-");
}
voidoutput_symbol()
{
printf("标识符:
<%s,%s>\n","0",name);
}
voidoutput_number()
{
printf("数字:
<%s,%s>\n","1",name);
}
voidoutput_others()
{
printf("其他:
<%s,%s>\n",name,"-");
}
//================================voidscan()
{
sourceFile=fopen("program.txt","r");//以读取方式打开源文件
if(sourceFile==NULL)
{
printf("fileopenerror\n");
exit(0);
}
outputFile=fopen("output.txt","w");//以写方式打开输出文件
if(outputFile==NULL)
{
printf("fileopenerror\n");
exit(0);
}
ch=fgetc(sourceFile);//读取字符
while(ch!
=EOF)
{//标识符以字母或下划线开头
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||ch=='_')
isKeyword();
if(ch>='0'&&ch<='9')
isNumber();
else
isOthers();
}
fclose(sourceFile);
fclose(outputFile);
}
//============================
voidisKeyword()
{
inti=0,j=0,k=0;
intflag=0;
for(k=0;k<30;k++)
name[k]='\0';//初始化变量名
while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||ch=='_'||(ch>'0'&&ch<'9'))
{
name[i++]=ch;//把标识符名字存入数组
ch=fgetc(sourceFile);//读取下一个字符
}
for(i=0;i<8;i++)
{
for(j=0;j<30;j++)
{//判断是否与关键字匹配
if(name[j]==keywordstab[i][j])
flag=0;
else
{//如果与当前关键字不匹配则跳出内循环继续与下一个关键字匹配
flag=1;break;
}
}
if(flag==0)//如果是关键字则跳出外循环
break;
}
if(flag==0)//是关键字
{
output_keyword();//输出关键字(限于篇幅输出函数没有放上来)
}else//不是关键字
{
output_symbol();//输出标识符
}
}
//============================
voidisNumber()
{
inti=0;
for(i=0;i<30;i++)
name[i]='\0';//初始化变量名
i=0;
while(ch>='0'&&ch<='9')
{
name[i++]=ch;
ch=fgetc(sourceFile);
}
output_number();
}
//============================
voidisOthers()
{
charch1;
inti;
for(i=0;i<30;i++)
name[i]='\0';
switch(ch)
{
case'+':
case'-':
case'*':
case'/':
case';':
case'(':
case')':
case'{':
case'}':
case'[':
case']':
name[0]=ch;
ch=fgetc(sourceFile);
output_others();break;
case'<':
case'>':
case'=':
{
ch1=fgetc(sourceFile);
if(ch1=='=')
{
name[0]=ch;
name[1]='=';
ch=fgetc(sourceFile);//读取下一个字符
output_others();break;
}else
{
name[0]=ch;
output_others();
ch=ch1;break;
}
}
case'':
case'10':
//换行符
ch=fgetc(sourceFile);
break;
default:
ch=fgetc(sourceFile);break;
}
}
//============================
voidmain()
{
scan();
}
5、调试程序:
检查输出结果是否正确。
六、思考题
1、词法分析能否采用空格来区分单词?
答:
不能。
程序中分割单词的不仅仅是空格,还可以是+,-,*,/,>,<,(,……等运算符或界定符。
2、程序设计中哪些环节影响词法分析的效率?
如何提高效率?
答:
例如在判断是否为关键字时,方法是把单词全部读取并存放在一个字符数组后再逐个与关键字表匹配,这样做可能效率比较低,若能在读取的同时判断可能会提高效率。
实验二语法分析程序的设计
(1)
学生姓名:
学号:
专业班级:
实验类型:
□验证□综合□设计□创新实验日期:
实验成绩:
一、实验目的
通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析中预测分析方法。
二、实验内容
设计一个文法的预测分析程序,判断特定表达式的正确性。
三、实验要求
1、给出文法如下:
G[E]
E->T|E+T;
T->F|T*F;
F->i|(E);
2、根据该文法构造相应的LL
(1)文法及LL
(1)分析表,并为该文法设计预测分析程序,利用C语言或C++语言或Java语言实现;
3、利用预测分析程序完成下列功能:
1)手工将测试的表达式写入文本文件,每个表达式写一行,用“;”表示结束;
2)读入文本文件中的表达式;
3)调用实验一中的词法分析程序搜索单词;
4)把单词送入预测分析程序,判断表达式是否正确(是否是给出文法的语言),若错误,应给出错误信息;
5)完成上述功能,有余力的同学可以进一步完成通过程序实现对非LL
(1)文法到LL
(1)文法的自动转换(见实验二附加资料1)。
四、实验环境
PC微机
Windows操作系统
VisualC++程序集成环境
五、实验步骤
1.分析文法,将给出的文法转化为LL
(1)文法;
G[E]
E->T|E+T;
T->F|T*F;
F->i|(E);
对应的LL
(1)文法为:
E->TE1
E1->+TE1|Ɛ;
T->FT1;
T1->*FT1|Ɛ;
F->i|(E);
2.构造该文法中非终结符的FIRST集和FOLLOW集:
FIRST(E)={(,i}FOLLOW(E)={),#}
FIRST(E1)={+,Ɛ}FOLLOW(E1)={),#}
FIRST(T)={(,i}FOLLOW(T)={+,),#}
FIRST(T1)={*,Ɛ}FOLLOW(T1)={+,),#}
FIRST(F)={(,i}FOLLOW(F)={*,+,),#}
3.构造预测分析表:
i
+
*
(
)
#
E
E->TE1
E->TE1
E1
E1->+TE1
E1->Ɛ
E1->Ɛ
T
T->FT1
T->FT1
T1
T1->Ɛ
T1->*FT1
T1->Ɛ
T1->Ɛ
F
F->i
F->(E)
注:
在程序中用P代替E1,Q代替T1。
4.学习预测分析程序的结构,设计合理的预测分析程序;
4.编写测试程序,包括表达式的读入和结果的输出;
FILE*inputFile;//输入文件
FILE*outputFile;//输出文件
charcurrentStr[10];//用来存放输入的字符串
charcurrentChar;//当前读取的字符
chartabData[5];//从预测分析表中匹配的产生式右部
charstatement[50];//用于存放读取的语句
intindex=0;
intfinish=0;
intendFlag=0;//文件结尾
interrorFlag=0;//语法错误标志
intendOfStamnt=0;//用于判断是否达到语句结尾
//预测分析表:
@表示错误,K表示空串
charE[10][5]={"E","iTP","+@","*@","(TP",")@","#@"};
charE1[10][5]={"P","i@","++TP","*@","(@",")K","#K"};
charT[10][5]={"T","iFQ","+@","*@","(FQ",")@","#@"};
charT1[10][5]={"Q","i@","+K","**FQ","(@",")K","#K"};
charF[10][5]={"F","ii","+@","*@","((E)",")@","#@"};
structStack//用来模拟符号栈
{
inttop;//栈顶指针
charstrName[MAX_STACK];//栈中存放的符号串
}stack;
//================================
voidcheckOneStatement()
{
charchtop;
errorFlag=0;
finish=0;
stack.top=0;
tabData[0]='\0';
push('#');
push('E');
currentChar=readNext();//读取字符
while(!
finish)
{
showStack();
chtop=pop();//栈顶字符
printf("char=%c\t",currentChar);
printf("tabData=%s\n",tabData);
if(chtop==currentChar)
{
if(chtop=='#')
{
finish=1;//finish
printf("正确!
\n");
break;
}
currentChar=readNext();
}
elseif(chtop=='#')
{
error();
exit(0);
}
else
{
inti;
match(chtop,currentChar);
if(tabData[1]=='@')
{error();
printf("错误:
%c\n",currentChar);
finish=1;
}else
{
for(i=0;tabData[i]!
='\0';i++);
i--;
while(i>0)
{
if(tabData[i--]!
='K')
push(tabData[i+1]);
}
}
}
}//endwhile(!
finish)
}
//================================
voidmain()
{
init();
while(!
endFlag)
{
index=0;
checkOneStatement();//对一条语句做语法检查
if(errorFlag)
{
printf("语句:
%s错误!
\n",statement);
fprintf(outputFile,"语句:
%s错误!
\n",statement);
}elseif(!
endFlag)
{
printf("语句:
%s合法!
\n",statement);
fprintf(outputFile,"语句:
%s合法!
\n",statement);
}
}
fclose(inputFile);
fclose(outputFile);
exit(0);
}
六、测试数据
输入数据:
编辑一个文本文文件expression.txt,在文件中输入如下内容:
10;
1+2;
(1+2)*3+(5+6*7);
((1+2)*3+4;
1+2+3+(*4+5);
(a+b)*(c+d);
((ab3+de4)**5)+1;
先调用实验一的词法分析程序扫描输入语句输出结果如下:
图:
输入文件
然后调用本次实验的语法分析程序对词法分析的结果进行处理,结果如下:
输出文件:
七、实验总结
在本次实验过程中,通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析中预测分析方法。
将书本上的理论知识运用到实验中,加深、巩固了对语法制导翻译原理的理解。
八、思考题
如果使用递归下降分析法来进行语法分析,为什么文法必须先转化为LL
(1)文法再做递归下降分析?
答:
为了消除左递归和消除回溯。
实验3语法分析程序的设计
(2)
学生姓名:
学号:
专业班级:
实验类型:
□验证□综合□设计□创新实验日期:
实验成绩:
一、实验目的
通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析中算符优先分析方法,并加深对语法制导翻译原理的理解。
二、实验内容
设计一个文法的算符优先分析程序,判断特定表达式的正确性,并结合语法制导翻译原理,构造相应语义规则,将语法分析所识别的正确的表达式翻译计算出结果。
三、实验要求
1、给出文法如下:
G[E]
E->T|E+T;
T->F|T*F;
F->i|(E);
可以构造算符优先表如下:
+
*
(
)
i
+
*
(
)
i
2、计算机中表示上述优先关系,优先关系的机内存放方式有两种1)直接存放,2)为优先关系建立优先函数,这里选择直接存放;
1、给出算符优先分析算法如下:
k:
=1;S[k]:
=‘#’;
REPEAT
把下一个输入符号读进a中;
IFS[k]∈VTTHENj:
=kELSEj:
=k-1;
WHILES[j]aDO
BEGIN
REPEAT
Q:
=S[j];
IFS[j-1]∈VTTHENj:
=j-1ELSEj:
=j-2
UNTILS[j]Q
把S[j+1]…S[k]归约为某个N;
k:
=j+1;
S[k]:
=N;
ENDOFWHILE;
IFS[j]aORS[j]aTHEN
BEGIN
k:
=k+1;S[k]:
=a
END
ELSEERROR
UNTILa=‘#’
4、根据给出算法,利用适当的数据结构实现算符优先分析程序;
5、利用算符优先分析程序完成下列功能:
1)手工将测试的表达式写入文本文件,每个表达式写一行,用“;”表示结束;
2)读入文本文件中的表达式;
3)调用实验2中的词法分析程序搜索单词;
4)把单词送入算法优先分析程序,判断表达式是否正确(是否是给出文法的语言),若错误,应给出错误信息;
5)完成上述功能,有余力的同学可以对正确的表达式计算出结果。
四、实验环境
PC微机
DOS操作系统或Windows操作系统
TurboC程序集成环境或VisualC++程序集成环境
五、实验步骤
1、分析文法中终结符号的优先关系;
2、存放优先关系或构造优先函数;
3、利用算符优先分析的算法编写分析程序;
4、写测试程序,包括表达式的读入和结果的输出;
#include"malloc.h"
#include
#include"stdio.h"
//#define_DEBUG_0//是否打印调试信息
//存储算符优先关系表,大于为1,小于为-1,等于为0,其它为2表示出错
inttable[6][6]={
{1,-1,-1,1,-1,1},
{1,1,-1,1,-1,1},
{-1,-1,-1,0,-1,2},
{1,1,2,1,2,1},
{1,1,2,1,2,1},
{-1,-1,-1,2,-1,0}};
charE[6][4]={"E+T","E+F","T+F","T+T","F+T","F+F"};
charF[4][4]={"(E)","(F)","(T)","i"};
charT[2][4]={"F*F","T*F"};
FILE*inputFile;//输入文件
FILE*outputFile;//输出文件
charcurrentStr[10];//用来存放输入的字符串
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 报告