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

📄 word_analyse.cpp

📁 C-语言的编译器中的词法分析和语法分析VC++开发
💻 CPP
字号:
#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>
#include<conio.h>
#define MAXTOKENLEN 40//
#define MAXLINE 1000
#define MAXRESERVED 6
#define FALSE 0
#define TRUE 1
#define BUFLEN 256//
using namespace std;

int   lineno=0; //
FILE* source; //
FILE* listing;//
int   linepos=0;//
static int bufsize=0;//
char file_in[100];
char file_out[100];
char lineBuf[MAXLINE];//
char tokenString[MAXTOKENLEN+1];


typedef enum 
{   ENDFILE,ERROR,
    ELSE,IF,INT,RETURN,VOID,WHILE,//keyword
    ID, NUM,
    ADD,SUB,MUL,DIV,LT,LE,GT,GE,EQ,NEQ,ASSIGN,SEMICOLON,COMMA,LSP,RSP,LMP,RMP,LLP,RLP
}TokenType;

typedef enum
{ 
        START, INASSIGN, SINCOMMENT, FINCOMMENT, INCOMMENT, 
        INNUM, INID, INL, ING,INNE, DONE ,
        
}StateType;

static struct
{    char* str;
     TokenType tok;
}reservedWords[MAXRESERVED]=
{{"else",ELSE},{"if",IF},{"int",INT},{"return",RETURN},{"void",VOID},{"while",WHILE}}; 

TokenType reservedLookup(char *s)
{    for(int i=0;i<MAXRESERVED;i++)
        if(!strcmp(s,reservedWords[i].str))return reservedWords[i].tok; 
     return ID;
}

char getNextChar(void)
{   
    if(linepos >= bufsize)
    {
        lineno++;
       
        if(fgets(lineBuf,BUFLEN-1,source)){
                 cout<<endl<<"line"<<lineno<<": "<<lineBuf<<endl;
                 bufsize = strlen(lineBuf);
                 linepos=0;
                 return lineBuf[linepos++];
        }
        else return EOF;
    } 
    else return lineBuf[linepos++];
}

void ungetNextChar(void)
{    linepos --;    }

bool isdigit(char c)//判断是不是数字 
{
     if(c >= '0' && c <= '9') return true;
     return false;
}

bool isalpha(char c)//判断是不是字母 
{
     if(c >=65 && c <=90 || c >= 97 && c <= 122) return true;
     return false;
}
//
TokenType getToken(void)
{ 
   int tokenStringIndex = 0;
   TokenType currentToken;
   StateType state = START;
   int save ;
   while (state != DONE)
   { char c = getNextChar();
     save = true;
     switch (state)
     { case START:
         if (isdigit(c))
           state = INNUM;
         else if (isalpha(c))
           state = INID;
         else if (c == ' ' || c == '\t'||c=='\n')
           save = false;
         else if (c == '=')
           state = INASSIGN;
         else if (c == '<')
           state = INL;
         else if (c == '>')  
           state = ING;
         else if (c == '!')
           state = INNE;
         else if (c == '/')
         { 
           save  = false;
           state = SINCOMMENT;
         }
         else 
         {
           state = DONE;
           switch(c)
           {  case EOF : save = false; currentToken = ENDFILE; break;
              case '+' : currentToken = ADD; break;
              case '-' : currentToken = SUB; break;
              case '*' : currentToken = MUL; break;
              case ';' : currentToken = SEMICOLON; break;
              case ',' : currentToken = COMMA; break;
              case '(' : currentToken = LSP; break;
              case ')' : currentToken = RSP; break;
              case '[' : currentToken = LMP; break;
              case ']' : currentToken = RMP; break;
              case '{' : currentToken = LLP; break;
              case '}' : currentToken = RLP; break;
              default  : currentToken = ERROR;break;
           }
         }
         break;
       case SINCOMMENT:
         if (c == '*')
         {  save  = false;
            state = INCOMMENT;
         }
         else
         { 
            c = '/';
            save = true;
            state = DONE;
            currentToken = DIV; // 
            ungetNextChar();
         }
         break;  
       case INCOMMENT:
         if (c == EOF)
         { state = DONE;
           currentToken = ENDFILE;
         }
         else if (c == '*') { state = FINCOMMENT; save  = false; }
         else save  = false;
         break;
       case FINCOMMENT:
         if (c == '/')
         {
            state = START;
            save  = false;
         }
         else if(c == '*') { state= FINCOMMENT; save  = false; }
         else { state = INCOMMENT; save  = false; }
         break;
       case INASSIGN:
         state = DONE;
         if (c == '=')
           currentToken = EQ;
         else
         { 
           ungetNextChar();
           save = false;
           currentToken = ASSIGN;
         }
         break;
       case INL:
         state = DONE;
         if (c == '=')
           currentToken = LE;
         else
         {
           ungetNextChar();
           save = false;
           currentToken = LT;
         }
         break;
       case ING:
         state = DONE;
         if (c == '=')
           currentToken = GE;
         else
         { 
           ungetNextChar();
           save = false;
           currentToken = GT;
         }
         break;
       case INNE:
         state = DONE;
         if (c == '=')
           currentToken = NEQ;
         else
         { 
           ungetNextChar();
           save = false;
           currentToken = ERROR;
         }
         break;
       case INNUM:
         if (!isdigit(c))
         { 
           ungetNextChar();
           save = false;
           state = DONE;
           currentToken = NUM;
         }
         break;
       case INID:
         if (!isalpha(c))
         {
           ungetNextChar();
           save = false;
           state = DONE;
           currentToken = ID;
         }
         break;
       case DONE:
       default: 
         cout<<listing<<"Scanner Bug: state= "<<state<<endl;
         state = DONE;
         currentToken = ERROR;
         break;
     }
     if ((save) && (tokenStringIndex <= MAXTOKENLEN)){
       tokenString[tokenStringIndex++] = (char) c;
       }
     if (state == DONE)
     { tokenString[tokenStringIndex] = '\0';
       if (currentToken == ID)
         currentToken = reservedLookup(tokenString);
     }
   }
   return currentToken;
} 

void printToken(TokenType token,char * tokenString)
{
   switch(token)
   {   case ERROR      : cout<<lineno<<": ERROE!"<<endl;
                         fprintf(listing,"    %d: ERROE  %s\n",lineno,tokenString);break;
       case ENDFILE    : cout<<"END OF FILE!"<<endl; fprintf(listing,"%s\n",tokenString);break;
       case ELSE       : cout<<lineno<<": Keyword     "<<tokenString<<endl;
                         fprintf(listing,"    %d: Keyword     %s\n",lineno,tokenString);break;
       case IF         : cout<<lineno<<": Keyword     "<<tokenString<<endl;
                         fprintf(listing,"    %d: Keyword     %s\n",lineno,tokenString);break;
       case INT        : cout<<lineno<<": Keyword     "<<tokenString<<endl;
                         fprintf(listing,"    %d: Keyword     %s\n",lineno,tokenString);break;
       case RETURN     : cout<<lineno<<": Keyword     "<<tokenString<<endl;
                         fprintf(listing,"    %d: Keyword     %s\n",lineno,tokenString);break;
       case VOID       : cout<<lineno<<": Keyword     "<<tokenString<<endl;
                         fprintf(listing,"    %d: Keyword     %s\n",lineno,tokenString);break;
       case WHILE      : cout<<lineno<<": Keyword     "<<tokenString<<endl;
                         fprintf(listing,"    %d: Keyword     %s\n",lineno,tokenString);break;
       case ID         : cout<<lineno<<": Identifier  "<<tokenString<<endl;
                         fprintf(listing,"    %d: Identifier  %s\n",lineno,tokenString);break;
       case NUM        : cout<<lineno<<": Number      "<<tokenString<<endl;
                         fprintf(listing,"    %d: Number      %s\n",lineno,tokenString);break;
       case ADD        : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case SUB        : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case MUL        : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case DIV        : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case LT         : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case LE         : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case GT         : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case GE         : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case EQ         : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case NEQ        : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case ASSIGN     : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case SEMICOLON  : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case COMMA      : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case LSP        : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case RSP        : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case LMP        : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case RMP        : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case LLP        : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break;
       case RLP        : cout<<lineno<<": Sign        "<<tokenString<<endl;
                         fprintf(listing,"    %d: Sign        %s\n",lineno,tokenString);break; 
       default         : fprintf(listing,"\n");break;
   }
}

int main()
{
    int i ;
    cout<< "***************************************"<<endl; 
    cout<<"请输入源文件名(包括路径和后缀名):"<<endl;
    while(cin>>file_in)
    {  if ((source = fopen(file_in,"r")) == NULL) 
           printf("cannot open infile,please input again:\n");
       else break;
    }
    cout<<endl;
    strcpy(file_out,"aa.txt");
    if ((listing = fopen(file_out,"w")) == NULL)
    {
        printf("cannot open infile\n");
        getch();
        exit(0);
    }
    lineno = 1;
    TokenType c;
    while ((c=getToken())!=ENDFILE) printToken(c,tokenString);
    fclose(source);
    fclose(listing);
    cout<<"****************************************"<<endl;
    listing=fopen(file_out,"r");
    char ch = fgetc(listing);
    while(ch!=EOF){
                   putchar(ch);
                   ch = fgetc(listing);
                   }
    fclose(listing);
    system("pause");
    return 0;
}

⌨️ 快捷键说明

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