词法分析实验报告.docx
《词法分析实验报告.docx》由会员分享,可在线阅读,更多相关《词法分析实验报告.docx(13页珍藏版)》请在冰点文库上搜索。
词法分析实验报告
词法分析实验报告
班级:
11信计指导老师:
实验小组成员:
一.实验内容:
1.写出词法分析的功能和目的
2.画出词法规则(包括标识符、无符号整数、单分界符、双分界符、注释头规则)对应的状态图(可参考课本P33图3-7)
3.画出词法分析程序流程图(可参考课本P34图3-8)
4.写出你的小组在实验二中改写的内容及思路,如果可能,写出相应的文法规则。
5.列出输入文件内容及输出文件内容,尽量体现该词法分析程序能识别的单词,特别是你小组所补充的单词
6.写词法分析实验体会
二.实验过程:
(1).词法分析的功能:
将输入的源程序进行划分,给出基本符号(keyword)的序列,并略过注解和空格等分隔符号。
基本符号是与输入的语言定义的词法所规定的终结符。
(2).词法分析的目的:
掌握词法分析的原理,熟悉保留字表等相关的数据结构与单词的分类方法,掌握词法分析器的设计与调试.
(3).词法规则对应的状态图
letter,digit
letter
digit
digit
+,-,….,;
>,<,=,!
=
非=
/*
其他非*
词法分析程序流程图:
(4).实验代码:
Scan.cpp:
#include
#include
#include
#definekeywordSum9
char*keyword[keywordSum]={"if","else","for","while","do","int","read","write","double"};
charsingleword[50]="+-*(){};,:
";
chardoubleword[10]="><=!
";
externcharScanin[300],Scanout[300];
externFILE*fin,*fout;
intTESTscan(){
charch,token[40];
intes=0,j,n;
printf("请输入源程序文件名(包括路径)");
scanf("%s",Scanin);
printf("请输入词法分析输出文件名(包括路径)");
scanf("%s",Scanout);
if((fin=fopen(Scanin,"r"))==NULL){
printf("\n打开词法分析输入文件出错!
\n");
return
(1);
}
if((fout=fopen(Scanout,"w"))==NULL){
printf("\n创建词法分析文件出错!
\n");
return
(2);
//////////////////////////
}
ch=getc(fin);
while(ch!
=EOF)
{
while(ch==''||ch=='\n'||ch=='\t')ch=getc(fin);
if(isalpha(ch))
{
token[0]=ch;j=1;
ch=getc(fin);
while(isalnum(ch))
{
token[j++]=ch;
ch=getc(fin);
}
token[j]='\0';
n=0;
while((nif(n>=keywordSum)
fprintf(fout,"%s\t%s\n","ID",token);
else
fprintf(fout,"%s\t%s\n",token,token);
}
elseif(isdigit(ch))
{
chartemp[40];
temp[0]=ch;
token[0]=temp[0];
//token[0]=ch;
j=1;
ch=getc(fin);
while(isdigit(ch))
{
temp[j++]=ch;
ch=getc(fin);
}
if(ch=='.'){
chardot=ch;
ch=getc(fin);
if(isdigit(ch)){
temp[j++]=dot;
temp[j++]=ch;
ch=getc(fin);
while(isdigit(ch)){
temp[j++]=ch;
ch=getc(fin);
}
if(ch=='.'){
temp[j++]=ch;
}
}
}
intcount=0;
for(intn=0;n<40;n++){
if(temp[n]=='.')
count++;
}
for(intz=0;z<40;z++){
token[z]=temp[z];
}
token[j]='\0';
fprintf(fout,"%s\t%s\n","NUM",token);
}
elseif(strchr(singleword,ch)>0)
{
token[0]=ch;token[1]='\0';
ch=getc(fin);
fprintf(fout,"%s\t%s\n",token,token);
}
elseif(strchr(doubleword,ch)>0)
{
token[0]=ch;
ch=getc(fin);
///////////////////////////////////////////////////////////////////////////
if(ch=='=')
{
token[1]=ch;token[2]='\0';
ch=getc(fin);
}else
token[1]='\0';
fprintf(fout,"%s\t%s\n",token,token);
}elseif(ch=='/')
{
ch=getc(fin);
if(ch=='*')
{
charchl;
chl=getc(fin);
do
{ch=chl;chl=getc(fin);}
while((ch!
='*'||chl!
='/')&&chl!
=EOF);
ch=getc(fin);
}else
{
token[0]='/';token[1]='\0';
fprintf(fout,"%s\t%s\n",token,token);
}
}else
{
token[0]=ch;token[1]='\0';
ch=getc(fin);
es=3;
fprintf(fout,"%s\t%s\n","ERROR",token);
}
}
fclose(fin);
fclose(fout);
return(es);
}
Scanmain.cpp:
#include
#include
externintTESTscan();
charScanin[300],Scanout[300];
FILE*fin,*fout;
voidmain(){
intes=0;
es=TESTscan();
if(es>0)printf("词法分析有错,编译停止!
");
elseprintf("词法分析成功!
\n");
}
(5).在实验二中改写的内容及思路
本程序在实验一的代码基础上,增加对带小数点的实数的识别,在实验一的代码上将elseif(isdigit(ch))语句分块修改为:
elseif(isdigit(ch))
{
chartemp[40];
temp[0]=ch;
token[0]=temp[0];
//token[0]=ch;
j=1;
ch=getc(fin);
while(isdigit(ch))
{
temp[j++]=ch;
ch=getc(fin);
}
if(ch=='.'){
chardot=ch;
ch=getc(fin);
if(isdigit(ch)){
temp[j++]=dot;
temp[j++]=ch;
ch=getc(fin);
while(isdigit(ch)){
temp[j++]=ch;
ch=getc(fin);
}
}
}
token[j]='\0';
fprintf(fout,"%s\t%s\n","NUM",token);
}
改写的思路:
首先,如果第一个读取到的字符是数字的话,用while循环判断接下来读取到的字符是否还是数字,如果是则加入到token[]字符数组中,如果不是,则判断读取的字符是否是小数点”.”,如果是的话,先将小数点保存在声明的dot变量中,再判断小数点后面的字符是不是数字,如果是的话,则将dot加入到token[]上,再加上小数点后面的数字到token[]上.
(6).运行程序并且输入读取源文件a.txt和输出结果文件b.txt,如下图:
a.txt的内容如下:
b.txt的内容如下:
由上图可知语法分析成功!
(7).词法分析实验体会
1.这次实验对我们来说,有一定的难度,虽然理论和算法很熟悉,但是当实际编
程的时候还是感觉无从下手,后来查了好多资料,请教了其他同学才得以完成这次试验,这次试验让我认识到要多动手才会有收获。
2.通过这次试验,增加了我c++的编程能力,为我以后的相关作业打下很好的
基础。
3.通过本次实验,了解了词法分析器的基本原理