06_05_词法分析

#include<stdio.h>
#include<ctype.h>
#include<string.h>
#define keywordSum  11


char 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;
}

 

转载于:https://www.cnblogs.com/liesun/p/7350341.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值