【编译技术实验】词法分析器(C++实现)

很久没有发表csdn博客了,后面会上线个人博客,预计在2022年3月底实现,发份实验代码冒个泡

代码易懂,无需注释就能看懂。

#include<iostream>
#include <unordered_map>
#include<string>
#include<cctype>
#include<vector>
#include<fstream>
using namespace std;

enum TYPE{ERROR,KEYWORD,IDENTIFIER,CONSTANT,OPERATOR,RELATIONAL_OPERATOR,DELIMITER};

class STDOUT{
public:
    STDOUT(string word, TYPE type, int row, int col): word(std::move(word)), type(type), row(row), col(col) {}

    void print(){
        cout<<word<<"     ";
        if(type==ERROR) cout<<"ERROR     ";
        else cout<<"("<<type<<","<<word<<")"<<"     ";
        cout<<OutPutTable[type]<<"     "<<"("<<row<<","<<col<<")"<<endl;
    }

    static unordered_map<int,string> OutPutTable;
private:
    string word;
    TYPE type;
    int row;
    int col;
};

unordered_map<int,string> STDOUT::OutPutTable={
        {ERROR,"ERROR"},{KEYWORD,"关键字"},{IDENTIFIER,"标识符"},
        {CONSTANT,"常数"},{OPERATOR,"运算符"},{RELATIONAL_OPERATOR,"关系运算符"},
        {DELIMITER,"分界符"}
};

class LexivalAnalyzer{
public:
    LexivalAnalyzer(){
        for(string str:{"do","end","for","if","printf","scanf","then","while"})
            keyWordTable[str] = keyWordTable.size();
        for(string str:{".",";","(",")","[","]"})
            delimiterTable[str]=delimiterTable.size();
        for(string str:{"+","-","*","/"})
            operatorTable[str] = operatorTable.size();
        for(string str:{"<","<=","=",">",">=","<>"})
            relationalOperatorTable[str] = relationalOperatorTable.size();
    }

    void run(const string& path){
        identifierTable.clear();
        constTable.clear();
        res.clear();
        string input= formatInput(path);
        cout<<"input file is:\n"<<input<<endl;
        int cur=0,row=1,col=1;
        while(cur < input.size()){
            if(input[cur] == ' '){
                ++cur;
                continue;
            }
            if(isalpha(input[cur])){
                alphaAdvanceSearch(input, cur, row, col);
            }else if(isdigit(input[cur])) {
                digitAdvanceSearch(input, cur, row, col);
            }else if(operatorTable.find(input.substr(cur,1)) != operatorTable.end()){
                normalAdvanceSearch(input, cur, row, col,operatorTable,OPERATOR);
            } else if(relationalOperatorTable.find(input.substr(cur,1))!=relationalOperatorTable.end()){
                normalAdvanceSearch(input, cur, row, col,relationalOperatorTable,RELATIONAL_OPERATOR);
            }else if(delimiterTable.find(input.substr(cur,1)) != delimiterTable.end()){
                res.emplace_back(STDOUT(input.substr(cur,1), DELIMITER, row, col));
                ++cur;
            }else if(input[cur] != '\n'){
                res.emplace_back(STDOUT(input.substr(cur,1), ERROR, row, col));
                ++cur;
            }
            else{
                ++row;
                col=0;
                ++cur;
            }
            ++col;
        }
        for(auto & re : res) re.print();
    }
private:
    static string formatInput(const string& path){
        ifstream readFile(path);
        string input,temp;
        while(!readFile.eof()){
            getline(readFile,temp,'\n');
            input+=temp;
            input+="\n";
        }
        return input;
    }

    void alphaAdvanceSearch(string input, int & cur, int row, int col){
        string instring;
        while(cur < input.size()){
            if(!(isalpha(input[cur]) || isdigit(input[cur]))) break;
            instring+=input[cur];
            ++cur;
        }
        if(keyWordTable.find(instring)!=keyWordTable.end())
            res.emplace_back(STDOUT(instring, KEYWORD, row, col));
        else {
            if (identifierTable.find(instring) == keyWordTable.end())
                identifierTable[instring]=identifierTable.size();
            res.emplace_back(STDOUT(instring, IDENTIFIER, row, col));
        }
    }

    void digitAdvanceSearch(string input, int & cur, int row, int col){
        string instring;
        bool flag=false;
        while(cur < input.size()){
            if(isdigit(input[cur]) || isalpha(input[cur])){
                if(isalpha(input[cur])) flag=true;
            }else break;
            instring+=input[cur];
            ++cur;
        }
        if(flag) res.emplace_back(STDOUT(instring, ERROR, row, col));
        else if(constTable.find(instring)!=constTable.end())
            res.emplace_back(STDOUT(instring, CONSTANT, row, col));
        else{
            constTable[instring]=constTable.size();
            res.emplace_back(STDOUT(instring, CONSTANT, row, col));
        }
    }

    void normalAdvanceSearch(string input, int & cur, int row, int col , unordered_map<string,int> &map,TYPE type){
        string instring;
        while(cur < input.size()){
            if(map.find(input.substr(cur,1)) == map.end()) break;
            instring+=input[cur];
            ++cur;
        }
        if(map.find(instring)!=map.end()) res.emplace_back(STDOUT(instring, type, row, col));
        else res.emplace_back(STDOUT(instring, ERROR, row, col));
    }

    unordered_map<string,int> keyWordTable;
    unordered_map<string,int> delimiterTable;
    unordered_map<string,int> operatorTable;
    unordered_map<string,int> relationalOperatorTable;
    unordered_map<string,int> identifierTable;
    unordered_map<string,int> constTable;
    vector<STDOUT> res;
};

int main(){
    LexivalAnalyzer lexivalAnalyzer;
    lexivalAnalyzer.run("D:\\LexicalAnalyzer\\test1.txt");
}
上一篇:C语言偶数魔方阵


下一篇:字典树