#include <iostream>
#include <unordered_map>
#include <fstream>
#include <vector>
#include <string>
/*
* 判断输⼊字符合法性hashmap:
* 关键字:
* 单⽬运算符:
* 双⽬运算符:
* 界符:
*/
std::unordered_map<std::string, std::string> flags_key;//关键字std::unordered_map<std::string, std::string> flags_delim;//界符std::unordered_map<std::string, std::string> flags_unaryOp;//单⽬运算符std::unordered_map<std::string, std::string> flags_binaryOp;//双⽬运算符
/*
* 分割带有空格字符串的结果集ansSet
*/
std::vector<std::string> ansSet;
/*
* 分割字符串到容器,分割符号默认为空格” ”
*/
void split(const std::string& s, std::vector<std::string>& tokens
, const std::string& delimiters = ” “) { std::string::size_type lastPos = s.find_first_not_of(delimiters, 0); std::string::size_type pos = s.find_first_of(delimiters, lastPos); while (std::string::npos != pos || std::string::npos != lastPos) {
tokens.push_back(s.substr(lastPos, pos – lastPos));//use emplace_back after
C++11
lastPos = s.find_first_not_of(delimiters, pos);
pos = s.find_first_of(delimiters, lastPos);
}
}
*
* 判断是否是数字
*/
bool isNumber(std::string& str) {
if (str == “0”) {return true;}//单个0返回真
if (str.size() > 1 && str[0] == ‘0’) {return false;}//不允许0开头的数字
bool ans = std::all_of(str.begin(), str.end(), [&](const char& temp){ return (temp – ‘0’ >= 0 && temp – ‘0’ <= 9);
});
return ans;
}
/*
* 初始化hashmap
*/
void init() {
//关键字
flags_key[“if”] = “KEY”;flags_key[“else”] = “KEY”; flags_key[“float”] = “KEY”;flags_key[“int”] = “KEY”;
//界符
flags_delim[“{“] = “DELIMITER”;flags_delim[“}”] = “DELIMITER”; flags_delim[“(“] = “DELIMITER”;flags_delim[“)”] = “DELIMITER”; flags_delim[“;”] = “DELIMITER”;
//单⽬运算符号
flags_unaryOp[“+”] = “UNARY_OPERATOR”;
//双⽬运算符号
flags_binaryOp[“=”] = “BINARY_OPERATOR”; flags_binaryOp[“==”] = “BINARY_OPERATOR”;
}
bool isLegal(std::string& str) {
if (str[0] == ‘_’) {return false;} //下划线开头if (str[0] == ‘$’) {return false;} //美元开头
if (str[0] – ‘a’ >= 0 && str[0] – ‘z’ <= 0) {return false;}//⼩写字⺟开头if (str[0] – ‘A’ >= 0 && str[0] – ‘Z’ <= 0) {return false;}//⼤写字⺟开头
return true;
}
/*
* 获取逐个字符的词法分析结果
*/
std::string gainResult(std::string& source) {
if (flags_key.find(source) != flags_key.end()) {//是否是关键字return source + “\t\t\t” + flags_key[source];
} else if (flags_delim.find(source) != flags_delim.end()) {//是否是界符
return source + “\t\t\t” + flags_delim[source];
} else if (flags_unaryOp.find(source) != flags_unaryOp.end()) {//是否是单⽬运算符return source + “\t\t\t” + flags_unaryOp[source];
} else if (flags_binaryOp.find(source) != flags_binaryOp.end()) {//是否是双⽬运算符
return source + “\t\t\t” + flags_binaryOp[source];
} else if (isNumber(source)) {//是否是数字return source + “\t\t\t” + “NUMBER”;
} else if (isLegal(source)) {//判断是否是⾮法标识符
return source + “\t\t\t” + “ERROR:ILLEGAL IDENTIFIER”;
} else {//标识符
return source + “\t\t\t” + “IDENTIFIER”;
}
}
/*
* main函数,实现业务总体流程
*/
int main() {
//打开⽂件std::ifstream
in(“//Users//jkchou//MyDataFile//ClionTest//LexicalAnalysis//source.txt”); std::ofstream
out(“//Users//jkchou//MyDataFile//ClionTest//LexicalAnalysis//answer.txt”); if (!in.is_open()) {
std::cout << “SOURCE OPEN FILE ERROR!!!\n”;
exit(0);
}
if (!out.is_open()) {
std::cout << “ANSWER OPEN FILE ERROR!!!\n”;
exit(0);
}
init();//初始化hashmap char temp[256];
//循环获取每⼀⾏
while (!in.eof()) {
//每次⾄多读取255个字符
if (!in.getline(temp, 255)) {//这个if⽤来防⽌读取终⽌⽽while循环死循环
break;
}
ansSet.clear();
std::string eachLine = temp;
split(eachLine, ansSet);//分割每⼀⾏,得到单个符号或集合
//输出结果到⽂件
int len_ansSet = (int)ansSet.size();
for (int i = 0; i < len_ansSet; ++i) {//对每个字符进⾏判断out << gainResult(ansSet[i]) << “\n”;
}
}
//关闭链接out.close();
in.close();
std::cout << “WORK SUCCESS!!!\n”;
std::cout << “PLEASE EXAMINATION FROM ANSWER.TXT\n”;
/*
* author:zwp
*/
return 0;
}