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

📄 sentenceanalyse.cpp

📁 用C语言做的词法分析器
💻 CPP
字号:
//all i wish is to dream again
#include "stdio.h" 
#include"conio.h"
#include"stdlib.h"
#include"string.h"
#include"malloc.h"
FILE *fp,*out;
char ch,*token;
int alreadyread=0;
typedef struct word{
     char name[10];
     int id;
     char value[10];        
     //word * next;
}wordnode;
wordnode *wordNode;
const int maxIndex=50;
/*
            {0,0,0,0,0,0,0,1,0},
            {0,0,0,0,0,0,0,1,0},
            {2,2,0,0,2,2,2,1,0},
            {2,2,0,0,2,2,2,1,0},
            {2,2,0,0,0,0,2,1,0},
            {2,2,0,0,0,0,2,1,0},
            {2,2,2,2,2,2,2,2,3},
            {0,0,0,0,0,0,0,0,1},
            {2,2,2,2,2,2,2,2,0},

*/
int table[maxIndex][maxIndex];//0:error ,1:< ,2:> 3:=
void tableInit(){
     int i,j;
     for(i=0;i<maxIndex;i++)
         for(j=0;j<maxIndex;j++)
               table[i][j]=0;  
    //a           
    table[5][11]=2;table[5][14]=2;table[5][31]=2;table[5][32]=2;table[5][22]=2;table[5][33]=2;table[5][38]=3;
    //b 
    table[6][11]=2;table[6][14]=2;table[6][31]=2;table[6][32]=2;table[6][22]=2;table[6][33]=2;
    //+
    table[31][5]=1;table[31][6]=1;table[31][22]=1;table[31][33]=1;table[31][10]=1;table[31][11]=2; table[31][14]=2;table[31][31]=2;table[31][31]=2;
    //-
    table[32][5]=1;table[32][6]=1;table[32][22]=1;table[32][33]=1;table[32][10]=1;table[32][11]=2; table[32][14]=2;table[31][31]=2;table[31][32]=2;
    //*      
    table[22][5]=1;table[22][6]=1;table[22][10]=1;table[22][11]=2; table[22][14]=2;table[22][31]=2;table[22][32]=2;table[22][22]=2;table[22][33]=2;  
    ///            
    table[33][5]=1;table[33][6]=1;table[33][10]=1;table[33][11]=2; table[33][14]=2;table[33][31]=2;table[33][32]=2;table[33][33]=2;table[33][22]=2;      
    //(
    table[10][5]=1;table[10][6]=1;table[10][31]=1;table[10][32]=1;table[10][22]=1;table[10][33]=1;table[10][10]=1;table[10][11]=3;
    //)
    table[11][11]=2;table[11][14]=2;table[11][31]=2;table[11][32]=2;table[11][22]=2;table[11][33]=2;
    //;
    table[14][47]=2;
    //=
    table[38][5]=1;table[38][6]=1;table[38][31]=1;table[38][32]=1;table[38][22]=1;table[38][33]=1;table[38][10]=1;table[38][14]=3;
    //$
    table[47][5]=1;table[47][47]=3;

}
//退出程序 
void exitPrograme(){
    getch();
    fclose(fp);
    //fclose(out);
    exit(0);
}
/**
初始化程序
获得输入文件指针和输出文件指针 
*/
void Init(){
     char filename[10];
     printf("输入文件名:");
     scanf("%s",filename);
     if((fp=fopen(filename,"r"))==NULL){
          printf("canot open file\n");
          exitPrograme();   
     }
     /*
     if((out=fopen("out.txt","a+"))==NULL){
          printf("canot open file\n");
          exitPrograme();
     }
     */
}
//从文件中读一个字符 
void getcharfromfile(){
     if(!feof(fp)){//feof(fp)不移动指针 ;fgetc移动指针 
         if(alreadyread==1)alreadyread=0;
         else ch=fgetc(fp);                 
     }
     else{
          printf("no more input");
     } 
}
//把读出的字符与之前的相连接 
void connect(){
       int len=strlen(token);
       realloc(token,len+2);
       token[len]=ch;
       token[len+1]='\0';
}
//获得一个单词 
void getWord(){
     token=(char *)malloc(sizeof(char));
     
     do{
          getcharfromfile();  
          if(feof(fp))return;     
     }while(ch==' ');
     
     wordNode=(wordnode *)malloc(sizeof(wordnode));
     wordNode->value[0]='\0';
     
     //构造标示符 、关键字
     if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')){
          while((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')){
                connect();
                getcharfromfile();                                          
          }        
          alreadyread=1;
          //关键字
          if(!strcmp(token,"include")){wordNode->id=2;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"void")){wordNode->id=7;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"int")){wordNode->id=12;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"if")){wordNode->id=17;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"else")){wordNode->id=18;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"for")){wordNode->id=19;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"printf")){wordNode->id=20;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"scanf")){wordNode->id=21;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"sizeof")){wordNode->id=23;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"while")){wordNode->id=28;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"do")){wordNode->id=29;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"getch")){wordNode->id=30;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"main")){wordNode->id=37;strcpy(wordNode->name,token);}
          else if(!strcmp(token,"char")){wordNode->id=45;strcpy(wordNode->name,token);}
          //标示符
          else{wordNode->id=5;strcpy(wordNode->name,"标示符");strcpy(wordNode->value,token);}
     }
     //构造整数 
     else if(ch>='0'&&ch<='9'){
           while(ch>='0'&&ch<='9'){
                connect();
                getcharfromfile();   
           }     
           alreadyread=1;
           wordNode->id=6;strcpy(wordNode->name,token);
     }
     //构造运算符、界符 
     else{
          connect();
          switch(ch){
              case '+':
                      getcharfromfile(); 
                      if(ch=='+'){connect();wordNode->id=34;strcpy(wordNode->name,token);break;}
                      else{alreadyread=1;wordNode->id=31;strcpy(wordNode->name,token);break;}
                       
              case '-':
                      getcharfromfile(); 
                      if(ch=='-'){connect();wordNode->id=35;strcpy(wordNode->name,token);break;}
                      else{alreadyread=1;wordNode->id=32;strcpy(wordNode->name,token);break;}
              case '#':wordNode->id=1;strcpy(wordNode->name,token);break; 
              case '"':wordNode->id=3;strcpy(wordNode->name,token);break;  
              case '%':wordNode->id=4;strcpy(wordNode->name,token);break;    
              case '{': wordNode->id=8;strcpy(wordNode->name,token);break;
              case '}': wordNode->id=9;strcpy(wordNode->name,token);break;
              case '(': wordNode->id=10;strcpy(wordNode->name,token);break;
              case ')': wordNode->id=11;strcpy(wordNode->name,token);break;
              case '&': wordNode->id=13;strcpy(wordNode->name,token);break;
              case ';': wordNode->id=14;strcpy(wordNode->name,token);break;
              case '[': wordNode->id=15;strcpy(wordNode->name,token);break;
              case ']': wordNode->id=16;strcpy(wordNode->name,token);break;
              case '*': wordNode->id=22;strcpy(wordNode->name,token);break;
              case '<': 
                      getcharfromfile(); 
                      if(ch=='='){connect();wordNode->id=25;strcpy(wordNode->name,token);break;}
                      else{alreadyread=1;wordNode->id=24;strcpy(wordNode->name,token);break;}
              case '>': 
                      getcharfromfile(); 
                      if(ch=='='){connect();wordNode->id=27;strcpy(wordNode->name,token);break;}
                      else{alreadyread=1;wordNode->id=26;strcpy(wordNode->name,token);break;}                      
              case '/': 
                      getcharfromfile(); 
                      if(ch=='*'){
                            char ch1,ch2;
                            do{
                                ch1=ch2;
                                getcharfromfile(); 
                                ch2=ch;
                                if(feof(fp))return;
                            }while(ch1!='*'||ch2!='/');
                            ch='\n';//for exit
                            break;
                      }
                      else{alreadyread=1;wordNode->id=33;strcpy(wordNode->name,token);break;}                  
                      
              case '.': wordNode->id=39;strcpy(wordNode->name,token);break;
              case '\'': wordNode->id=40;strcpy(wordNode->name,token);break;
              case '\\': wordNode->id=46;strcpy(wordNode->name,token);break;
              case ':': wordNode->id=41;strcpy(wordNode->name,token);break;
              case '|': wordNode->id=43;strcpy(wordNode->name,token);break;
              case ',': wordNode->id=44;strcpy(wordNode->name,token);break;
              case '!': 
                      getcharfromfile(); 
                      if(ch=='='){connect();wordNode->id=36;strcpy(wordNode->name,token);break;}
                      else{alreadyread=1;wordNode->id=42;strcpy(wordNode->name,token);break;}              
                   
              case '=': wordNode->id=38;strcpy(wordNode->name,token);break;
              case '$': wordNode->id=47;strcpy(wordNode->name,token);break;//new~~~~~
              case '\n':break;
              case '\t':break;
              default:printf("\n an error has been found:\n");break;               
          }     
          
     }
}
//输出规约结果
void printfGY(wordnode * Stack,int j,int k){
      int i;
      printf("归约:");
      for(i=j;i<=k;i++)printf("%s ",Stack[i].name);
      printf("\n");
}
//输出移进的结果 
void printfYJ(wordnode * Stack,int i){
      printf("移进:");
      printf("%s%s",Stack[i].name,Stack[i].value);
      printf("\n");
}
/**
语法分析器 
*/
void SentenceAnalyse(){
     //int Stack[1000];
     wordnode *Stack=(wordnode*)malloc(1000*sizeof(wordnode));
     int k=0;
     int j;
     Stack[k].id=47;//$
     tableInit();
     while(!feof(fp)){
          getWord();
          if(ch!='\n'&&ch!='\t'){          
               if(Stack[k].id==-1)j=k-1;           
               else j=k; 
               //printf("%d %d ",j,wordNode->id);
               if(table[Stack[j].id][wordNode->id]==1||table[Stack[j].id][wordNode->id]==3){//(a<·b) or (a=·b) push in b
                    k++;                                                   
                    Stack[k].id=wordNode->id;   
                    strcpy(Stack[k].name,wordNode->name); 
                    strcpy(Stack[k].value,wordNode->value); 
                    printfYJ(Stack,k);
               }
               else if(table[Stack[j].id][wordNode->id]==2){              //a·>b stack out while Pj-1>·Pj
                    //int i;
                    while(table[Stack[j].id][wordNode->id]==2){
                        int pervious;
                        do{
                            //if(Stack[j].id==-1)j--;  //in case
                            pervious=Stack[j].id;                             //save the top-ermination
                            j--;
                            if(Stack[j].id==-1)j--;                        //find the near ermination in stack
                        }while(table[Stack[j].id][pervious]!=1);
                        printfGY(Stack,j+1,k);   
                        //move in a 'N'         
                        Stack[j+1].id=-1; 
                        strcpy(Stack[j+1].name,"N"); 
                        
                        //clear the old ones
                        strcpy(Stack[j+2].name,"");
                        strcpy(Stack[j+3].name,"");
                        //strcpy(Stack[j+4].name,"");
                        //strcpy(Stack[j+5].name,"");
                    }
                    //push in
                    k=j+2;
                    Stack[k].id=wordNode->id;
                    strcpy(Stack[k].name,wordNode->name);
                    strcpy(Stack[k].value,wordNode->value); 
                    printfYJ(Stack,k);
               }
               else{//error
                    printf("\nerror right after:");
                    int i;
                    for(i=1;i<=j;i++)printf("%s",Stack[i].name);
                    printf("\n");
                    break;  
               }
          }
          free(token);  
     }
     if(Stack[0].id==47&&Stack[1].id==-1&&Stack[2].id==47)printf("Nice sentense!");    
     else printf("Bad sentense!");                         
}


main(){
       //加载文件 
       Init();
       //分析文件
       SentenceAnalyse();
       //exit程序 
       exitPrograme();          
} 
























































































⌨️ 快捷键说明

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