编译原理词法分析实验一词法分析扫描器的设计实现本科论文.docx
《编译原理词法分析实验一词法分析扫描器的设计实现本科论文.docx》由会员分享,可在线阅读,更多相关《编译原理词法分析实验一词法分析扫描器的设计实现本科论文.docx(17页珍藏版)》请在冰豆网上搜索。
编译原理词法分析实验一词法分析扫描器的设计实现本科论文
编译原理程序设计实验报告
——实验题目
班级:
计算机1306姓名:
学号:
289
实验目标:
词法分析扫描器的设计实现
实验内容:
1.概要设计
1)主函数:
每次从文件中读取一个字符,不是#,继续判断其是否是0~9数字,是进入isnumber()函数,否继续判断其是否是a~z或A~Z,是进入isalpha()函数,否继续判断是否是空格或换行符,是继续读下一个字符,否进入isother()函数。
2)Isnumber():
读字符,将数字(包括小数点)全部接收,并存入常数表。
3)Isalpha():
读字符,将a~z或A~Z(包括下划线)全部接收,与关键字表比较,匹配,输出序号,否则存入标识符表。
4)Isother():
读字符,将符号都接受,与界符表比较,匹配输出序号,遇到”或’分别存入字符表和字符串表。
2.流程图
T
F
T
F
T
F
F
3.关键函数
voidIsNumber();//读的是数字
voidIsAlpha();//读的是关键字和标示符
intIsOther();//读字符、字符串、界符
源程序代码:
(加入注释)
#include
#include
#include
#include
usingnamespacestd;
/***********定义结构体***********/
typedefstructToken
{
charname[20];
intstate;//状态,为0是标识符,为1是字符,为2是字符串,为3是数字,为4是关键字,为5是界符
}Token;
typedefstructSTR//
{
charname[20];
intcode;
}STR;
STRiT[10];
STRcT[20];
STRsT[20];
STRCT[20];
STRKT[10]={{"int",4},{"main",5},{"void",6},{"if",7},{"else",8},{"char",9}};
STRPT[30]={{">=",10},{"<=",11},{"==",12},{"=",13},{">",14},{"<",15},{"+",16},{"-",17},{"*",18},{"/",19},
{"{",20},{"}",21},{",",22},{";",23},{"(",24},{")",25},
{"[",26},{"]",27}};
/***********全局变量声明*********/
TokenCurrentToken;//正在读的token
Tokentoken[200];
FILE*fp;//源文件指针
charch;//读取字符
intstate=0;//0表示标识符,1表示字符,2表示字符串
intiT_i=0;//iT结构体数组下标
intcT_i=0;
intsT_i=0;
intCT_i=0;
intindex=0;//token的下标
/***函数声明***/
voidIsNumber();//读的是数字
voidIsAlpha();//读的是字母,关键字和标示符
intIsOther();//,;+-
/******************主函数**********************/
intmain()
{
inti=0;
if((fp=fopen("source.txt","r"))==NULL)
{
cout<<"cannotopenthesourcefile!
\n"<exit
(1);
}
ch=fgetc(fp);//文件中读一个字符
while(ch!
='#')
{
for(i=0;i<20;i++)
CurrentToken.name[i]='\0';//将单词缓冲区初始化
if((ch>='0')&&(ch<='9'))//数字
IsNumber();
elseif(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||(ch=='_'))//关键字和标识符
{
IsAlpha();
}
elseif(ch==''||ch=='\n')
{
ch=fgetc(fp);
}
else
IsOther();
}
cout<for(i=0;i<=index;i++)
{
cout<}
cout<cout<<"finish"<return0;
}
/************数字处理****************/
voidIsNumber()
{
intk=0;
while(((ch>='0')&&(ch<='9')))
{
CurrentToken.name[k++]=ch;//将数字放入单词缓冲区
ch=fgetc(fp);
}
boolflag=1;
if(ch=='.')
{
CurrentToken.name[k++]=ch;
ch=fgetc(fp);
if(((ch<'0')||(ch>'9')))
{
CurrentToken.name[k++]=ch;
flag=0;
}
else
{
while(((ch>='0')&&(ch<='9')))
{
CurrentToken.name[k++]=ch;//将数字放入单词缓冲区
ch=fgetc(fp);
}
}
}
if(flag==1)
{
strcpy(CT[CT_i++].name,CurrentToken.name);
strcpy(token[index].name,CurrentToken.name);
token[index++].state=3;
//cout<"<cout<<"<03>";
}
else
cout<"<}
/************是否为关键字****************/
voidIsAlpha()
{
inti=0;
if(state==0)
{
boolflag=0;
while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||ch=='_')//将完整的单词放入单词缓冲区
{
CurrentToken.name[i++]=ch;
ch=fgetc(fp);
}
flag=0;//判断是否是关键字
for(i=0;i<7;i++)
{
if(strcmp(CurrentToken.name,KT[i].name)==0)
{
flag=1;
//printf("%s<%02d>\n",CurrentToken.name,KT[i].code);
strcpy(token[index].name,CurrentToken.name);
token[index++].state=4;
printf("<%02d>",KT[i].code);
break;
}
}
if(flag!
=1)
{
while(((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z'))||ch=='_'||((ch>='0')&&(ch<='9')))
{
CurrentToken.name[i++]=ch;
ch=fgetc(fp);
}
//printf("%s<00>\n",CurrentToken.name);
printf("<00>");
strcpy(token[index].name,CurrentToken.name);
token[index++].state=0;
inttag=0;
for(intj=0;j{
if(strcmp(CurrentToken.name,iT[j].name)==0)
{
tag=1;
break;
}
}
if(tag==0)
{
strcpy(iT[iT_i].name,CurrentToken.name);
iT[iT_i++].code=0;
}
}
}
}
/***************其它************/
intIsOther()
{
inti;
for(i=0;i<20;i++)
{
CurrentToken.name[i]='\0';//将缓冲区初始化
}
boolflag=0;
switch(ch)
{
case'>':
{
CurrentToken.name[0]='>';
flag=1;
ch=fgetc(fp);
if(ch=='=')
{
CurrentToken.name[1]='=';
ch=fgetc(fp);
break;
}
else
{
break;
}
}
case'<':
{
CurrentToken.name[0]='<';
flag=1;
ch=fgetc(fp);
if(ch=='=')
{
CurrentToken.name[1]='=';
ch=fgetc(fp);
break;
}
else
{
break;
}
}
case'=':
{
CurrentToken.name[0]='=';
flag=1;
ch=fgetc(fp);
if(ch=='=')
{
CurrentToken.name[1]='=';
ch=fgetc(fp);
break;
}
else
{
break;
}
}
case'+':
{
CurrentToken.name[0]='+';
break;
}
case'-':
{
CurrentToken.name[0]='-';
break;
}
case'*':
{
CurrentToken.name[0]='*';
break;
}
case'/':
{
CurrentToken.name[0]='/';
break;
}
case'{':
{
CurrentToken.name[0]='{';
break;
}
case'}':
{
CurrentToken.name[0]='}';
break;
}
case',':
{
CurrentToken.name[0]=',';
break;
}
case';':
{
CurrentToken.name[0]=';';
break;
}
case'(':
{
CurrentToken.name[0]='(';
break;
}
case')':
{
CurrentToken.name[0]=')';
break;
}
case'[':
{
CurrentToken.name[0]='[';
break;
}
case']':
{
CurrentToken.name[0]=']';
break;
}
case'\'':
{
CurrentToken.name[0]='\'';
ch=fgetc(fp);
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
CurrentToken.name[1]=ch;
ch=fgetc(fp);
if(ch=='\'')
{
CurrentToken.name[2]='\'';
cout<<"<01>";
strcpy(token[index].name,CurrentToken.name);
token[index++].state=1;
inttag=0;
for(intj=0;j<=cT_i;j++)
{
if(strcmp(cT[cT_i].name,CurrentToken.name)==0)
tag=1;
}
if(tag==0)
{
strcpy(cT[cT_i++].name,CurrentToken.name);
}
ch=fgetc(fp);
return0;
}
else
{
cout<<"error1";
exit
(1);
}
}
else
{
cout<<"error2";
exit
(1);
}
}
case'\"':
{
intj=1;
CurrentToken.name[0]='\"';
ch=fgetc(fp);
while((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
CurrentToken.name[j++]=ch;
ch=fgetc(fp);
}
if(ch=='\"')
{
CurrentToken.name[j++]='\"';
cout<<"<02>";
strcpy(token[index].name,CurrentToken.name);
token[index++].state=1;
inttag=0;
for(intj=0;j<=sT_i;j++)
{
if(strcmp(sT[sT_i].name,CurrentToken.name)==0)
tag=1;
}if(tag==0)
{
strcpy(sT[sT_i++].name,CurrentToken.name);}
ch=fgetc(fp);
return0;
}
else
{
cout<<"error3";
exit
(1);
}
}
}
if(CurrentToken.name[0]!
='\0')
{
for(i=0;i<20;i++)
if(strcmp(CurrentToken.name,PT[i].name)==0)
{
//printf("%s<%d>\n",CurrentToken.name,PT[i].code);
printf("<%d>",PT[i].code);
strcpy(token[index].name,CurrentToken.name);
token[index++].state=PT[i].code;
break;
}
}
if(flag!
=1)
ch=fgetc(fp);
//while(ch==''||ch=='\n')ch=fgetc(fp);
return0;
}
程序运行结果:
(截屏)
输入:
Source.txt文本
intmain(void)
{
inta=1,d=2,c;
if(a<=d)
{
c=a;
a=d;
d=c;
}
charch[10]="ok";
charx,y='a';
c=a+d;
}
}
#
输出: