很久没有发表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"); }