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