• 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("
    打开词法分析输入文件出错!
    ");
          return(1);//输入文件出错返回错误代码1
       }
       if ((fout=fopen(Scanout,"w"))==NULL) //判断输出文件名是否正确
       {
          printf("
    创建词法分析输出文件出错!
    ");
          return(2); //输出文件出错返回错误代码2
       }
       ch=getc(fin);
       while(ch!=EOF)
       {
          while (ch==' '||ch=='
    '||ch=='	')
            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]='';  //标识符组合结束
    		 //查保留字
    		 n=0;
    		 while ((n<keywordSum) && strcmp(token,keyword[n])) n++;
    		 if (n>=keywordSum)  //不是保留字,输出标识符
    			fprintf(fout,"%s	%s
    ","ID",token);  //输出标识符符号
    		else//是保留字,输出保留字
    			fprintf(fout,"%s	%s
    ",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]='';  //整数组合结束
    		 fprintf(fout,"%s	%s
    ","NUM",token);  //输出整数符号
          }
          else if (strchr(singleword,ch)>0)  //单分符处理
          {
    		 token[0]=ch;
    		 token[1]='';
    		 ch=getc(fin);//读下一个符号以便识别下一个单词
    		 fprintf(fout,"%s	%s
    ",token,token);  //输出单分界符符号
          }
          else if (strchr(doubleword,ch)>0)  //双分界符处理
          {
    		 token[0]=ch;
    		 ch=getc(fin);  //读下一个字符判断是否为双分界符
    		 if (ch=='=')  //如果是=,组合双分界符
    		 {
    			token[1]=ch;
    			token[2]='';  //组合双分界符结束
    		   	ch=getc(fin);  //读下一个符号以便识别下一个单词
    		 } else//不是=则为单分界符
    			token[1]='';
    		 fprintf(fout,"%s	%s
    ",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]='';
    			 fprintf(fout,"%s	%s
    ",token,token);  //输出单分界符/
    		 }
    	}
    	else//错误处理
        {
            token[0]=ch;
            token[1]='';
            ch=getc(fin);  //读下一个符号以便识别下一个单词
            es=3;  //设置错误代码
            fprintf(fout,"%s	%s
    ","ERROR",token);  //输出错误符号
        }
       }
       fclose(fin);//关闭输入输出文件
       fclose(fout);
       return(es);  //返回主程序
    }
    
    
    
    //c:	est01.txt C:out01.txt  运算符大致可以分为5种类型:算术运算符、连接运算符、关系运算符、赋值运算符和逻辑运算符。
    
    int main()
    {
        int flag=0;
        flag = TESTScan();
        if(flag>0)
            printf("词法分析有错,编译停止!
    ");
        else
            printf("词法分析成功!
    ");
        return 0;
    }
    

    
       
    
    
    请dalao不吝赐教。
  • 相关阅读:
    Object-C 声明属性为什么用下划线,代码规范和编程风格
    iOS API 概述
    iOS 彻底学会使用delegate
    iOS NSNotification的使用
    L1_6 连续因子
    天梯 L1_46整除光棍
    51-Nod 1279
    UVA
    hdu 1078
    Poj 1088 滑雪 递归实现
  • 原文地址:https://www.cnblogs.com/liesun/p/7350341.html
Copyright © 2020-2023  润新知