词法分析器文档分解.docx
《词法分析器文档分解.docx》由会员分享,可在线阅读,更多相关《词法分析器文档分解.docx(16页珍藏版)》请在冰点文库上搜索。
词法分析器文档分解
词法分析程序文档
说明:
该词法分析器实现对C语言源代码进行词法分析的功能,由文件输入,将输入的源代码输出为token序列,用二元组形式由文件和屏幕输出,文件输出首先输入源文件路径和文件名称,将注释过滤,能够报告不合法字符,并且记录源代码的行数,单词数(包括关键字,标识符和常量)和字符数(包括字母,数字,标点符号,运算符,空格和换行符)。
程序设计:
具体见源代码
源代码:
#include
usingnamespacestd;
#defineMAX32
charch='';
intline=1,zifu=1,word=0;
/*line记录行数
zifu记录字符数(包括字母,数字,标点符号,运算符,空格和换行符)
word记录单词数(包括关键字,标识符和常量)*/
stringkey[32]={"auto","break","case","char","const","continue","default","do","double",
"else","enum","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while"
};//c语言中的所有关键字
intIskey(stringc)//关键字判断
{
inti;
for(i=0;i{if(key[i].compare(c)==0){//将字符串与关键字一一进行比较return1;}}return0;}intIsLetter(charc)//判断是否为字母{if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))){return1;}elsereturn0;}intIsDigit(charc)//判断是否为数字{if(c>='0'&&c<='9'){return1;}elsereturn0;}voidanalyse(FILE*fpin,FILE*fpout){stringarr="";stringstr="";while((ch=fgetc(fpin))!=EOF){zifu++;//将文件中的字符逐一进行扫描,包括字母,数字,标点符号,运算符,空格和换行符arr="";if(IsLetter(ch))//对开头是字母或数字的字符串进行判断{while(IsLetter(ch)||IsDigit(ch)||ch=='_')//符合标识符或者关键字标准的字符串进行判断{if((ch<='Z')&&(ch>='A'))ch=ch+32;arr=arr+ch;//将每个单个读取的字符连成字符串ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);//不满足条件的多读取的字符回退一格if(Iskey(arr))//判断字符串是否是关键字{fprintf(fpout,"(%s%s)\n",arr.c_str(),"key");printf("(%s%s)\n",arr.c_str(),"key");word++;}else//字符串不是关键字则判定为标识符{fprintf(fpout,"(%s%s)\n",arr.c_str(),"id");printf("(%s%s)\n",arr.c_str(),"id");word++;}}elseif(IsDigit(ch))//开头为数字的串即为常量{while(IsDigit(ch)||ch=='.'&&IsDigit(fgetc(fpin))){arr=arr+ch;ch=fgetc(fpin);}fseek(fpin,-1L,SEEK_CUR);fprintf(fpout,"(%s%s)\n",arr.c_str(),"num");printf("(%s%s)\n",arr.c_str(),"num");word++;}elseswitch(ch)//既不是数字也不是字母的符号判定{case'+':{ch=fgetc(fpin);//判定++,+=,+if(ch=='+'){fprintf(fpout,"(%s%s)\n","++","-");printf("(%s%s)\n","++","-");zifu++;}if(ch=='='){fprintf(fpout,"(%s%s)\n","+=","-");printf("(%s%s)\n","+=","-");zifu++;}else{fprintf(fpout,"(%s%s)\n","+","-");printf("(%s%s)\n","+","-");fseek(fpin,-1L,SEEK_CUR);}}break;case'-':{ch=fgetc(fpin);if(ch=='-')//判定--,-=,-{fprintf(fpout,"(%s%s)\n","--","-");printf("(%s%s)\n","--","-");zifu++;}if(ch=='='){fprintf(fpout,"(%s%s)\n","-=","-");printf("(%s%s)\n","-=","-");zifu++;}else{fprintf(fpout,"(%s%s)\n","-","-");printf("(%s%s)\n","-","-");fseek(fpin,-1L,SEEK_CUR);}}break;case'*':fprintf(fpout,"(%s%s)\n","*","-");printf("(%s%s)\n","*","-");break;case'=':{ch=fgetc(fpin);//判定==,=if(ch=='='){fprintf(fpout,"(%s%s)\n","==","-");printf("(%s%s)\n","==","-");zifu++;}else{fprintf(fpout,"(%s%s)\n","=","EQ");printf("(%s%s)\n","=","EQ");fseek(fpin,-1L,SEEK_CUR);}}break;case'/':{ch=fgetc(fpin);//判定是注释还是运算符/if(ch=='*')//形如/**/的注释,将注释过滤{zifu--;ch=fgetc(fpin);while((ch!='*')&&(ch=fgetc(fpin))=='/');}elseif(ch=='/')//形如//的注释,将注释过滤{zifu--;ch=fgetc(fpin);while(ch!='\n')ch=fgetc(fpin);line++;}else{fprintf(fpout,"(%s%s)\n","/","-");printf("(%s%s)\n","/","-");fseek(fpin,-1L,SEEK_CUR);}}break;case'%':fprintf(fpout,"(%s%s)\n","%","-");printf("(%s%s)\n","%","-");break;case'#':fprintf(fpout,"(%s%s)\n","#","-");printf("(%s%s)\n","#","-");break;case'!':{ch=fgetc(fpin);//判定!=还是!if(ch=='='){fprintf(fpout,"(%s%s)\n","!=","-");printf("(%s%s)\n","!=","-");zifu++;}else{fprintf(fpout,"(%s%s)\n","!","-");printf("(%s%s)\n","!","-");fseek(fpin,-1L,SEEK_CUR);}}break;case'|':{ch=fgetc(fpin);if(ch=='|')//判定||还是|{fprintf(fpout,"(%s%s)\n","||","-");printf("(%s%s)\n","||","-");zifu++;}else{fprintf(fpout,"(%s%s)\n","|","-");printf("(%s%s)\n","|","-");fseek(fpin,-1L,SEEK_CUR);}}break;case'&':{ch=fgetc(fpin);if(ch=='&')//判定&&还是&{fprintf(fpout,"(%s%s)\n","&&","-");printf("(%s%s)\n","&&","-");zifu++;}else{fprintf(fpout,"(%s%s)\n","&","-");printf("(%s%s)\n","&","-");fseek(fpin,-1L,SEEK_CUR);}}break;case'(':fprintf(fpout,"(%s%s)\n","(","-");printf("(%s%s)\n","(","-");break;case')':fprintf(fpout,"(%s%s)\n",")","-");printf("(%s%s)\n",")","-");break;case'[':fprintf(fpout,"(%s%s)\n","[","-");printf("(%s%s)\n","[","-");break;case']':fprintf(fpout,"(%s%s)\n","]","-");printf("(%s%s)\n","]","-");break;case';':fprintf(fpout,"(%s%s)\n",";","-");printf("(%s%s)\n",";","-");break;case'.':fprintf(fpout,"(%s%s)\n",".","-");printf("(%s%s)\n",".","-");break;case',':fprintf(fpout,"(%s%s)\n",",","-");printf("(%s%s)\n",",","-");break;case'{':fprintf(fpout,"(%s%s)\n","{","-");printf("(%s%s)\n","{","-");break;case'}':fprintf(fpout,"(%s%s)\n","}","-");printf("(%s%s)\n","}","-");break;case'"':fprintf(fpout,"(%s%s)\n","引号","-");printf("(%s%s)\n","引号","-");break;case'?':fprintf(fpout,"(%s%s)\n","?","-");printf("(%s%s)\n","?","-");break;case':':fprintf(fpout,"(%s%s)\n",":","-");printf("(%s%s)\n",":","-");break;case'>':{ch=fgetc(fpin);if(ch=='=')//判定>=还是>{fprintf(fpout,"(%s%s)\n",">=","GE");printf("(%s%s)\n",">=","GE");zifu++;}else{fprintf(fpout,"(%s%s)\n",">","GT");printf("(%s%s)\n",">","GT");fseek(fpin,-1L,SEEK_CUR);}}break;case'<':{ch=fgetc(fpin);//判定<=还是<还是<>if(ch=='='){fprintf(fpout,"(%s%s)\n","<=","LE");printf("(%s%s)\n","<=","LE");zifu++;}elseif(ch=='>'){fprintf(fpout,"(%s%s)\n","<>","NE");printf("(%s%s)\n","<>","NE");zifu++;}else{fprintf(fpout,"(%s%s)\n","<","LT");printf("(%s%s)\n","<","LT");fseek(fpin,-1L,SEEK_CUR);}}break;case'':break;case'\n':line++;//每读到\n,记录行数break;default:fprintf(fpout,"(%c%s)\n",ch,"不合法");printf("(%c%s)\n",ch,"不合法");break;}}}intmain(){charin_fn[30];FILE*fpin,*fpout;fpout=fopen("playover.txt","w");cout<<"请输入源文件名(包括路径和后缀名):";for(;;){cin>>in_fn;if((fpin=fopen(in_fn,"r"))!=NULL)break;elsecout<<"文件路径错误!请输入源文件名(包括路径和后缀名):";}cout<<"\n分析如下"<analyse(fpin,fpout);cout<<"行数:"<cout<<"单词数:"<cout<<"字符数:"<fclose(fpout);fclose(fpin);system("pause");return0;}输入文件:输出文件:
if(key[i].compare(c)==0){//将字符串与关键字一一进行比较
return1;
}
return0;
intIsLetter(charc)//判断是否为字母
if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A')))
elsereturn0;
intIsDigit(charc)//判断是否为数字
if(c>='0'&&c<='9')
voidanalyse(FILE*fpin,FILE*fpout)
stringarr="";
stringstr="";
while((ch=fgetc(fpin))!
=EOF)
{zifu++;//将文件中的字符逐一进行扫描,包括字母,数字,标点符号,运算符,空格和换行符
arr="";
if(IsLetter(ch))//对开头是字母或数字的字符串进行判断
while(IsLetter(ch)||IsDigit(ch)||ch=='_')//符合标识符或者关键字标准的字符串进行判断
if((ch<='Z')&&(ch>='A'))ch=ch+32;
arr=arr+ch;//将每个单个读取的字符连成字符串
ch=fgetc(fpin);
fseek(fpin,-1L,SEEK_CUR);//不满足条件的多读取的字符回退一格
if(Iskey(arr))//判断字符串是否是关键字
fprintf(fpout,"(%s%s)\n",arr.c_str(),"key");
printf("(%s%s)\n",arr.c_str(),"key");
word++;
else//字符串不是关键字则判定为标识符
fprintf(fpout,"(%s%s)\n",arr.c_str(),"id");
printf("(%s%s)\n",arr.c_str(),"id");
elseif(IsDigit(ch))//开头为数字的串即为常量
while(IsDigit(ch)||ch=='.'&&IsDigit(fgetc(fpin)))
arr=arr+ch;
fseek(fpin,-1L,SEEK_CUR);
fprintf(fpout,"(%s%s)\n",arr.c_str(),"num");
printf("(%s%s)\n",arr.c_str(),"num");
elseswitch(ch)//既不是数字也不是字母的符号判定
case'+':
ch=fgetc(fpin);//判定++,+=,+
if(ch=='+')
fprintf(fpout,"(%s%s)\n","++","-");
printf("(%s%s)\n","++","-");
zifu++;
if(ch=='=')
fprintf(fpout,"(%s%s)\n","+=","-");
printf("(%s%s)\n","+=","-");
else
fprintf(fpout,"(%s%s)\n","+","-");
printf("(%s%s)\n","+","-");
break;
case'-':
if(ch=='-')//判定--,-=,-
fprintf(fpout,"(%s%s)\n","--","-");
printf("(%s%s)\n","--","-");
fprintf(fpout,"(%s%s)\n","-=","-");
printf("(%s%s)\n","-=","-");
fprintf(fpout,"(%s%s)\n","-","-");
printf("(%s%s)\n","-","-");
case'*':
fprintf(fpout,"(%s%s)\n","*","-");
printf("(%s%s)\n","*","-");
case'=':
ch=fgetc(fpin);//判定==,=
if(ch=='='){
fprintf(fpout,"(%s%s)\n","==","-");
printf("(%s%s)\n","==","-");
fprintf(fpout,"(%s%s)\n","=","EQ");
printf("(%s%s)\n","=","EQ");
case'/':
ch=fgetc(fpin);//判定是注释还是运算符/
if(ch=='*')//形如/**/的注释,将注释过滤
{zifu--;
while((ch!
='*')&&(ch=fgetc(fpin))=='/')
;
elseif(ch=='/')//形如//的注释,将注释过滤
while(ch!
='\n')ch=fgetc(fpin);
line++;
fprintf(fpout,"(%s%s)\n","/","-");
printf("(%s%s)\n","/","-");
case'%':
fprintf(fpout,"(%s%s)\n","%","-");
printf("(%s%s)\n","%","-");
case'#':
fprintf(fpout,"(%s%s)\n","#","-");
printf("(%s%s)\n","#","-");
case'!
':
ch=fgetc(fpin);//判定!
=还是!
fprintf(fpout,"(%s%s)\n","!
=","-");
printf("(%s%s)\n","!
","-");
case'|':
if(ch=='|')//判定||还是|
fprintf(fpout,"(%s%s)\n","||","-");
printf("(%s%s)\n","||","-");
fprintf(fpout,"(%s%s)\n","|","-");
printf("(%s%s)\n","|","-");
case'&':
if(ch=='&')//判定&&还是&
fprintf(fpout,"(%s%s)\n","&&","-");
printf("(%s%s)\n","&&","-");
fprintf(fpout,"(%s%s)\n","&","-");
printf("(%s%s)\n","&","-");
case'(':
fprintf(fpout,"(%s%s)\n","(","-");
printf("(%s%s)\n","(","-");
case')':
fprintf(fpout,"(%s%s)\n",")","-");
printf("(%s%s)\n",")","-");
case'[':
fprintf(fpout,"(%s%s)\n","[","-");
printf("(%s%s)\n","[","-");
case']':
fprintf(fpout,"(%s%s)\n","]","-");
printf("(%s%s)\n","]","-");
case';':
fprintf(fpout,"(%s%s)\n",";","-");
printf("(%s%s)\n",";","-");
case'.':
fprintf(fpout,"(%s%s)\n",".","-");
printf("(%s%s)\n",".","-");
case',':
fprintf(fpout,"(%s%s)\n",",","-");
printf("(%s%s)\n",",","-");
case'{':
fprintf(fpout,"(%s%s)\n","{","-");
printf("(%s%s)\n","{","-");
case'}':
fprintf(fpout,"(%s%s)\n","}","-");
printf("(%s%s)\n","}","-");
case'"':
fprintf(fpout,"(%s%s)\n","引号","-");
printf("(%s%s)\n","引号","-");
case'?
fprintf(fpout,"(%s%s)\n","?
printf("(%s%s)\n","?
case':
fprintf(fpout,"(%s%s)\n",":
printf("(%s%s)\n",":
case'>':
if(ch=='=')//判定>=还是>
fprintf(fpout,"(%s%s)\n",">=","GE");
printf("(%s%s)\n",">=","GE");
fprintf(fpout,"(%s%s)\n",">","GT");
printf("(%s%s)\n",">","GT");
case'<':
ch=fgetc(fpin);//判定<=还是<还是<>
fprintf(fpout,"(%s%s)\n","<=","LE");
printf("(%s%s)\n","<=","LE");
elseif(ch=='>'){
fprintf(fpout,"(%s%s)\n","<>","NE");
printf("(%s%s)\n","<>","NE");
fprintf(fpout,"(%s%s)\n","<","LT");
printf("(%s%s)\n","<","LT");
case'':
case'\n':
line++;//每读到\n,记录行数
default:
fprintf(fpout,"(%c%s)\n",ch,"不合法");
printf("(%c%s)\n",ch,"不合法");
intmain()
charin_fn[30];
FILE*fpin,*fpout;
fpout=fopen("playover.txt","w");
cout<<"请输入源文件名(包括路径和后缀名):
";
for(;;)
cin>>in_fn;
if((fpin=fopen(in_fn,"r"))!
=NULL)break;
elsecout<<"文件路径错误!
请输入源文件名(包括路径和后缀名):
cout<<"\n分析如下"<analyse(fpin,fpout);cout<<"行数:"<cout<<"单词数:"<cout<<"字符数:"<fclose(fpout);fclose(fpin);system("pause");return0;}输入文件:输出文件:
analyse(fpin,fpout);
cout<<"行数:
"<cout<<"单词数:"<cout<<"字符数:"<fclose(fpout);fclose(fpin);system("pause");return0;}输入文件:输出文件:
cout<<"单词数:
"<cout<<"字符数:"<fclose(fpout);fclose(fpin);system("pause");return0;}输入文件:输出文件:
cout<<"字符数:
"<fclose(fpout);fclose(fpin);system("pause");return0;}输入文件:输出文件:
fclose(fpout);
fclose(fpin);
system("pause");
输入文件:
输出文件:
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2