⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lexicalanalyzer.cpp

📁 cmm语言词法分析程序
💻 CPP
字号:
//CMM语言词法分析器
//BY 高旭 学号200632580318 武汉大学国际软件学院06级10班 
//祝为我批改作业的来时身体健康,心情愉快,工作顺利 
#include <iostream>
#define N 20
#define keywordSum 7

using namespace std;

//保留字表 
char *keyword[keywordSum]={"if","else","int","real","write","read","while"};

//判断一个字段是整数或者是浮点数
//传入的参数为一个字符串的地址 
//返回值是2时不是合法的数据 
//返回值是1时为整数 
//返回值是2时为浮点数 
int isIntOrReal(char *str)
{
    int k,j=0;
    for(k=0;str[k]!='#'&&str[k]!='\0';k++)
    {
    switch(j)
    {
     case 0:
          {
              if(k==0&&str[k]>='0'&&str[k]<='9') j=1;
              else return(0);
              break;
          }
     case 1:
          {
              if(str[k]>='0'&&str[k]<='9') j=1;
              else if(str[k]=='.') j=2;
              else return(0);
              break;
          }
     case 2:
          {
              if(str[k]>='0'&&str[k]<='9') j=3;
              else return(0);
          }
     case 3:
          {
              if(str[k]>='0'&&str[k]<='9') j=3;
              else return(0);
          }
    }
  }
  if(j==1) return 1;//返回值是1时为整数 
  else if(j==3) return 2;//返回值是2时为浮点数 
  else return 0;
}

//判断是否是标识符 
//传入的参数为一个字符串的地址 
//返回值为1是是合法的标识符或者是关键字 
int isID(char *str)
{
    int k,j=0;
    for(k=0;str[k]!='#'&&str[k]!='\0';k++)
    {
    switch(j)
    {
     case 0:
          {
             if((k==0&&str[k]>='a'&&str[k]<='z')||(str[k]>='A'&&str[k]<='Z')) j=3;
             else return 0;
             break;
          }
     case 1:
          {
             if((str[k]>='0'&&str[k]<='9')||(str[k]>='a'&&str[k]<='z')||(str[k]>='A'&&str[k]<='Z')) j=2;
             else if (str[k]=='_') j=1;
             else return 0;
             break;
          }
    case 2:
         {
             if((str[k]>='a'&&str[k]<='z')||(str[k]>='0'&&str[k]<='9')||(str[k]>='A'&&str[k]<='Z')) j=2;
             else if (str[k]=='_') j=1;
             else return 0;
             break;
          }
     case 3:
         {
             if((str[k]>='a'&&str[k]<='z')||(str[k]>='0'&&str[k]<='9')||(str[k]>='A'&&str[k]<='Z')) j=2;
             else if(str[k]=='_') j=1;
             else return 0;
             break;
          }
     case 4:
         {
             if((str[k]>='a'&&str[k]<='z')||(str[k]>='0'&&str[k]<='9')||(str[k]>='A'&&str[k]<='Z')) j=2;
             else if(str[k]=='_') j=1;             
             else return 0;
             break;
          }          
     
    }
    }
    if(j==2||j==3) return 1;//返回值为1是是合法的标识符 
    else return 0;
}

//判断特殊符号
//输入是一个字符串
//返回值是0时是非法符号 
//返回值是1时字段是一个运算符号 
//返回值是2时字段是一个关系符号 
int isSign(char *str)
{
    int k,j=0;
    for(k=0;str[k]!='#'&&str[k]!='\0';k++)
    {
     switch(j)
    {
     case 0:
          {
          if((k==0)&&(str[k]=='+'||str[k]=='-'||str[k]=='*'||str[k]=='/'||str[k]=='('||str[k]==')'||str[k]=='{'||str[k]=='}'||str[k]==';'||str[k]=='>'))
          j=1;
          else if(str[k]=='='||str[k]=='<') j=2;
          //else if(str[k]=='/') j=4;
          else return 0;
          break;
          }
     case 1:
         {
              j=1;
              return 0;
              break;
          }
     case 2:
          {
              if(str[k]=='='||str[k]=='>') j=3;              
              else j=0;
              break;
          }     
     }
     }
     if(j==1||j==2||j==4||j==7) return 1;
     else if (j==3) return 2;
     else return(0);
}

main ()
{
     //k是判断其字段类型的序号 
     //i是想屏幕上写字符的序号 
     //n是判断是否属于保留字的时的序号 
     //LineNum是行号 
     int k,i,n,h=0,LineNum=1;
     //用于暂时保存字段的字符串 
     char str[N];
     //读出的单个字符 
     int ch;
     FILE *fin;
     char Scanin[300];
     while(1){
     //从控制台键入输入的文件路径 
     printf("\nPlease input the path of file:\n");
     scanf("%s",Scanin);     
     
     //判断输入的文件格式是否正确,是否存在要读取的文件 
     if((fin=fopen(Scanin,"r"))==NULL)
     {
         printf("Can't find the file wanted!");
         return 1;
     }
     
     //读取第一个字符 
     ch=getc(fin);
     //输出第一行的行号 
     printf("Line: %d",LineNum);
     while(ch!=EOF){                 //在文件结束之前 
     while(ch=='\n'||ch=='\r') 
     {
     ch=getc(fin);                   //读取下一个字符 
     LineNum++;                      //遇到换行或者回车符号就行号加1 
     printf("\nLine: %d",LineNum);   //输出当前行号 
     }
     while(ch==' '||ch=='\t'||ch=='\n'||ch=='\r') ch=getc(fin);      //滤过回车,换行,制表,空格 
     while(ch!=' '&&ch!='\n'&&ch!='\r'&&ch!='\t'&&ch!=EOF)           //读取一个字段,将其以字符串形式赋值 
     {          
          str[h++]=ch;
          ch=getc(fin);                       
     }
     str[h++]='\0';                      //清空字符串中其余部分 
     if(str[0]!='\0')
     {
          //若字段以数字开头,则判断其是否是合法的数据类型:整数或浮点数 
          if(str[0]>='0'&&str[0]<='9')
          {              
              if(isIntOrReal(str)==1) printf("\nint:\t");//是整数                          
              else if(isIntOrReal(str)==2) printf("\nreal:\t");//是浮点数 
              else printf("\ninvalidNUM:\t");//不符合词法的数据类型 
              for(i=0;str[i]!='\0';i++)printf("%c",str[i]);//输出该字段
          }
          
          //若字段以字母开头,则判断其是否是合法的标识符 
          else if((str[0]>='a'&&str[0]<='z')||(str[0]>='A'&&str[0]<='Z'))
          {
               n=0;               
               //判断是否是保留字 
               while((n<keywordSum)&&(strcmp(str,keyword[n]))) n++;
               if(n>=keywordSum)//此时不是保留字 
               {
                  if(isID(str)==1) printf("\nvalidID:\t");//符合命名规范的标识符 
                  else printf("\ninvalidID:\t");//不符合命名规范的标识符  
                  for(i=0;str[i]!='\0';i++)printf("%c",str[i]);//输出该字段
               }
               else//此时是保留字 
               {
                    printf("\nkeyword:\t");
                    for(i=0;str[i]!='\0';i++)printf("%c",str[i]);//输出该字段
               }                      
          }         
          
          //若以上都不是,判断其是否是特殊符号 
          else 
          {
               if(isSign(str)==1) printf("\nMathemetics or Separate Symbol:\t");//是数学符号或者单分隔符 
               else if(isSign(str)==2) printf("\nLogic Symbol:\t");//是逻辑关系符号 
               else printf("\ninvalid:\t");//是不符合CMM语言文法规范的符号 
               for(i=0;str[i]!='\0';i++)printf("%c",str[i]);//输出该字段 
          }    
     }
     h=0;     
     }
}   
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -