编译原理词法分析实验含代码.doc
《编译原理词法分析实验含代码.doc》由会员分享,可在线阅读,更多相关《编译原理词法分析实验含代码.doc(8页珍藏版)》请在冰豆网上搜索。
计算机编译原理实验
班级:
计算机科学与技术113班
姓名:
学号:
南昌大学信息工程学院计算机系
实验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或C++语言,设计函数scan(),实现该算法;
4、编制测试程序(主函数main);
5、调试程序:
读入文本文件program.txt,运行程序得到输出结果result.txt,并检查输出结果是否正确。
六、测试数据
输入数据:
编辑一个文本文件program.txt,在文件中输入一段程序代码,如:
ifdata+92>0x3fthen
data=data+01;
else
data=data-01;
将输出结果存放在result.txt文件中,输出格式如下:
<0,data>
<+,->
<1,92>
<>,->
<3,3f>
<0,data>
<=,->
<0,data>
<+,->
<2,1>
<;,->
<0,data>
<=,->
<0,data>
<-,->
<2,->
<;,->
七、实验报告要求
实验报告应包括以下几个部分:
1、词法的正规式描述;
2、变换后的状态图;
3、词法分析程序的数据结构与算法。
【源程序】
#include
#include
usingnamespacestd;
#defineLENGTH5
charch='';
stringkey[5]={"if","then","else","while","do"};
intIskey(stringc){//关键字判断
inti;
for(i=0;iif(key[i].compare(c)==0)return1;
}
return0;
}
intIsLetter(charc){//判断是否为字母
if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A')))return1;
elsereturn0;
}
intIsLetter1(charc){//判断是否为a~f字母
if(((c<='f')&&(c>='a'))||((c<='F')&&(c>='A')))return1;
elsereturn0;
}
intIsNum(charc){//判断是否为数字
if(c>='0'&&c<='9')return1;
elsereturn0;
}
voidscan(FILE*fpin){
stringarr="";
while((ch=fgetc(fpin))!
=EOF)
{
arr="";
if(ch==''||ch=='\t'||ch=='\n'){}
elseif(IsLetter(ch)||ch=='_')
{
arr=arr+ch;
ch=fgetc(fpin);
while(IsLetter(ch)||IsNum(ch))
{
if((ch<='Z')&&(ch>='A'))ch=ch+32;
arr=arr+ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
if(Iskey(arr)){cout<<"<"<"<elsecout<<"<"<"< }
elseif(IsNum(ch))
{
intflag=0;
if(ch=='0')
{
arr=arr+ch;
ch=fgetc(fpin);
if(ch>='0'&&ch<='7'){
while(ch>='0'&&ch<='7')
{
flag=1;
arr=arr+ch;
ch=fgetc(fpin);
}
}
elseif(ch=='x'||ch=='X')
{
flag=2;
arr=arr+ch;
ch=fgetc(fpin);
while(IsNum(ch)||IsLetter1(ch))
{
arr=arr+ch;
ch=fgetc(fpin);
}
}
elseif(ch==''||ch==','||ch==';'){
cout<<"<"<"< }
fseek(fpin,-1L,SEEK_CUR);
if(flag==1)cout<<"<"<"< elseif(flag==2)cout<<"<"<"< }
else
{
arr=arr+ch;
ch=fgetc(fpin);
while(IsNum(ch))
{
arr=arr+ch;
ch=fgetc(fpin);
}
fseek(fpin,-1L,SEEK_CUR);
cout<<"<"<"< }
}
elseswitch(ch)
{
case'+':
case'-':
case'*':
case'=':
case'/':
cout<<"<"<"<case'(':
case')':
case'[':
case']':
case';':
case'.':
case',':
case'{':
case'}':
cout<<"<"<"<case':
':
{ch=fgetc(fpin);
if(ch=='=')cout<<"<"<<":
="<<",运算符>"<else{cout<<"<"<<":
:
"<<",界符>"<fseek(fpin,-1L,SEEK_CUR);}
}break;
case'>':
{ch=fgetc(fpin);
if(ch=='=')cout<<"<"<<">="<<",运算符>"<if(ch=='>')cout<<"<"<<">>"<<",输入控制符>"<else{cout<<"<"<<">"<<",运算符>"<fseek(fpin,-1L,SEEK_CUR);}