06_05_词法分析

来源:互联网 发布:独立 知乎 编辑:程序博客网 时间:2024/06/01 09:24
#include<stdio.h>#include<ctype.h>#include<string.h>#define keywordSum  11char Scanin[300],Scanout[300]; //用于接收输入输出文件名FILE *fin,*fout;//用于指向输入输出文件的指针char *keyword[keywordSum]={ "if","else","for","while","do","int","double","float","char","read","write"};char singleword[50]="+-*(){};,:";char doubleword[10]="><=!";char Scanin[300], Scanout[300]; //用于接收输入输出文件名,在TEST_main.c中定义FILE *fin,*fout; //用于指向输入输出文件的指针,在TEST_main.c中定义int TESTScan()//词法分析函数{   char ch,token[40]; //ch为每次读入的字符,token用于保存识别出的单词   int es=0,j,n; //es错误代码,0表示没有错误。j,n为临时变量,控制组合单词时的下标等   printf("请输入源程序文件名(包括路径):");   scanf("%s",Scanin);   printf("请输入词法分析输出文件名(包括路径):");   scanf("%s",Scanout);   if ((fin=fopen(Scanin,"r"))==NULL) //判断输入文件名是否正确   {      printf("\n打开词法分析输入文件出错!\n");      return(1);//输入文件出错返回错误代码1   }   if ((fout=fopen(Scanout,"w"))==NULL) //判断输出文件名是否正确   {      printf("\n创建词法分析输出文件出错!\n");      return(2); //输出文件出错返回错误代码2   }   ch=getc(fin);   while(ch!=EOF)   {      while (ch==' '||ch=='\n'||ch=='\t')        ch=getc(fin);  if(ch==EOF)        break;      if (isalpha(ch))   //isalpha:一种函数:判断字符ch是否为英文字母,当ch为英文字母a-z或A-Z时,返回非零值(不一定是1),否则返回零      { token[0]=ch; j=1; ch=getc(fin); while(isalnum(ch))  //如果是字母数字则组合标识符;如果不是则标识符组合结束 {token[j++]=ch;  //组合的标识符保存在token中ch=getc(fin);  //读下一个字符 } token[j]='\0';  //标识符组合结束 //查保留字 n=0; while ((n<keywordSum) && strcmp(token,keyword[n])) n++; if (n>=keywordSum)  //不是保留字,输出标识符fprintf(fout,"%s\t%s\n","ID",token);  //输出标识符符号else//是保留字,输出保留字fprintf(fout,"%s\t%s\n",token,token);  //输出保留字符号  }  else if (isdigit(ch))//数字处理      { token[0]=ch; j=1; ch=getc(fin);  //读下一个字符 while (isdigit(ch))  //如果是数字则组合整数;如果不是则整数组合结束 {token[j++]=ch;  //组合整数保存在token中ch=getc(fin);  //读下一个字符 } token[j]='\0';  //整数组合结束 fprintf(fout,"%s\t%s\n","NUM",token);  //输出整数符号      }      else if (strchr(singleword,ch)>0)  //单分符处理      { token[0]=ch; token[1]='\0'; ch=getc(fin);//读下一个符号以便识别下一个单词 fprintf(fout,"%s\t%s\n",token,token);  //输出单分界符符号      }      else if (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);  //输出单或双分界符符号      }      else if (ch=='/')  //注释处理      { ch=getc(fin);  //读下一个字符 if (ch=='*')  //如果是*,则开始处理注释 {            char ch1;ch1=getc(fin);  //读下一个字符do{    ch=ch1;    ch1=getc(fin);            }  //删除注释while ((ch!='*' || ch1!='/')&&ch1!=EOF);  //直到遇到注释结束符*/或文件尾ch=getc(fin);//读下一个符号以便识别下一个单词 } else  //不是*则处理单分界符/ { token[0]='/'; if(token[1]=='/'); token[2]='\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);  //返回主程序}//c:\test01.txt C:\out01.txt  运算符大致可以分为5种类型:算术运算符、连接运算符、关系运算符、赋值运算符和逻辑运算符。int main(){    int flag=0;    flag = TESTScan();    if(flag>0)        printf("词法分析有错,编译停止!\n");    else        printf("词法分析成功!\n");    return 0;}

                                             
0 0