程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++寫的一個簡單的詞法分析器(分析C語言)

C++寫的一個簡單的詞法分析器(分析C語言)

編輯:C++入門知識

實驗用:

幾點注意:

1.代碼又長又臭,時間關系,沒有優化,冗余項多(我都看不下去了。囧)

2.加了一下簡單的錯誤檢測。(在mapping.h中定義了錯誤類型,可以查閱)

3.使用頭文件宏定義來模擬符號表,也可以用文件

4.對於標志符的入口地址,無非是為了唯一識別,只要名字相同,都作為一個,使用自增的Int來模擬入口地址,即唯一標識。不考慮變量類型。

5.最後輸出有三個表:Token表,錯誤表,標志符表。

6.一個字符一個字符的讀文件,其實可以每次讀到一個固定長度的緩沖區,雙緩沖區進行分析。也可以讀每一行。

代碼:

mapping.h:

[cpp]
/*
頭文件:mapping.h
*/ 
 
//關鍵字 
#define AUTO 1 
#define BREAK 2 
#define CASE 3 
#define CHAR 4 
#define CONST 5 
#define CONTINUE 6 
#define DEFAULT 7 
#define DO 8 
#define DOUBLE 9 
#define ELSE 10 
#define ENUM 11 
#define EXTERN 12 
#define FLOAT 13 
#define FOR 14 
#define GOTO 15 
#define IF 16 
#define INT 17 
#define LONG 18 
#define REGISTER 19 
#define RETURN 20 
#define SHORT 21 
#define SIGNED 22 
#define SIZEOF 23 
#define STATIC 24 
#define STRUCT 25 
#define SWITCH 26 
#define TYPEDEF 27 
#define UNION 28 
#define UNSIGNED 29 
#define VOID 30 
#define VOLATILE 31 
#define WHILE 32 
#define KEY_DESC "關鍵字" 
 
//標志符 
#define IDENTIFER 40 
#define IDENTIFER_DESC "標志符" 
 
//常量 
#define INT_VAL 51 //整形常量 
#define CHAR_VAL 52 //字符常量 
#define FLOAT_VAL 53 //浮點數常量 
#define STRING_VAL 54 //雙精度浮點數常量 
#define MACRO_VAL 55 //宏常量 
#define CONSTANT_DESC "常量" 
 
//運算符 
#define NOT 61   // ! 
#define BYTE_AND 62 //& 
#define COMPLEMENT 63 // ~ 
#define BYTE_XOR  64 // ^ 
#define MUL 65 // * 
#define DIV 66// / 
#define MOD 67 // % 
#define ADD 68 // + 
#define SUB 69 // - 
#define LES_THAN 70 // < 
#define GRT_THAN 71 // > 
#define ASG 72 // = 
#define ARROW 73 // -> 
#define SELF_ADD 74 // ++ 
#define SELF_SUB 75 // -- 
#define LEFT_MOVE 76 // << 
#define RIGHT_MOVE 77 // >> 
#define LES_EQUAL 78 // <= 
#define GRT_EQUAL 79 // >= 
#define EQUAL 80 // == 
#define NOT_EQUAL 81 // != 
#define AND 82 // && 
#define OR 83 // || 
#define COMPLETE_ADD 84 // += 
#define COMPLETE_SUB 85 // -= 
#define COMPLETE_MUL 86 // *= 
#define COMPLETE_DIV 87 // /= 
#define COMPLETE_BYTE_XOR 88 // ^= 
#define COMPLETE_BYTE_AND 89 // &= 
#define COMPLETE_COMPLEMENT 90 // ~= 
#define COMPLETE_MOD 91 //%= 
#define BYTE_OR 92 // | 
 
#define OPE_DESC "運算符" 
 
//限界符 
#define LEFT_BRA 100 // ( 
#define RIGHT_BRA 101 // ) 
#define LEFT_INDEX 102 // [ 
#define RIGHT_INDEX 103 // ] 
#define L_BOUNDER 104 //  { 
#define R_BOUNDER 105 // } 
#define POINTER 106 // . 
#define JING 107 // # 
#define UNDER_LINE 108 // _ 
#define COMMA 109 // , 
#define SEMI 110 // ; 
#define SIN_QUE 111 // ' 
#define DOU_QUE 112 // " 
 
#define CLE_OPE_DESC "限界符" 
 
#define NOTE1 120 // "/**/"注釋 
#define NOTE2 121 // "//"注釋 
#define NOTE_DESC "注釋" 
 
 
#define HEADER 130 //頭文件 
#define HEADER_DESC "頭文件" 
 
//錯誤類型 
#define FLOAT_ERROR "float表示錯誤" 
#define FLOAT_ERROR_NUM 1 
#define DOUBLE_ERROR "double表示錯誤" 
#define DOUBLE_ERROR_NUM 2 
#define NOTE_ERROR "注釋沒有結束符" 
#define NOTE_ERROR_NUM 3 
#define STRING_ERROR "字符串常量沒有結束符" 
#define STRING_ERROR_NUM 4 
#define CHARCONST_ERROR "字符常量沒有結束符" 
#define CHARCONST_ERROR_NUM 5 
#define CHAR_ERROR "非法字符" 
#define CHAR_ERROR_NUM 6 
#define LEFT_BRA_ERROR "'('沒有對應項" 
#define LEFT_BRA_ERROR_NUM 7 
#define RIGHT_BRA_ERROR "')'沒有對應項" 
#define RIGHT_BRA_ERROR_NUM 8 
#define LEFT_INDEX_ERROR "'['沒有對應項" 
#define LEFT_INDEX_ERROR_NUM 9 
#define RIGHT_INDEX_ERROR "']'沒有對應項" 
#define RIGHT_INDEX_ERROR_NUM 10 
#define L_BOUNDER_ERROR "'{'沒有對應項" 
#define L_BOUNDER_ERROR_NUM 11 
#define R_BOUNDER_ERROR "'}'沒有對應項" 
#define R_BOUNDER_ERROR_NUM 12 
#define PRE_PROCESS_ERROR "預處理錯誤" //頭文件或者宏定義錯誤 
#define PRE_PROCESS_ERROR_NUM  13 
 
#define _NULL "無" 

main.cpp:
[cpp] 
//main.cpp 
 
#include <iostream> 
#include <fstream> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <iomanip> 
#include "mapping.h" 
 
using namespace std; 
 
const char * key[] = {"auto","break","case","char","const","continue","default","do","double", 
                      "else","enum","extern","float","for","goto","if","int","long","register", 
                      "return","short","signed","sizeof","static","struct","switch","typedef", 
                      "union","unsigned","void","volatile","while" 
                     };//C語言的關鍵字 
int leftSmall = 0;//左小括號 
int rightSmall = 0;//右小括號 
int leftMiddle = 0;//左中括號 
int rightMiddle = 0;//右中括號 
int leftBig = 0;//左大括號 
int rightBig = 0;//右大括號 
int lineBra[6][1000] = {0};//括號和行數的對應關系,第一維代表左右6種括號 
int static_iden_number = 0;//模擬標志符的地址,自增 
//Token節點 
struct NormalNode 

    char content[30];//內容 
    char describe[30];//描述 
    int type;//種別碼 
    int addr;//入口地址 
    int line;//所在行數 
    NormalNode * next;//下一個節點 
}; 
 
NormalNode * normalHead;//首結點 
 
//錯誤節點 
struct ErrorNode 

    char content[30];//錯誤內容 
    char describe[30];//錯誤描述 
    int type; 
    int line;//所在行數 
    ErrorNode * next;//下一個節點 
}; 
 
ErrorNode * errorHead;//首節點 
 
//標志符節點 
struct IdentiferNode 

    char content[30];//內容 
    char describe[30];//描述 
    int type;//種別碼 
    int addr;//入口地址 
    int line;//所在行數 
    IdentiferNode * next;//下一個節點 
}; 
IdentiferNode * idenHead;//首節點 
 
 
void initNode() 

    normalHead = new NormalNode(); 
    strcpy(normalHead->content,""); 
    strcpy(normalHead->describe,""); 
    normalHead->type = -1; 
    normalHead->addr = -1; 
    normalHead->line = -1; 
    normalHead->next = NULL; 
 
    errorHead = new ErrorNode(); 
    strcpy(errorHead->content,""); 
    strcpy(errorHead->describe,""); 
    errorHead->line = -1; 
    errorHead->next = NULL; 
 
    idenHead = new IdentiferNode(); 
    strcpy(idenHead->content,""); 
    strcpy(idenHead->describe,""); 
    idenHead->type = -1; 
    idenHead->addr = -1; 
    idenHead->line = -1; 
    idenHead->next = NULL; 

 
void createNewNode(char * content,char *descirbe,int type,int addr,int line) 

    NormalNode * p = normalHead; 
    NormalNode * temp = new NormalNode(); 
 
    while(p->next!=NULL) 
    { 
        p = p->next; 
    } 
 
    strcpy(temp->content,content); 
    strcpy(temp->describe,descirbe); 
    temp->type = type; 
    temp->addr = addr; 
    temp->line = line; 
    temp->next = NULL; 
 
    p->next = temp; 

void createNewError(char * content,char *descirbe,int type,int line) 

    ErrorNode * p = errorHead; 
    ErrorNode * temp = new ErrorNode(); 
 
    strcpy(temp->content,content); 
    strcpy(temp->describe,descirbe); 
    temp->type = type; 
    temp->line = line; 
    temp->next = NULL; 
    while(p->next!=NULL) 
    { 
        p = p->next; 
    } 
    p->next = temp; 

//返回值是新的標志符的入口地址 
int createNewIden(char * content,char *descirbe,int type,int addr,int line) 

    IdentiferNode * p = idenHead; 
    IdentiferNode * temp = new IdentiferNode(); 
    int flag = 0; 
    int addr_temp = -2; 
    while(p->next!=NULL) 
    { 
        if(strcmp(content,p->next->content) == 0) 
        { 
            flag = 1; 
            addr_temp = p->next->addr; 
        } 
        p = p->next; 
    } 
    if(flag == 0) 
    { 
        addr_temp = ++static_iden_number;//用自增來模擬入口地址 
    } 
    strcpy(temp->content,content); 
    strcpy(temp->describe,descirbe); 
    temp->type = type; 
    temp->addr = addr_temp; 
    temp->line = line; 
    temp->next = NULL; 
    p->next = temp; 
    return addr_temp; 

 
void printNodeLink() 

    NormalNode * p = normalHead; 
    p = p->next; 
    cout<<"************************************分析表******************************"<<endl<<endl; 
    cout<<setw(30)<<"內容"<<setw(10)<<"描述"<<"\t"<<"種別碼"<<"\t"<<"地址"<<"\t"<<"行號"<<endl; 
    while(p!=NULL) 
    { 
        if(p->type == IDENTIFER) 
        { 
            cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<p->addr<<"\t"<<p->line<<endl; 
        } 
        else 
        { 
            cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<"\t"<<p->line<<endl; 
        } 
        p = p->next; 
    } 
    cout<<endl<<endl; 

/*
錯誤種類:
1.float表示錯誤
2.double表示錯誤
3.注釋沒有結束符
4.字符串常量沒有結束符
5.字符常量沒有結束符
6.非法字符
7.'('沒有對應項
8.預處理錯誤
*/ 
void printErrorLink() 

    ErrorNode * p = errorHead; 
    p = p->next; 
    cout<<"************************************錯誤表******************************"<<endl<<endl; 
    cout<<setw(10)<<"內容"<<setw(30)<<"描述"<<"\t"<<"類型"<<"\t"<<"行號"<<endl; 
    while(p!=NULL) 
    { 
        cout<<setw(10)<<p->content<<setw(30)<<p->describe<<"\t"<<p->type<<"\t"<<p->line<<endl; 
        p = p->next; 
    } 
    cout<<endl<<endl; 

//標志符表,有重復部分,暫不考慮 
void printIdentLink() 

    IdentiferNode * p = idenHead; 
    p = p->next; 
    cout<<"************************************標志符表******************************"<<endl<<endl; 
    cout<<setw(30)<<"內容"<<setw(10)<<"描述"<<"\t"<<"種別碼"<<"\t"<<"地址"<<"\t"<<"行號"<<endl; 
    while(p!=NULL) 
    { 
        cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<p->addr<<"\t"<<p->line<<endl; 
        p = p->next; 
    } 
    cout<<endl<<endl; 

int mystrlen(char * word) 

    if(*word == '\0') 
    { 
        return 0; 
    } 
    else 
    { 
        return 1+mystrlen(word+1); 
    } 

//預處理,處理頭文件和宏定義 
void preProcess(char * word,int line) 

    const char * include_temp = "include"; 
    const char * define_temp = "define"; 
    char * p_include,*p_define; 
    int flag = 0; 
    p_include = strstr(word,include_temp); 
    if(p_include!=NULL) 
    { 
        flag = 1; 
        int i; 
        for(i=7;;) 
        { 
            if(*(p_include+i) == ' ' || *(p_include+i) == '\t') 
            { 
                i++; 
            } 
            else 
            { 
                break; 
            } 
        } 
        createNewNode(p_include+i,HEADER_DESC,HEADER,-1,line); 
    } 
    else 
    { 
        p_define = strstr(word,define_temp); 
        if(p_define!=NULL) 
        { 
            flag = 1; 
            int i; 
            for(i=7;;) 
            { 
                if(*(p_define+i) == ' ' || *(p_define+i) == '\t') 
                { 
                    i++; 
                } 
                else 
                { 
                    break; 
                } 
            } 
            createNewNode(p_define+i,CONSTANT_DESC,MACRO_VAL,-1,line); 
        } 
    } 
    if(flag == 0) 
    { 
        createNewError(word,PRE_PROCESS_ERROR,PRE_PROCESS_ERROR_NUM,line); 
    } 

 
void close() 

    delete idenHead; 
    delete errorHead; 
    delete normalHead; 

 
int seekKey(char * word) 

    for(int i=0; i<32; i++) 
    { 
        if(strcmp(word,key[i]) == 0) 
        { 
            return i+1; 
        } 
    } 
    return IDENTIFER; 

 
void scanner() 

    char filename[30]; 
    char ch; 
    char array[30];//單詞長度上限是30 
    char * word; 
    int i; 
    int line = 1;//行數 
 
 
    FILE * infile; 
    printf("請輸入要進行語法分析的C語言程序:\n"); 
    scanf("%s",filename); 
    infile = fopen(filename,"r"); 
    while(!infile) 
    { 
        printf("打開文件失敗!\n"); 
        return; 
    } 
    ch = fgetc(infile); 
    while(ch!=EOF) 
    { 
 
        i = 0; 
        //以字母或者下劃線開頭,處理關鍵字或者標識符 
        if((ch>='A' && ch<='Z') || (ch>='a' && ch<='z') || ch == '_') 
        { 
            while((ch>='A' && ch<='Z')||(ch>='a' && ch<='z')||(ch>='0' && ch<='9') || ch == '_') 
            { 
                array[i++] = ch; 
                ch = fgetc(infile); 
            } 
            word = new char[i+1]; 
            memcpy(word,array,i); 
            word[i] = '\0'; 
            int seekTemp = seekKey(word); 
            if(seekTemp!=IDENTIFER) 
            { 
                createNewNode(word,KEY_DESC,seekTemp,-1,line); 
            } 
            else 
            { 
                int addr_tmp = createNewIden(word,IDENTIFER_DESC,seekTemp,-1,line); 
                createNewNode(word,IDENTIFER_DESC,seekTemp,addr_tmp,line); 
            } 
            fseek(infile,-1L,SEEK_CUR);//向後回退一位 
        } 
        //以數字開頭,處理數字 
        else if(ch >='0' && ch<='9') 
        { 
            int flag = 0; 
            int flag2 = 0; 
            //處理整數 
            while(ch >='0' && ch<='9') 
            { 
                array[i++] = ch; 
                ch = fgetc(infile); 
            } 
            //處理float 
            if(ch == '.') 
            { 
                flag2 = 1; 
                array[i++] = ch; 
                ch = fgetc(infile); 
                if(ch>='0' && ch<='9') 
                { 
                    while(ch>='0' && ch<='9') 
                    { 
                        array[i++] = ch; 
                        ch = fgetc(infile); 
                    } 
                } 
                else 
                { 
                    flag = 1; 
                } 
 
                //處理Double 
                if(ch == 'E' || ch == 'e') 
                { 
                    array[i++] = ch; 
                    ch = fgetc(infile); 
                    if(ch == '+' || ch == '-') 
                    { 
                        array[i++] = ch; 
                        ch = fgetc(infile); 
                    } 
                    if(ch >='0' && ch<='9') 
                    { 
                        array[i++] = ch; 
                        ch = fgetc(infile); 
                    } 
                    else 
                    { 
                        flag = 2; 
                    } 
                } 
 
            } 
            word = new char[i+1]; 
            memcpy(word,array,i); 
            word[i] = '\0'; 
            if(flag == 1) 
            { 
                createNewError(word,FLOAT_ERROR,FLOAT_ERROR_NUM,line); 
            } 
            else if(flag == 2) 
            { 
                createNewError(word,DOUBLE_ERROR,DOUBLE_ERROR_NUM,line); 
            } 
            else 
            { 
                if(flag2 == 0) 
                { 
                    createNewNode(word,CONSTANT_DESC,INT_VAL,-1,line); 
                } 
                else 
                { 
                    createNewNode(word,CONSTANT_DESC,FLOAT_VAL,-1,line); 
                } 
            } 
            fseek(infile,-1L,SEEK_CUR);//向後回退一位 
        } 
        //以"/"開頭 
        else if(ch == '/') 
        { 
            ch = fgetc(infile); 
            //處理運算符"/=" 
            if(ch == '=') 
            { 
                createNewNode("/=",OPE_DESC,COMPLETE_DIV,-1,line); 
            } 
            //處理"/**/"型注釋 
            else if(ch == '*') 
            { 
                ch =  fgetc(infile); 
                while(1) 
                { 
                    while(ch != '*') 
                    { 
                        if(ch == '\n') 
                        { 
                            line++; 
                        } 
                        ch = fgetc(infile); 
                        if(ch == EOF) 
                        { 
                            createNewError(_NULL,NOTE_ERROR,NOTE_ERROR_NUM,line); 
                            return; 
                        } 
                    } 
                    ch = fgetc(infile); 
                    if(ch == '/') 
                    { 
                        break; 
                    } 
                    if(ch == EOF) 
                    { 
                        createNewError(_NULL,NOTE_ERROR,NOTE_ERROR_NUM,line); 
                        return; 
                    } 
                } 
                createNewNode(_NULL,NOTE_DESC,NOTE1,-1,line); 
            } 
            //處理"//"型注釋 
            else if(ch == '/') 
            { 
                while(ch!='\n') 
                { 
                    ch = fgetc(infile); 
                    if(ch == EOF) 
                    { 
                        createNewNode(_NULL,NOTE_DESC,NOTE2,-1,line); 
                        return; 
                    } 
                } 
                line++; 
                createNewNode(_NULL,NOTE_DESC,NOTE2,-1,line); 
                if(ch == EOF) 
                { 
                    return; 
                } 
            } 
            //處理除號 
            else 
            { 
                createNewNode("/",OPE_DESC,DIV,-1,line); 
            } 
        } 
        //處理常量字符串 
        else if(ch == '"') 
        { 
            createNewNode("\"",CLE_OPE_DESC,DOU_QUE,-1,line); 
            ch = fgetc(infile); 
            i = 0; 
            while(ch!='"') 
            { 
                array[i++] = ch; 
                if(ch == '\n') 
                { 
                    line++; 
                } 
                ch = fgetc(infile); 
                if(ch == EOF) 
                { 
                    createNewError(_NULL,STRING_ERROR,STRING_ERROR_NUM,line); 
                    return; 
                } 
            } 
            word = new char[i+1]; 
            memcpy(word,array,i); 
            word[i] = '\0'; 
            createNewNode(word,CONSTANT_DESC,STRING_VAL,-1,line); 
            createNewNode("\"",CLE_OPE_DESC,DOU_QUE,-1,line); 
        } 
        //處理常量字符 
        else if(ch == '\'') 
        { 
            createNewNode("\'",CLE_OPE_DESC,SIN_QUE,-1,line); 
            ch = fgetc(infile); 
            i = 0; 
            while(ch!='\'') 
            { 
                array[i++] = ch; 
                if(ch == '\n') 
                { 
                    line++; 
                } 
                ch = fgetc(infile); 
                if(ch == EOF) 
                { 
                    createNewError(_NULL,CHARCONST_ERROR,CHARCONST_ERROR_NUM,line); 
                    return; 
                } 
            } 
            word = new char[i+1]; 
            memcpy(word,array,i); 
            word[i] = '\0'; 
            createNewNode(word,CONSTANT_DESC,CHAR_VAL,-1,line); 
            createNewNode("\'",CLE_OPE_DESC,SIN_QUE,-1,line); 
        } 
        else if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') 
        { 
            if(ch == '\n') 
            { 
                line++; 
            } 
        } 
        else 
        { 
            if(ch == EOF) 
            { 
                return; 
            } 
            //處理頭文件和宏常量(預處理) 
            else if(ch == '#') 
            { 
                while(ch!='\n' && ch!=EOF) 
                { 
                    array[i++] = ch; 
                    ch = fgetc(infile); 
                } 
                word = new char[i+1]; 
                memcpy(word,array,i); 
                word[i] = '\0'; 
                preProcess(word,line); 
 
                fseek(infile,-1L,SEEK_CUR);//向後回退一位 
            } 
            //處理-開頭的運算符 
            else if(ch == '-') 
            { 
                array[i++] = ch; 
                ch = fgetc(infile); 
                if(ch >='0' && ch<='9') 
                { 
                    int flag = 0; 
                    int flag2 = 0; 
                    //處理整數 
                    while(ch>='0' && ch<='9') 
                    { 
                        array[i++] = ch; 
                        ch = fgetc(infile); 
                    } 
                    //處理float 
                    if(ch == '.') 
                    { 
                        flag2 = 1; 
                        array[i++] = ch; 
                        ch = fgetc(infile); 
                        if(ch>='0' && ch<='9') 
                        { 
                            while(ch>='0' && ch<='9') 
                            { 
                                array[i++] = ch; 
                                ch = fgetc(infile); 
                            } 
                        } 
                        else 
                        { 
                            flag = 1; 
                        } 
                        //處理Double 
                        if(ch == 'E' || ch == 'e') 
                        { 
                            array[i++] = ch; 
                            ch = fgetc(infile); 
                            if(ch == '+' || ch == '-') 
                            { 
                                array[i++] = ch; 
                                ch = fgetc(infile); 
                            } 
                            if(ch >='0' && ch<='9') 
                            { 
                                array[i++] = ch; 
                                ch = fgetc(infile); 
                            } 
                            else 
                            { 
                                flag = 2; 
                            } 
                        } 
                    } 
                    word = new char[i+1]; 
                    memcpy(word,array,i); 
                    word[i] = '\0'; 
                    if(flag == 1) 
                    { 
                        createNewError(word,FLOAT_ERROR,FLOAT_ERROR_NUM,line); 
                    } 
                    else if(flag == 2) 
                    { 
                        createNewError(word,DOUBLE_ERROR,DOUBLE_ERROR_NUM,line); 
                    } 
                    else 
                    { 
                        if(flag2 == 0) 
                        { 
                            createNewNode(word,CONSTANT_DESC,INT_VAL,-1,line); 
                        } 
                        else 
                        { 
                            createNewNode(word,CONSTANT_DESC,FLOAT_VAL,-1,line); 
                        } 
                    } 
                    fseek(infile,-1L,SEEK_CUR);//向後回退一位 
                } 
                else if(ch == '>') 
                { 
                    createNewNode("->",OPE_DESC,ARROW,-1,line); 
                } 
                else if(ch == '-') 
                { 
                    createNewNode("--",OPE_DESC,SELF_SUB,-1,line); 
                } 
                else if(ch == '=') 
                { 
                    createNewNode("--",OPE_DESC,SELF_SUB,-1,line); 
                } 
                else 
                { 
                    createNewNode("-",OPE_DESC,SUB,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            //處理+開頭的運算符 
            else if(ch == '+') 
            { 
                ch = fgetc(infile); 
                if(ch == '+') 
                { 
                    createNewNode("++",OPE_DESC,SELF_ADD,-1,line); 
                } 
                else if(ch == '=') 
                { 
                    createNewNode("+=",OPE_DESC,COMPLETE_ADD,-1,line); 
                } 
                else 
                { 
                    createNewNode("+",OPE_DESC,ADD,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            //處理*開頭的運算符 
            else if(ch == '*') 
            { 
                ch = fgetc(infile); 
                if(ch == '=') 
                { 
                    createNewNode("*=",OPE_DESC,COMPLETE_MUL,-1,line); 
                } 
                else 
                { 
                    createNewNode("*",OPE_DESC,MUL,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            //處理按^開頭的運算符 
            else if(ch == '^') 
            { 
                ch = fgetc(infile); 
                if(ch == '=') 
                { 
                    createNewNode("^=",OPE_DESC,COMPLETE_BYTE_XOR,-1,line); 
                } 
                else 
                { 
                    createNewNode("^",OPE_DESC,BYTE_XOR,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            //處理%開頭的運算符 
            else if(ch == '%') 
            { 
                ch = fgetc(infile); 
                if(ch == '=') 
                { 
                    createNewNode("%=",OPE_DESC,COMPLETE_MOD,-1,line); 
                } 
                else 
                { 
                    createNewNode("%",OPE_DESC,MOD,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            //處理&開頭的運算符 
            else if(ch == '&') 
            { 
                ch = fgetc(infile); 
                if(ch == '=') 
                { 
                    createNewNode("&=",OPE_DESC,COMPLETE_BYTE_AND,-1,line); 
                } 
                else if(ch == '&') 
                { 
                    createNewNode("&&",OPE_DESC,AND,-1,line); 
                } 
                else 
                { 
                    createNewNode("&",OPE_DESC,BYTE_AND,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            //處理~開頭的運算符 
            else if(ch == '~') 
            { 
                ch = fgetc(infile); 
                if(ch == '=') 
                { 
                    createNewNode("~=",OPE_DESC,COMPLETE_COMPLEMENT,-1,line); 
                } 
                else 
                { 
                    createNewNode("~",OPE_DESC,COMPLEMENT,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            //處理!開頭的運算符 
            else if(ch == '!') 
            { 
                ch = fgetc(infile); 
                if(ch == '=') 
                { 
                    createNewNode("!=",OPE_DESC,NOT_EQUAL,-1,line); 
                } 
                else 
                { 
                    createNewNode("!",OPE_DESC,NOT,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            //處理<開頭的運算符 
            else if(ch == '<') 
            { 
                ch = fgetc(infile); 
                if(ch == '<') 
                { 
                    createNewNode("<<",OPE_DESC,LEFT_MOVE,-1,line); 
                } 
                else if(ch == '=') 
                { 
                    createNewNode("<=",OPE_DESC,LES_EQUAL,-1,line); 
                } 
                else 
                { 
                    createNewNode("<",OPE_DESC,LES_THAN,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            //處理>開頭的運算符 
            else if(ch == '>') 
            { 
                ch = fgetc(infile); 
                if(ch == '>') 
                { 
                    createNewNode(">>",OPE_DESC,RIGHT_MOVE,-1,line); 
                } 
                else if(ch == '=') 
                { 
                    createNewNode(">=",OPE_DESC,GRT_EQUAL,-1,line); 
                } 
                else 
                { 
                    createNewNode(">",OPE_DESC,GRT_THAN,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            //處理|開頭的運算符 
            else if(ch == '|') 
            { 
                ch = fgetc(infile); 
                if(ch == '|') 
                { 
                    createNewNode("||",OPE_DESC,OR,-1,line); 
                } 
                else 
                { 
                    createNewNode("|",OPE_DESC,BYTE_OR,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            else if(ch == '=') 
            { 
                ch = fgetc(infile); 
                if(ch == '=') 
                { 
                    createNewNode("==",OPE_DESC,EQUAL,-1,line); 
                } 
                else 
                { 
                    createNewNode("=",OPE_DESC,ASG,-1,line); 
                    fseek(infile,-1L,SEEK_CUR); 
                } 
            } 
            else if(ch == '(') 
            { 
                leftSmall++; 
                lineBra[0][leftSmall] = line; 
                createNewNode("(",CLE_OPE_DESC,LEFT_BRA,-1,line); 
            } 
            else if(ch == ')') 
            { 
                rightSmall++; 
                lineBra[1][rightSmall] = line; 
                createNewNode(")",CLE_OPE_DESC,RIGHT_BRA,-1,line); 
            } 
            else if(ch == '[') 
            { 
                leftMiddle++; 
                lineBra[2][leftMiddle] = line; 
                createNewNode("[",CLE_OPE_DESC,LEFT_INDEX,-1,line); 
            } 
            else if(ch == ']') 
            { 
                rightMiddle++; 
                lineBra[3][rightMiddle] = line; 
                createNewNode("]",CLE_OPE_DESC,RIGHT_INDEX,-1,line); 
            } 
            else if(ch == '{') 
            { 
                leftBig++; 
                lineBra[4][leftBig] = line; 
                createNewNode("{",CLE_OPE_DESC,L_BOUNDER,-1,line); 
            } 
            else if(ch == '}') 
            { 
                rightBig++; 
                lineBra[5][rightBig] = line; 
                createNewNode("}",CLE_OPE_DESC,R_BOUNDER,-1,line); 
            } 
            else if(ch == '.') 
            { 
                createNewNode(".",CLE_OPE_DESC,POINTER,-1,line); 
            } 
            else if(ch == ',') 
            { 
                createNewNode(",",CLE_OPE_DESC,COMMA,-1,line); 
            } 
            else if(ch == ';') 
            { 
                createNewNode(";",CLE_OPE_DESC,SEMI,-1,line); 
            } 
            else 
            { 
                char temp[2]; 
                temp[0] = ch; 
                temp[1] = '\0'; 
                createNewError(temp,CHAR_ERROR,CHAR_ERROR_NUM,line); 
            } 
        } 
        ch = fgetc(infile); 
    } 

void BraMappingError() 

    if(leftSmall != rightSmall) 
    { 
        int i = (leftSmall>rightSmall) ? (leftSmall-rightSmall) : (rightSmall - leftSmall); 
        bool  flag = (leftSmall>rightSmall) ? true : false; 
        if(flag) 
        { 
            while(i--) 
            { 
                createNewError(_NULL,LEFT_BRA_ERROR,LEFT_BRA_ERROR_NUM,lineBra[0][i+1]); 
            } 
        } 
        else 
        { 
            while(i--) 
            { 
                createNewError(_NULL,RIGHT_BRA_ERROR,RIGHT_BRA_ERROR_NUM,lineBra[1][i+1]); 
            } 
        } 
    } 
    if(leftMiddle != rightMiddle) 
    { 
        int i = (leftMiddle>rightMiddle) ? (leftMiddle-rightMiddle) : (rightMiddle - leftMiddle); 
        bool flag = (leftMiddle>rightMiddle) ? true : false; 
        if(flag) 
        { 
            while(i--) 
            { 
                createNewError(_NULL,LEFT_INDEX_ERROR,LEFT_INDEX_ERROR_NUM,lineBra[2][i+1]); 
            } 
        } 
        else 
        { 
            while(i--) 
            { 
                createNewError(_NULL,RIGHT_INDEX_ERROR,RIGHT_INDEX_ERROR_NUM,lineBra[3][i+1]); 
            } 
        } 
    } 
    if(leftBig != rightBig) 
    { 
        int i = (leftBig>rightBig) ? (leftBig-rightBig) : (rightBig - leftSmall); 
        bool flag = (leftBig>rightBig) ? true : false; 
        if(flag) 
        { 
            while(i--) 
            { 
                createNewError(_NULL,L_BOUNDER_ERROR,L_BOUNDER_ERROR_NUM,lineBra[4][i+1]); 
            } 
        } 
        else 
        { 
            while(i--) 
            { 
                createNewError(_NULL,R_BOUNDER_ERROR,R_BOUNDER_ERROR_NUM,lineBra[5][i+1]); 
            } 
        } 
    } 

 
int main() 

    initNode(); 
    scanner(); 
    BraMappingError(); 
    printNodeLink(); 
    printErrorLink(); 
    printIdentLink(); 
    close(); 
    return 0; 

測試的C文件:test.c(一個錯誤很多的C程序)

[cpp] view plaincopy
#include          <stdio.h> 
#include "my.h" 
#define max 90 
#de some 
 
int char main() 

    8888char yn; 
    do 
    { 
    int 9801; 
    float 9.; 
    double 9.ef; 
    float -9.876; 
    double hello.8.9; 
    float 7.9e-5; 
    int e-5; 
    a /= 6; 
        init(); /*初始化*/ 
        scanner();//掃描源程序// 
        printf("Are You continue(y/n)\n"); 
        yn=getch(); 
    if(a == 7) 
    { 
         
    } 
    else 
    { 
         
    } 

 
    } 
    while(yn=='y'||yn=='Y'); 
     
    return 0; 
[hello 
     
 
 
 
// 
 
// 
// 
     
    printf("hello"); 
    /*我是頭豬 
     

程序運行結果:

[plain] view plaincopy
請輸入要進行語法分析的C語言程序: 
test.c 
************************************分析表****************************** 
 
                          內容      描述        種別碼  地址    行號 
                     <stdio.h>    頭文件        130             1 
                        "my.h"    頭文件        130             2 
                        max 90      常量        55              3 
                           int    關鍵字        17              6 
                          char    關鍵字        4               6 
                          main    標志符        40      1       6 
                             (    限界符        100             6 
                             )    限界符        101             6 
                             {    限界符        104             7 
                          8888      常量        51              8 
                          char    關鍵字        4               8 
                            yn    標志符        40      2       8 
                             ;    限界符        110             8 
                            do    關鍵字        8               9 
                             {    限界符        104             10 
                           int    關鍵字        17              11 
                          9801      常量        51              11 
                             ;    限界符        110             11 
                         float    關鍵字        13              12 
                             ;    限界符        110             12 
                        double    關鍵字        9               13 
                             f    標志符        40      3       13 
                             ;    限界符        110             13 
                         float    關鍵字        13              14 
                        -9.876      常量        53              14 
                             ;    限界符        110             14 
                        double    關鍵字        9               15 
                         hello    標志符        40      4       15 
                             .    限界符        106             15 
                           8.9      常量        53              15 
                             ;    限界符        110             15 
                         float    關鍵字        13              16 
                        7.9e-5      常量        53              16 
                             ;    限界符        110             16 
                           int    關鍵字        17              17 
                             e    標志符        40      5       17 
                            -5      常量        51              17 
                             ;    限界符        110             17 
                             a    標志符        40      6       18 
                            /=    運算符        87              18 
                             6      常量        51              18 
                             ;    限界符        110             18 
                          init    標志符        40      7       19 
                             (    限界符        100             19 
                             )    限界符        101             19 
                             ;    限界符        110             19 
                            無      注釋        120             19 
                       scanner    標志符        40      8       20 
                             (    限界符        100             20 
                             )    限界符        101             20 
                             ;    限界符        110             20 
                            無      注釋        121             21 
                        printf    標志符        40      9       21 
                             (    限界符        100             21 
                             "    限界符        112             21 
       Are You continue(y/n)\n      常量        54              21 
                             "    限界符        112             21 
                             )    限界符        101             21 
                             ;    限界符        110             21 
                            yn    標志符        40      2       22 
                             =    運算符        72              22 
                         getch    標志符        40      10      22 
                             (    限界符        100             22 
                             )    限界符        101             22 
                             ;    限界符        110             22 
                            if    關鍵字        16              23 
                             (    限界符        100             23 
                             a    標志符        40      6       23 
                            ==    運算符        80              23 
                             7      常量        51              23 
                             )    限界符        101             23 
                             {    限界符        104             24 
                             }    限界符        105             26 
                          else    關鍵字        10              27 
                             {    限界符        104             28 
                             }    限界符        105             30 
                             }    限界符        105             33 
                         while    關鍵字        32              34 
                             (    限界符        100             34 
                            yn    標志符        40      2       34 
                            ==    運算符        80              34 
                             '    限界符        111             34 
                             y      常量        52              34 
                             '    限界符        111             34 
                            ||    運算符        83              34 
                            yn    標志符        40      2       34 
                            ==    運算符        80              34 
                             '    限界符        111             34 
                             Y      常量        52              34 
                             '    限界符        111             34 
                             )    限界符        101             34 
                             ;    限界符        110             34 
                        return    關鍵字        20              36 
                             0      常量        51              36 
                             ;    限界符        110             36 
                             [    限界符        102             37 
                         hello    標志符        40      4       37 
                            無      注釋        121             43 
                            無      注釋        121             45 
                            無      注釋        121             46 
                        printf    標志符        40      9       47 
                             (    限界符        100             47 
                             "    限界符        112             47 
                         hello      常量        54              47 
                             "    限界符        112             47 
                             )    限界符        101             47 
                             ;    限界符        110             47 
 
 
************************************錯誤表****************************** 
 
      內容                          描述        類型    行號 
  #de some                    預處理錯誤        13      4 
        9.                 float表示錯誤        1       12 
       9.e                double表示錯誤        2       13 
         @                      非法字符        6       31 
        無                注釋沒有結束符        3       49 
        無                 '['沒有對應項        9       37 
        無                 '{'沒有對應項        11      7 
 
 
************************************標志符表****************************** 
 
                          內容      描述        種別碼  地址    行號 
                          main    標志符        40      1       6 
                            yn    標志符        40      2       8 
                             f    標志符        40      3       13 
                         hello    標志符        40      4       15 
                             e    標志符        40      5       17 
                             a    標志符        40      6       18 
                          init    標志符        40      7       19 
                       scanner    標志符        40      8       20 
                        printf    標志符        40      9       21 
                            yn    標志符        40      2       22 
                         getch    標志符        40      10      22 
                             a    標志符        40      6       23 
                            yn    標志符        40      2       34 
                            yn    標志符        40      2       34 
                         hello    標志符        40      4       37 
                        printf    標志符        40      9       47 
 
 
 
Process returned 0 (0x0)   execution time : 5.629 s 
Press any key to continue. 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved