GaiaXiOS/GaiaXiOS/Binding/Expression/GXAnalyzeCore/GXAnalyze.cpp (1,836 lines of code) (raw):

#include "GXAnalyze.h" #include <mutex> // std::mutex #include<cmath> //c头文件 #include <sstream> #include <iomanip> using namespace std; static mutex mtx; //锁,避免多线程读写导致的线程不安全问题发生 static vector<vector<char> > grammarProduct; //文法grammarProduct[S]产生式 ,~为空字 static unordered_map<char, set<char> > terminalSymbolMap; //终结符(char)terminal symbol,及它的first集合(set<char>) static unordered_map<char, set<char> > nonTerminalSymbolMap; //非终结符(char)non-terminal symbol,及它的first集合(set<char>) static unordered_map<string, string> gotoTable; //初始化最终产物,可根据该表格找到规约或递进的结果 static bool isInit = false; //判断是否已经进行过初始化 static unordered_map<string, char> terminal; //终结符集合 static unordered_map<string, char> nonTerminal; //非终结符集合 static vector<string> grammarFormula; //每层文法式的集合 struct Closure { //闭包CLOSURE vector<vector<char> > project; //项目集 vector<set<char> > outlook; //展望串 unordered_map<char, int> go; // GO函数 }; static vector<Closure> closureArray; //闭包集合 static unordered_map<char, string> wordToSymbol; //key:word value:symbol static unordered_map<string, string> cache; //表达式缓存 /* * 存放终结符完整词汇的string集合 */ static string terminalWord[] = {"true", "false", "null", "value", "num", "string", "data", "id", ",", "function", "long", "(", ")", "!", "-", "+", "%", "/", "*", ">", "<", ">=", "<=", "==", "!=", "&&", "||", "?", ":", "?:", "error", "#", "~"}; /* * 存放终结符标识符的char集合 */ static char terminalSymbol[] = {'t', 'f', 'n', 'v', 'u', 's', 'd', 'i', ',', 'a', 'o', '(', ')', '!', '-', '+', '%', '/', '*', '>', '<', 'l', 'b', '=', 'p', '&', '@', '?', ':', 'y', 'e', '#', '~'}; /* * 存放非终结符完整词汇的string集合 */ static string nonTerminalWord[] = {"S", "Ten", "L", "Nin", "Eig", "Sev", "Six", "Fiv", "Fou", "Thr", "Two", "P", "One"}; /* * 存放非终结符标识符的char集合 */ static char nonTerminalSymbol[] = {'S', 'T', 'L', 'N', 'E', 'D', 'F', 'G', 'H', 'U', 'Y', 'P', 'O'}; /* * 表达式语法集合 */ static string grammar[] = {"S->T", "T->TyN|L:N|N", "L->N?N", "N->N@E|E", "E->E&D|D", "D->DpF|D=F|F", "F->F>G|F<G|FlG|FbG|G", "G->G+H|G-H|H", "H->H*U|H/U|H%U|U", "U->+Y|-Y|!Y|Y", "Y->(T)|i(P)|O|~", "P->O,P|O|~", "O->t|f|n|v|u|s|d|a|o"}; /* * 判断word是否为终结符 */ bool isTerminalWord(const string &s) { //在map中判断 if (terminal.count(s) > 0) { return true; } if (s == "M") { return true; } return false; } /* * 判断字符是否是数字类型 */ bool isNumber(char ch) { if (ch >= '0' && ch <= '9') return true; else return false; } /* * 初始化:获取文法grammarProduct */ void getGrammarProduct() { int sizeG = sizeof(grammar) / sizeof(grammar[0]); for (int i = 0; i < sizeG; i++) { grammarFormula.push_back(grammar[i]); } char symbol; int i = 0; vector<char> value; char chX; set<char> m; nonTerminalSymbolMap['M'] = m; for (auto temp : grammarFormula) { for (int y = 0; y < temp.length(); y++) { symbol = temp[y]; if (symbol == '|') { grammarProduct.push_back(value); value.clear(); i = 3; value.push_back(chX); continue; } i++; if (i == 1) { chX = symbol; nonTerminalSymbolMap[symbol] = m; } else if (i != 2 && i != 3 && symbol != '~') terminalSymbolMap[symbol] = m; if (i != 2 && i != 3) value.push_back(symbol); if (y == temp.length() - 1) { if (!value.empty()) { grammarProduct.push_back(value); } value.clear(); i = 0; continue; } } } if (grammarProduct.empty()) { exit(0); } value.clear(); value.push_back('M'); value.push_back(grammarProduct[0][0]); grammarProduct.insert(grammarProduct.begin(), value); //去掉ts中的非终结符 for (auto &it : nonTerminalSymbolMap) { unordered_map<char, set<char> >::iterator iter; iter = terminalSymbolMap.find(it.first); if (iter != terminalSymbolMap.end()) terminalSymbolMap.erase(iter); } } /* * 初始化:获取First集 */ void getFirst() { //得到First集合 for (auto &it : terminalSymbolMap) it.second.insert(it.first); //求非终结符的First集合 int r = 0; int change = 1; while (change) { if (r == 20) break; r++; change = 0; for (auto &it : nonTerminalSymbolMap) { for (unsigned int i = 0; i < grammarProduct.size(); i++) { if (grammarProduct[i][0] == it.first) { unsigned int size = it.second.size(); unordered_map<char, set<char> >::iterator iter = terminalSymbolMap.find( grammarProduct[i][1]); if (terminalSymbolMap.find(grammarProduct[i][1]) != terminalSymbolMap.end() || grammarProduct[i][1] == '~') { it.second.insert(grammarProduct[i][1]); if (it.second.size() > size) change = 1; } else { unsigned int col = 1; while (1) { int flag = 0; unordered_map<char, set<char> >::iterator itt = nonTerminalSymbolMap.find( grammarProduct[i][col]); for (auto &iter : itt->second) { if (iter == '~') flag = 1; else it.second.insert(iter); } if (flag) { col++; if (grammarProduct[i].size() <= col) { it.second.insert('~'); break; } else if (terminalSymbolMap.find(grammarProduct[i][col]) != terminalSymbolMap.end()) { it.second.insert(grammarProduct[i][col]); break; } else { } } else break; } if (it.second.size() > size) change = 1; } } } } } } /* * 初始化:生成闭包集 */ void getClosure() { int i = 0; Closure clo; closureArray.push_back(clo); while (1) { if (i == closureArray.size()) break; if (i == 0) { vector<char> vec(grammarProduct[0]); vec.insert(vec.begin() + 1, ' '); closureArray[i].project.push_back(vec); set<char> m; m.insert('#'); closureArray[i].outlook.push_back(m); } for (unsigned int j = 0; j < closureArray[i].project.size(); j++) { for (unsigned int k = 0; k < closureArray[i].project[j].size(); k++) { if (closureArray[i].project[j][k] == ' ') { if (k == closureArray[i].project[j].size() - 1) break; for (unsigned int x = 0; x < grammarProduct.size(); x++) { if (grammarProduct[x][0] == closureArray[i].project[j][k + 1]) { vector<char> vec(grammarProduct[x]); vec.insert(vec.begin() + 1, ' '); int exist = 0; for (unsigned int y = 0; y < closureArray[i].project.size(); y++) { if (closureArray[i].project[y] == vec) { exist = y; break; } } if (exist == 0) { closureArray[i].project.push_back(vec); } set<char> m; bool emp = true; //判空 int t = 0; while (emp) { emp = false; if (k + t + 1 == closureArray[i].project[j].size() - 1) { //情况一 for (auto it : closureArray[i].outlook[j]) m.insert(it); } else if ( terminalSymbolMap.find( closureArray[i].project[j][k + t + 2]) != terminalSymbolMap.end()) { //情况二 m.insert(closureArray[i].project[j][k + 2 + t]); } else { set<char> m1( (nonTerminalSymbolMap.find( closureArray[i].project[j][k + 2 + t]))->second); for (auto it : m1) { if (it == '~') { emp = true; t++; } else { m.insert(it); } } } } if (exist) { for (auto it : m) { closureArray[i].outlook[exist].insert(it); } } else closureArray[i].outlook.push_back(m); } } break; } } } for (unsigned int j = 0; j < closureArray[i].project.size(); j++) { for (unsigned int k = 0; k < closureArray[i].project[j].size(); k++) { if (closureArray[i].project[j][k] == ' ') { if (k == closureArray[i].project[j].size() - 1) break; vector<char> new_closure_pro(closureArray[i].project[j]); new_closure_pro[k] = new_closure_pro[k + 1]; new_closure_pro[k + 1] = ' '; set<char> new_closure_search(closureArray[i].outlook[j]); bool dif = false; for (unsigned int x = 0; x < closureArray.size(); x++) { // dif = false; for (unsigned int y = 0; y < closureArray[x].project.size(); y++) { dif = false; if (new_closure_pro == closureArray[x].project[y]) { if (closureArray[x].outlook[0].size() != new_closure_search.size()) { dif = true; continue; } auto iter = closureArray[x].outlook[0].begin(); for (auto it : new_closure_search) { if (it != *iter) { dif = true; break; } iter++; } if (dif == false) { closureArray[i].go[new_closure_pro[k]] = x; break; } } else dif = true; if (dif == false) break; } if (dif == false) break; } if (closureArray[i].go.count(new_closure_pro[k]) != 0 && dif) { closureArray[closureArray[i].go[new_closure_pro[k]]].project.push_back( new_closure_pro); closureArray[closureArray[i].go[new_closure_pro[k]]].outlook.push_back( new_closure_search); break; } if (dif) { Closure new_closure; new_closure.project.push_back(new_closure_pro); new_closure.outlook.push_back(new_closure_search); closureArray.push_back(new_closure); closureArray[i].go[new_closure_pro[k]] = closureArray.size() - 1; } } } } i++; } } /* * 初始化:生成gotoTable */ int getGotoTable() { for (unsigned int i = 0; i < closureArray.size(); i++) { for (unsigned int j = 0; j < closureArray[i].project.size(); j++) { for (unsigned int k = 0; k < closureArray[i].project[j].size(); k++) { if (closureArray[i].project[j][k] == ' ') { if (k == closureArray[i].project[j].size() - 1) { if (closureArray[i].project[j][0] == 'M') { string m = to_string(i) + '#'; if (gotoTable.find(m) != gotoTable.end() && gotoTable[m] != "acc") { return 0; } else gotoTable[m] = "acc"; } else { int id; for (unsigned int x = 0; x < grammarProduct.size(); x++) { vector<char> vec(closureArray[i].project[j]); vec.pop_back(); if (grammarProduct[x] == vec) { id = x; break; } } for (auto it : closureArray[i].outlook[j]) { string m = to_string(i) + it; if (gotoTable.find(m) != gotoTable.end() && gotoTable[m] != (string) "r" + to_string(id)) { return 0; } else gotoTable[m] = (string) "r" + to_string(id); } } } else { char next = closureArray[i].project[j][k + 1]; if (terminalSymbolMap.find(next) != terminalSymbolMap.end()) { string m = to_string(i) + next; if (gotoTable.find(m) != gotoTable.end() && gotoTable[m] != (string) "s" + to_string(closureArray[i].go[next])) { return 0; } else gotoTable[m] = (string) "s" + to_string(closureArray[i].go[next]); } else { string m = to_string(i) + next; if (gotoTable.find(m) != gotoTable.end() && gotoTable[m] != to_string(closureArray[i].go[next])) { return 0; } else gotoTable[m] = to_string(closureArray[i].go[next]); } } break; } } } } return 1; } /* * 初始化:获取终结符和非终结符相关集合 */ void initTerminal() { int sizeTerminal = sizeof(terminalWord) / sizeof(terminalWord[0]); int sizeNonTerminal = sizeof(nonTerminalWord) / sizeof(nonTerminalWord[0]); set<char> m; for (int i = 0; i < sizeTerminal; i++) { wordToSymbol.insert(pair<char, string>(terminalSymbol[i], terminalWord[i])); terminal.insert(pair<string, char>(terminalWord[i], terminalSymbol[i])); terminalSymbolMap[terminalSymbol[i]] = m; } for (int i = 0; i < sizeNonTerminal; i++) { wordToSymbol.insert(pair<char, string>(nonTerminalSymbol[i], nonTerminalWord[i])); nonTerminal.insert(pair<string, char>(nonTerminalWord[i], nonTerminalSymbol[i])); nonTerminalSymbolMap[nonTerminalSymbol[i]] = m; } } /* * 调用所有初始化函数 */ void init() { if (!isInit) { cache.reserve(1024); isInit = true; getGrammarProduct(); getFirst(); getClosure(); initTerminal(); getGotoTable(); } } /* * Analyze对象初始化 */ GXAnalyze::GXAnalyze() { init(); } /* * Analyze对象析构函数 */ GXAnalyze::~GXAnalyze() { } int countDecimalPlaces(const std::string &str) { size_t decimalPos = str.find('.'); if (decimalPos == std::string::npos) { return 0; } return str.length() - decimalPos - 1; } std::string formatFloat(double number, int precision) { std::ostringstream oss; oss << std::fixed << std::setprecision(precision) << number; return oss.str(); } /* * 获取两个数值计算的结果 */ GXATSNode GXAnalyze::doubleCalculate(GXATSNode left, GXATSNode right, string op) { GXATSNode result = GXATSNode(left.name, left.token, left.token); string name; if ((op == "?") || (op == ":") || (op == "?:") || (op == "==") || (op == "!=")) { //可以返回map和array } else if (left.token == "map" || left.token == "array") { result.name = "expressionError: illegal operator '" + op + "',left operand has type of '" + left.token + "'"; result.token = "error"; return result; } //返回值都为bool if (op == ">") { result.token = "bool"; if ((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) { if (stof(left.name) > stof(right.name)) { result.name = "true"; } else { result.name = "false"; } } else { result.name = "false"; } } //返回值都为bool else if (op == ">=") { result.token = "bool"; if ((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) { if (stof(left.name) >= stof(right.name)) { result.name = "true"; } else { result.name = "false"; } } else { result.name = "false"; } } //返回值都为bool else if (op == "<") { result.token = "bool"; if ((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) { if (stof(left.name) < stof(right.name)) { result.name = "true"; } else { result.name = "false"; } } else { result.name = "false"; } } //返回值都为bool else if (op == "<=") { result.token = "bool"; if ((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) { if (stof(left.name) <= stof(right.name)) { result.name = "true"; } else { result.name = "false"; } } else { result.name = "false"; } } //返回值都为bool else if (op == "&&") { result.token = "bool"; if (left.token == "bool" && right.token == "bool") { if (left.name == "true" && right.name == "true") { result.name = "true"; } else { result.name = "false"; } } else if (left.token == "bool" && (right.token == "num" || right.token == "long")) { if (left.name == "true" && (stof(right.name) != 0.0F)) { result.name = "true"; } else { result.name = "false"; } } else if (left.token == "bool" && right.token == "string") { if (left.name == "true" && right.name == "true") { result.name = "true"; } else { result.name = "false"; } } else if ((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) { if ((stof(left.name) != 0.0F) && (stof(right.name) != 0.0F)) { result.name = "true"; } else { result.name = "false"; } } else if ((left.token == "num" || left.token == "long") && right.token == "bool") { if (((stof(left.name) != 0.0F) && right.name == "true") || ((left.token == "num" || left.token == "long") && right.token == "string")) { result.name = "true"; } else { result.name = "false"; } } else if ((left.token == "string" && right.token == "string") || (left.token == "string" && right.token == "bool")) { if (left.name == "true" && right.name == "true") { result.name = "true"; } else { result.name = "false"; } } else if (left.token == "string" && (right.token == "num" || right.token == "long")) { if (left.name == "true" && (stof(right.name) != 0.0F)) { result.name = "true"; } else { result.name = "false"; } } else { result.name = "false"; } } //返回值都为bool else if (op == "||") { result.token = "bool"; if (left.token == "bool" && right.token == "bool") { if (left.name == "true" || right.name == "true") { result.name = "true"; } else { result.name = "false"; } } else if (left.token == "bool" && (right.token == "num" || right.token == "long")) { if (left.name == "true" || (stof(right.name) != 0.0F)) { result.name = "true"; } else { result.name = "false"; } } else if (left.token == "bool" && right.token == "string") { if (left.name == "true" || right.name == "true") { result.name = "true"; } else { result.name = "false"; } } else if ((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) { if ((stof(left.name) != 0.0F) || (stof(right.name) != 0.0F)) { result.name = "true"; } else { result.name = "false"; } } else if ((left.token == "num" || left.token == "long") && right.token == "bool") { if (((stof(left.name) != 0.0F) || right.name == "true") || (left.token == "num" || right.token == "string")) { result.name = "true"; } else { result.name = "false"; } } else if ((left.token == "string" && right.token == "string") || (left.token == "string" && right.token == "bool")) { if (left.name == "true" || right.name == "true") { result.name = "true"; } else { result.name = "false"; } } else if (left.token == "string" && (right.token == "num" || right.token == "long")) { if (left.name == "true" || (stof(right.name) != 0.0F)) { result.name = "true"; } else { result.name = "false"; } } else if (left.token == "null") { if ((right.token == "num" || right.token == "long")) { if (stof(right.name) != 0.0F) { result.name = "true"; } else { result.name = "false"; } } else if (right.name == "true") { result.name = "true"; } else { result.name = "false"; } } else if (right.token == "null") { if (left.token == "num" || left.token == "long") { if (stof(left.name) != 0.0F) { result.name = "true"; } else { result.name = "false"; } } else if (left.name == "true") { result.name = "true"; } else { result.name = "false"; } } else { result.name = "false"; } } //返回值都为bool else if (op == "!=") { result.token = "bool"; if (left.token == "bool" && (right.token == "num" || right.token == "long")) { if ((left.name == "true" && (stof(right.name) == 0.0F)) || (left.name == "false" && (stof(right.name) != 0.0F))) { result.name = "true"; } else { result.name = "false"; } } else if ((left.token == "num" || left.token == "long") && right.token == "bool") { if (((stof(left.name) == 0.0F) && right.name == "true") || ((stof(left.name) != 0.0F) && right.name == "false")) { result.name = "true"; } else { result.name = "false"; } } else if (((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long"))) { float lef = stof(left.name); float rig = stof(right.name); if (lef != rig) { result.name = "true"; } else { result.name = "false"; } } else if ((left.token == "string" && right.token == "bool") || (left.token == "bool" && right.token == "string")) { if (left.name == right.name) { result.name = "false"; } } else if ((left.name != right.name) || (left.token != right.token)) { result.name = "true"; } else { result.name = "false"; } } //返回值都为bool else if (op == "==") { result.token = "bool"; if (left.token == "bool" && (right.token == "num" || right.token == "long")) { if ((left.name == "true" && (stof(right.name) != 0.0F)) || (left.name == "false" && (stof(right.name) == 0.0F))) { result.name = "true"; } else { result.name = "false"; } } else if ((left.token == "num" || left.token == "long") && right.token == "bool") { if (((stof(left.name) != 0.0F) && right.name == "true") || ((stof(left.name) == 0.0F) && right.name == "false")) { result.name = "true"; } else { result.name = "false"; } } else if (((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) && (stof(left.name) == stof(right.name))) { result.name = "true"; } else if ((left.name == right.name)) { if (left.token == right.token) { result.name = "true"; } else if ((left.token == "string" && right.token == "bool") || (left.token == "bool" && right.token == "string")) { result.name = "true"; } } else { result.name = "false"; } } else if (op == "?") { if (left.name == "true" || ((left.name != "false" && left.token != "null"))) { result.name = right.name; result.token = right.token; } else if ((left.token == "num" || left.token == "long") && stof(left.name) != 0.0F) { result.name = right.name; result.token = right.token; } else { result.token = "right"; result.name = "right"; } } else if (op == "?:") { if (left.name == "true" || (left.name != "false" && left.token != "null")) { result.name = left.name; result.token = left.token; } else { result.name = right.name; result.token = right.token; } } else if (op == ":") { if (left.token == "right" && left.name == "right") { result.token = right.token; result.name = right.name; } else { result.token = left.token; result.name = left.name; } } else if (op == "+") { if ((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) { if (left.token == "num" || right.token == "num") { int n = max(countDecimalPlaces(left.name), countDecimalPlaces(right.name)); double temp = stod(left.name) + stod(right.name); string resNum = formatFloat(temp, n); result.name = resNum; result.token = "num"; } else { long temp = stol(left.name) + stol(right.name); result.name = to_string(temp); result.token = "long"; } } else if (left.token == "string" && right.token == "string") { result.token = "string"; result.name = left.name + right.name; } else if (left.token == "null" || right.token == "null") { result.name = "null"; result.token = "null"; } else { if ((left.token == "num" || left.token == "long") && right.token == "string") { result.name = left.name + right.name; result.token = "string"; } else if ((right.token == "num" || right.token == "long") && left.token == "string") { result.name = left.name + right.name; result.token = "string"; } else { result.token = "error"; if (left.token == "string" || (left.token == "num" || left.token == "long")) { result.name = "expressionError: '" + right.name + "' expected num or string value,not '" + right.token + "'"; } else if (right.token == "string" || (right.token == "num" || right.token == "long")) { result.name = "expressionError: '" + left.name + "' expected num or string value,not '" + left.token + "'"; } else { result.name = "expressionError: '" + left.name + "' expected num or string value,not '" + left.token + "'"; } } } } else if (op == "-") { if ((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) { if (left.token == "num" || right.token == "num") { int n = max(countDecimalPlaces(left.name), countDecimalPlaces(right.name)); double temp = stod(left.name) - stod(right.name); string resNum = formatFloat(temp, n); result.name = resNum; result.token = "num"; } else { long temp = stol(left.name) - stol(right.name); result.name = to_string(temp); result.token = "long"; } } else if (left.token == "null" || right.token == "null") { result.name = "null"; result.token = "null"; } else { result.token = "error"; if ((left.token == "num" || left.token == "long")) { result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; } else if (left.token == "null" || right.token == "null") { result.name = "null"; result.token = "null"; } else if ((right.token == "num" || right.token == "long")) { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + left.token; } else { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + left.token; } } } else if (op == "*") { if ((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) { if (left.token == "num" || right.token == "num") { //如果需要保留n位小数,那么输入时需要输入n位 int n = max(countDecimalPlaces(left.name), countDecimalPlaces(right.name)); double temp = stod(left.name) * stod(right.name); string resNum = formatFloat(temp, n); result.name = resNum; result.token = "num"; } else { long temp = stol(left.name) * stol(right.name); result.name = to_string(temp); result.token = "long"; } } else if (left.token == "null" || right.token == "null") { result.name = "null"; result.token = "null"; } else { result.token = "error"; if ((left.token == "num" || left.token == "long")) { result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; } else if (left.token == "null" || right.token == "null") { result.name = "null"; result.token = "null"; } else if ((right.token == "num" || right.token == "long")) { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + left.token; } else { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + left.token; } } } else if (op == "/") { if ((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) { if (stof(right.name) == 0) { result.token = "error"; result.name = "expressionError: divide or mod by zero"; } else { if (left.token == "num" || right.token == "num") { int n = max(countDecimalPlaces(left.name), countDecimalPlaces(right.name)); double temp = stod(left.name) / stod(right.name); string resNum = formatFloat(temp, n); result.name = resNum; result.token = "num"; } else { long temp = stol(left.name) / stol(right.name); long double tempF = stold(left.name) / stold(right.name); if (temp != tempF && (left.token == "num" || right.token == "num")) { result.name = to_string(tempF); result.token = "num"; } else { result.name = to_string(temp); result.token = "long"; } } } } else if (left.token == "null" || right.token == "null") { result.name = "null"; result.token = "null"; } else { result.token = "error"; if ((left.token == "num" || left.token == "long")) { result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; } else if (left.token == "null" || right.token == "null") { result.name = "null"; result.token = "null"; } else if ((right.token == "num" || right.token == "long")) { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + left.token; } else { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + left.token; } } } else if (op == "%") { if ((left.token == "num" || left.token == "long") && (right.token == "num" || right.token == "long")) { if (stof(right.name) == 0) { result.token = "error"; result.name = "expressionError: divide or mod by zero"; } else { if (left.token == "num" || right.token == "num") { int n = max(countDecimalPlaces(left.name), countDecimalPlaces(right.name)); double temp = fmod(stod(left.name), stod(right.name)); string resNum = formatFloat(temp, n); result.name = resNum; result.token = "num"; } else { long temp = stol(left.name) % stol(right.name); result.name = to_string(temp); result.token = "long"; } } } else if (left.token == "null" || right.token == "null") { result.name = "null"; result.token = "null"; } else { result.token = "error"; if ((left.token == "num" || left.token == "long")) { result.name = "expressionError: '" + right.name + "'" + ": expected num value,not: " + right.token; } else if (left.token == "null" || right.token == "null") { result.name = "null"; result.token = "null"; } else if ((right.token == "num" || right.token == "long")) { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + left.token; } else { result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + left.token; } } } else { result.token = "error"; result.name = "expressionError: wrong expression"; } return result; } /* * 获取单个数值计算的结果 */ GXATSNode GXAnalyze::singleCalculate(GXATSNode left, string op) { GXATSNode result = GXATSNode(left.name, left.token, left.token); if (left.token == "map" || left.token == "array") { return result; } if (op == "-") { if ((left.token == "num" || left.token == "long")) { float temp = -stof(left.name); result.name = to_string(temp); result.token = left.token; } else { result.token = "error"; result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + left.token; } } else if (op == "+") { if ((left.token == "num" || left.token == "long")) { result.token = left.token; result.name = left.name; } else { result.token = "error"; result.name = "expressionError: '" + left.name + "'" + ": expected num value,not: " + left.token; } } else if (op == "!") { if (left.token == "bool") { if (left.name == "false") { result.name = "true"; } else if (left.name == "true") { result.name = "false"; } else { result.token = "error"; result.name = "expressionError: unknown identifier '" + left.name + "'"; } } else { result.token = "error"; result.name = "expressionError: '" + left.name + "' expected bool value,not '" + left.token + "'"; } } return result; } /* * @expression:需要计算的表达式 * @source:数据源 * 计算表达式结果函数 */ long GXAnalyze::getValue(string expression, void *source) { char *input; int inputLength = expression.length(); input = new char[inputLength + 2]; vector<GXATSNode> array; vector<GXATSNode> arrayNum; array.reserve(128); arrayNum.reserve(128); string result = "#"; strcpy(input, expression.c_str()); int p = 0; int synCode; int countNode = 0; while (p < strlen(input)) { if (input[p] == ' ') { p++; } else { GXATSNode token = scanner(synCode, p, input, this); if (isTerminalWord(token.detail)) { result = result + terminal[token.detail]; } else { result = result + nonTerminal[token.detail]; } GXATSNode tokenNum; if (token.token == "value" || token.token == "data") { long res = this->getSourceValue(token.name, source); if (res == 0) { tokenNum.name = "null"; tokenNum.token = "null"; } else { GXValue *gxv = (GXValue *) res; if (gxv->tag == GX_TAG_FLOAT) { tokenNum.name = to_string(gxv->float64); if (tokenNum.name.find('.') != -1) { tokenNum.name = regex_replace(tokenNum.name, regex("0+?$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 tokenNum.name = regex_replace(tokenNum.name, regex("[.]$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 } tokenNum.token = "num"; } else if (gxv->tag == GX_TAG_LONG) { tokenNum.name = to_string(gxv->intNum); tokenNum.token = "long"; } else if (gxv->tag == GX_TAG_STRING) { tokenNum.name = gxv->str; tokenNum.token = "string"; } else if (gxv->tag == GX_TAG_BOOL) { if (gxv->int32 == 1) { tokenNum.name = "true"; } else { tokenNum.name = "false"; } tokenNum.token = "bool"; } else if (gxv->tag == GX_TAG_ARRAY) { tokenNum.name = to_string((long) (gxv->ptr)); tokenNum.token = "array"; } else if (gxv->tag == GX_TAG_MAP) { tokenNum.name = to_string((long) (gxv->ptr)); tokenNum.token = "map"; } else if (gxv->tag == GX_TAG_NULL) { tokenNum.name = "null"; tokenNum.token = "null"; } else { tokenNum.name = "null"; tokenNum.token = "null"; } if (gxv->tag == GX_TAG_STRING && gxv->str != NULL) { delete[] gxv->str; gxv->str = NULL; } delete gxv; } } else if (token.token == "function") { long res = this->getFunctionValue(token.name, nullptr, 0, ""); if (res == 0) { tokenNum.name = "null"; tokenNum.token = "null"; } else { GXValue *gxv = (GXValue *) res; if (gxv->tag == GX_TAG_FLOAT) { tokenNum.name = to_string(gxv->float64); if (tokenNum.name.find('.') != -1) { tokenNum.name = regex_replace(tokenNum.name, regex("0+?$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 tokenNum.name = regex_replace(tokenNum.name, regex("[.]$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 } tokenNum.token = "num"; } else if (gxv->tag == GX_TAG_LONG) { tokenNum.name = to_string(gxv->intNum); tokenNum.token = "long"; } else if (gxv->tag == GX_TAG_STRING) { tokenNum.name = gxv->str; tokenNum.token = "string"; } else if (gxv->tag == GX_TAG_BOOL) { if (gxv->int32 == 1) { tokenNum.name = "true"; } else { tokenNum.name = "false"; } tokenNum.token = "bool"; } else if (gxv->tag == GX_TAG_ARRAY) { tokenNum.name = to_string((long) (gxv->ptr)); tokenNum.token = "array"; } else if (gxv->tag == GX_TAG_MAP) { tokenNum.name = to_string((long) (gxv->ptr)); tokenNum.token = "map"; } else if (gxv->tag == GX_TAG_NULL) { tokenNum.name = "null"; tokenNum.token = "null"; } else { tokenNum.name = "null"; tokenNum.token = "null"; } if (gxv->tag == GX_TAG_STRING && gxv->str != NULL) { delete[] gxv->str; gxv->str = NULL; } delete gxv; } } else { tokenNum = token; } if (token.token != "op") { token.count = countNode; tokenNum.count = countNode; countNode++; arrayNum.push_back(tokenNum); } array.push_back(token); } } //释放s的内存空间 delete[]input; result = result + "#"; long Res; mtx.lock(); unordered_map<string, string>::iterator iter = cache.find(result); mtx.unlock(); if (iter != cache.end()) { if (iter->second == "(0)") { GXATSNode res = arrayNum[0]; GXValue *pointer; if (res.token == "string") { pointer = new GXValue(GX_TAG_STRING, res.name); } else if (res.token == "bool") { if (res.name == "true") { pointer = new GXValue(GX_TAG_BOOL, 1); } else { pointer = new GXValue(GX_TAG_BOOL, 0); } } else if (res.token == "num") { pointer = new GXValue(GX_TAG_FLOAT, (float) atof(res.name.c_str())); } else if (res.token == "long") { pointer = new GXValue(GX_TAG_LONG, (int64_t) atoll(res.name.c_str())); } else if (res.token == "map") { pointer = new GXValue(GX_TAG_MAP, (void *) atol(res.name.c_str())); } else if (res.token == "array") { pointer = new GXValue(GX_TAG_ARRAY, (void *) atol(res.name.c_str())); } else if (res.token == "null") { pointer = new GXValue(GX_TAG_NULL, 1); } else { pointer = new GXValue(GX_TAG_NULL, 1); } Res = (long) pointer; } else { Res = calculateCache(iter->second, arrayNum, this, source); } } else { Res = check(result, array, this, source, expression); } arrayNum.clear(); array.clear(); return Res; } /* * 计算缓存格式的表达式的方法 */ long GXAnalyze::calculateCache(string cacheString, vector<GXATSNode> array, void *p_analyze, void *source) { long *paramsStack; int paramsSize = 0; bool isFunction = false; vector<long> paramsTempArray; bool hasNum2 = false; bool isNum1 = true; int num1 = -1; int num2 = -1; GXATSNode res; string op = ""; for (int i = 0; i < cacheString.length(); i++) { if (cacheString[i] == '(') { continue; } if (cacheString[i] == ')') { if (op == "") { res = array[num1]; } else if (hasNum2) { array[num2] = doubleCalculate(array[num1], array[num2], op); res = array[num2]; } else { array[num1] = singleCalculate(array[num1], op); res = array[num1]; } num1 = -1; num2 = -1; hasNum2 = false; isNum1 = true; op = ""; continue; } if (isNumber(cacheString[i])) { if (isNum1) { if (num1 == -1) { num1 = cacheString[i] - '0'; } else { num1 = num1 * 10 + (cacheString[i] - '0'); } } else { hasNum2 = true; if (num2 == -1) { num2 = cacheString[i] - '0'; } else { num2 = num2 * 10 + (cacheString[i] - '0'); } } } else { if (cacheString[i] == ',') { //函数参数 if (!isFunction) { paramsStack = new long[array.size() + 2]; isFunction = true; } GXATSNode node = array[num1]; if (node.token == "num") { GXValue *par = new GXValue(GX_TAG_FLOAT, (float) atof( node.name.c_str())); paramsTempArray.push_back((long) par); } else if (node.token == "long") { GXValue *par = new GXValue(GX_TAG_LONG, (int64_t) atoll( node.name.c_str())); paramsTempArray.push_back((long) par); } else if (node.token == "string") { GXValue *par = new GXValue(GX_TAG_STRING, node.name.c_str()); paramsTempArray.push_back((long) par); } else if (node.token == "bool") { if (node.name == "true") { GXValue *par = new GXValue(GX_TAG_BOOL, 1); paramsTempArray.push_back((long) par); } else { GXValue *par = new GXValue(GX_TAG_BOOL, 0); paramsTempArray.push_back((long) par); } } else if (node.token == "map") { GXValue *par = new GXValue(GX_TAG_MAP, (void *) atol( node.name.c_str())); paramsTempArray.push_back((long) par); } else if (node.token == "array") { GXValue *par = new GXValue(GX_TAG_ARRAY, (void *) atol( node.name.c_str())); paramsTempArray.push_back((long) par); } else if (node.token == "null") { GXValue *par = new GXValue(GX_TAG_NULL, 1); paramsTempArray.push_back((long) par); } else { GXValue *par = new GXValue(GX_TAG_NULL, 1); paramsTempArray.push_back((long) par); } num1 = -1; } else if (cacheString[i] == 'g') { //函数名 if (cacheString[i - 1] != '(') { if (!isFunction) { paramsStack = new long[array.size() + 2]; isFunction = true; } GXATSNode node = array[num1]; num1 = -1; if (node.token == "num") { GXValue *par = new GXValue(GX_TAG_FLOAT, (float) atof( node.name.c_str())); paramsTempArray.push_back((long) par); } else if (node.token == "long") { GXValue *par = new GXValue(GX_TAG_LONG, (int64_t) atoll( node.name.c_str())); paramsTempArray.push_back((long) par); } else if (node.token == "string") { GXValue *par = new GXValue(GX_TAG_STRING, node.name.c_str()); paramsTempArray.push_back((long) par); } else if (node.token == "bool") { if (node.name == "true") { GXValue *par = new GXValue(GX_TAG_BOOL, 1); paramsTempArray.push_back((long) par); } else { GXValue *par = new GXValue(GX_TAG_BOOL, 0); paramsTempArray.push_back((long) par); } } else if (node.token == "map") { GXValue *par = new GXValue(GX_TAG_MAP, (void *) atol( node.name.c_str())); paramsTempArray.push_back((long) par); } else if (node.token == "array") { GXValue *par = new GXValue(GX_TAG_ARRAY, (void *) atol( node.name.c_str())); paramsTempArray.push_back((long) par); } else if (node.token == "null") { GXValue *par = new GXValue(GX_TAG_NULL, 1); paramsTempArray.push_back((long) par); } else { GXValue *par = new GXValue(GX_TAG_NULL, 1); paramsTempArray.push_back((long) par); } } int numFunction = -1; for (int x = i + 1; x < cacheString.length(); x++) { if (isNumber(cacheString[x])) { if (numFunction == -1) { numFunction = cacheString[x] - '0'; } else { numFunction = numFunction * 10 + (cacheString[x] - '0'); } i++; } else { i++; break; } } for (int paramsIndex = paramsTempArray.size() - 1; paramsIndex >= 0; paramsIndex--) { paramsStack[paramsSize] = paramsTempArray[paramsIndex]; ++paramsSize; } paramsTempArray.clear(); GXATSNode node = array[numFunction]; //有参数 long funVal = this->getFunctionValue(array[numFunction].name, paramsStack, paramsSize, ""); if (funVal == 0) { node.name = "null"; node.token = "null"; array[numFunction] = node; res = array[numFunction]; } else { GXValue *fun = (GXValue *) funVal; //取出结果 if (fun->tag == GX_TAG_FLOAT) { node.name = to_string(fun->float64); if (node.name.find('.') != -1) { node.name = regex_replace(node.name, regex("0+?$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 node.name = regex_replace(node.name, regex("[.]$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 } node.token = "num"; } else if (fun->tag == GX_TAG_LONG) { node.name = to_string(fun->intNum); node.token = "long"; } else if (fun->tag == GX_TAG_BOOL) { if (fun->int32 == 1) { node.name = "true"; node.token = "bool"; } else { node.name = "false"; node.token = "bool"; } } else if (fun->tag == GX_TAG_STRING) { node.name = fun->str; node.token = "string"; } else if (fun->tag == GX_TAG_MAP) { node.name = to_string((long) fun->ptr); node.token = "map"; } else if (fun->tag == GX_TAG_ARRAY) { node.name = to_string((long) fun->ptr); node.token = "array"; } else if (fun->tag == GX_TAG_NULL) { node.name = "null"; node.token = "null"; } else { node.name = "null"; node.token = "null"; } array[numFunction] = node; res = array[numFunction]; if (fun != NULL && fun->tag == GX_TAG_STRING && fun->str != NULL) { delete[] fun->str; fun->str = NULL; } if (fun != NULL) { delete fun; } } if (isFunction) { isFunction = false; delete[] paramsStack; } paramsSize = 0; } else { //操作符 isNum1 = false; op = op + cacheString[i]; if (!isNumber(cacheString[i + 1]) && cacheString[i + 1] != ')') { op = op + cacheString[i + 1]; i++; } } } } GXValue *pointer; if (res.token == "string") { pointer = new GXValue(GX_TAG_STRING, res.name); } else if (res.token == "bool") { if (res.name == "true") { pointer = new GXValue(GX_TAG_BOOL, 1); } else { pointer = new GXValue(GX_TAG_BOOL, 0); } } else if (res.token == "num") { pointer = new GXValue(GX_TAG_FLOAT, (float) atof(res.name.c_str())); } else if (res.token == "long") { pointer = new GXValue(GX_TAG_LONG, (int64_t) atoll(res.name.c_str())); } else if (res.token == "map") { pointer = new GXValue(GX_TAG_MAP, (void *) atol(res.name.c_str())); } else if (res.token == "array") { pointer = new GXValue(GX_TAG_ARRAY, (void *) atol(res.name.c_str())); } else if (res.token == "null") { pointer = new GXValue(GX_TAG_NULL, 1); } else { pointer = new GXValue(GX_TAG_NULL, 1); } return (long) pointer; } /* * 语法分析并生成缓存表达式的过程 */ long GXAnalyze::check(string s, vector<GXATSNode> array, void *p_analyze, void *source, string expression) { string tree; if (array.size() == 1) { tree = "(0)"; } GXValue *pointer; GXAnalyze *analyze = (GXAnalyze *) p_analyze; string temp = "\0"; //需要分析的语句 string sentence = s + temp; string *statusStack = new string[sentence.size() + 2]; //状态栈 int statusSize = 0; char *symbolStack = new char[sentence.size() + 2]; //符号栈 int symbolSize = 0; GXATSNode *valueStack = new GXATSNode[sentence.size() + 2]; int valueSize = 0; long *paramsStack = new long[sentence.size() + 2]; int paramsSize = 0; int valueStep = 0; //数值数 vector<long> paramsTempArray; bool isFunction = false; string valueType; symbolStack[symbolSize] = '#'; ++symbolSize; sentence = sentence.substr(1); statusStack[statusSize] = "0"; ++statusSize; string new_status; //下一入栈的新状态 while (true) { string cur_status;//当前状态 char cur_symbol;//当前“展望”字符 cur_status = statusStack[statusSize - 1]; cur_symbol = sentence[0]; string m = cur_status + cur_symbol; //当前new_status,下一入栈的新状态 new_status = gotoTable[m]; if (new_status == "acc") { if (valueStack[0].token == "string") { pointer = new GXValue(GX_TAG_STRING, valueStack[0].name); } else if (valueStack[0].token == "bool") { if (valueStack[0].name == "true") { pointer = new GXValue(GX_TAG_BOOL, 1); } else { pointer = new GXValue(GX_TAG_BOOL, 0); } } else if (valueStack[0].token == "num") { pointer = new GXValue(GX_TAG_FLOAT, (float) atof(valueStack[0].name.c_str())); } else if (valueStack[0].token == "long") { pointer = new GXValue(GX_TAG_LONG, (int64_t) atoll(valueStack[0].name.c_str())); } else if (valueStack[0].token == "map") { pointer = new GXValue(GX_TAG_MAP, (void *) atol(valueStack[0].name.c_str())); } else if (valueStack[0].token == "array") { pointer = new GXValue(GX_TAG_ARRAY, (void *) atol(valueStack[0].name.c_str())); } else if (valueStack[0].token == "null") { pointer = new GXValue(GX_TAG_NULL, 1); } else { pointer = new GXValue(GX_TAG_NULL, 1); } delete[] statusStack; delete[] symbolStack; delete[] valueStack; delete[] paramsStack; mtx.lock(); auto iterEnd = cache.find(s); if (iterEnd == cache.end()) { cache.insert(pair<string, string>{s, tree}); } mtx.unlock(); return (long) pointer; } else if (new_status[0] == 's') { statusStack[statusSize] = new_status.substr(1); ++statusSize; // 1 symbolStack[symbolSize] = cur_symbol; //读入一个字符 ++symbolSize; string temp; auto ite = wordToSymbol.find(cur_symbol); if (ite != wordToSymbol.end()) { temp = ite->second; } if ((isTerminalWord(temp) && (temp == "true" || temp == "false" || temp == "null" || temp == "value" || temp == "num" || temp == "string" || temp == "data" || temp == "id" || temp == "function" || temp == "long")) || (temp == "map" || temp == "array")) { // push value if (isTerminalWord(temp) && temp == "id") { //接下来读入参数,(和)变为运算符 isFunction = true; } GXATSNode t1; if (temp == "value" || temp == "data") { long res = analyze->getSourceValue(array[valueStep].name, source); if (res == 0) { t1.name = "null"; t1.token = "null"; t1.count = array[valueStep].count; valueStack[valueSize] = t1; ++valueSize; } else { GXValue *gxv = (GXValue *) res; t1.count = array[valueStep].count; if (gxv->tag == GX_TAG_FLOAT) { t1.name = to_string(gxv->float64); if (t1.name.find('.') != -1) { t1.name = regex_replace(t1.name, regex("0+?$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 t1.name = regex_replace(t1.name, regex("[.]$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 } t1.token = "num"; } else if (gxv->tag == GX_TAG_LONG) { t1.name = to_string(gxv->intNum); t1.token = "long"; } else if (gxv->tag == GX_TAG_STRING) { t1.name = gxv->str; t1.token = "string"; } else if (gxv->tag == GX_TAG_BOOL) { if (gxv->int32 == 1) { t1.name = "true"; } else { t1.name = "false"; } t1.token = "bool"; } else if (gxv->tag == GX_TAG_ARRAY) { t1.name = to_string((long) (gxv->ptr)); t1.token = "array"; } else if (gxv->tag == GX_TAG_MAP) { t1.name = to_string((long) (gxv->ptr)); t1.token = "map"; } else if (gxv->tag == GX_TAG_NULL) { t1.name = "null"; t1.token = "null"; } else { t1.name = "null"; t1.token = "null"; } valueStack[valueSize] = t1; ++valueSize; if (gxv->tag == GX_TAG_STRING && gxv->str != NULL) { delete[] gxv->str; gxv->str = NULL; } delete gxv; } } else if (temp == "function") { long res = analyze->getFunctionValue(array[valueStep].name, nullptr, 0, ""); if (res == 0) { t1.name = "null"; t1.token = "null"; t1.count = array[valueStep].count; valueStack[valueSize] = t1; ++valueSize; } else { GXValue *gxv = (GXValue *) res; t1.count = array[valueStep].count; if (gxv->tag == GX_TAG_FLOAT) { t1.name = to_string(gxv->float64); if (t1.name.find('.') != -1) { t1.name = regex_replace(t1.name, regex("0+?$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 t1.name = regex_replace(t1.name, regex("[.]$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 } t1.token = "num"; } else if (gxv->tag == GX_TAG_LONG) { t1.name = to_string(gxv->intNum); t1.token = "long"; } else if (gxv->tag == GX_TAG_STRING) { t1.name = gxv->str; t1.token = "string"; } else if (gxv->tag == GX_TAG_BOOL) { if (gxv->int32 == 1) { t1.name = "true"; } else { t1.name = "false"; } t1.token = "bool"; } else if (gxv->tag == GX_TAG_ARRAY) { t1.name = to_string((long) (gxv->ptr)); t1.token = "array"; } else if (gxv->tag == GX_TAG_MAP) { t1.name = to_string((long) (gxv->ptr)); t1.token = "map"; } else if (gxv->tag == GX_TAG_NULL) { t1.name = "null"; t1.token = "null"; } else { t1.name = "null"; t1.token = "null"; } valueStack[valueSize] = t1; ++valueSize; if (gxv->tag == GX_TAG_STRING && gxv->str != NULL) { delete[] gxv->str; gxv->str = NULL; } delete gxv; } } else { valueStack[valueSize] = array[valueStep]; ++valueSize; } } valueStep = valueStep + 1; sentence = sentence.substr(1); } else if (new_status[0] == 'r') { new_status = new_status.substr(1); int gid = atoi(new_status.c_str()); int len = grammarProduct[gid].size() - 1; if (len == 1) { char reduced_symbol = grammarProduct[gid][0]; string m = statusStack[statusSize - 2] + reduced_symbol; new_status = gotoTable[m]; statusStack[statusSize - 1] = (new_status); symbolStack[symbolSize - 1] = (reduced_symbol); } else { string *action = new string[len]; GXATSNode t1; GXATSNode t2; string op; bool changedT1 = false; bool changedT2 = false; GXATSNode tempR; GXATSNode tempR2; bool isChangedOp = false; char reduced_symbol = grammarProduct[gid][0]; unordered_map<char, string>::iterator iterAction; for (int i = 0; i < len; i++) { iterAction = wordToSymbol.find(symbolStack[symbolSize - 1]); if (iterAction != wordToSymbol.end()) { action[i] = iterAction->second; } // action[i] = wordToSymbol[symbolStack[symbolSize - 1]]; --statusSize; --symbolSize; } for (int i = 0; i < len; i++) { if ((isTerminalWord(action[i]) && !((action[i] == "true" || action[i] == "false" || action[i] == "null" || action[i] == "value" || action[i] == "num" || action[i] == "string" || action[i] == "long" || action[i] == "data" || action[i] == "id"))) || (action[i] == "map" || action[i] == "array")) { if (!isChangedOp) { op = action[i]; isChangedOp = true; } } else { if (!changedT1) { changedT1 = true; } else { changedT2 = true; } } } delete[] action; if (len > 1) { if (changedT2) { if (valueSize < 2) { delete[] statusStack; delete[] symbolStack; delete[] valueStack; delete[] paramsStack; analyze->throwError("expressionError: expression '" + expression + "' missing calculation element"); return 0L; } t2 = valueStack[valueSize - 1]; t1 = valueStack[valueSize - 2]; if (isFunction) { if (op == "(") { tempR = t1; --valueSize; } else if (op == ",") { tempR = t1; tempR2 = t2; valueSize = valueSize - 2; } else if (op == ")") { int ParamsSize = valueSize - 1; for (int i = valueSize - 1; i >= 0; i--) { if (i == ParamsSize) { tree = tree + '('; } if (valueStack[i].token == "id") { //需要翻转一遍,否则取到的参数顺序是反过来的 for (int paramsIndex = paramsTempArray.size() - 1; paramsIndex >= 0; paramsIndex--) { paramsStack[paramsSize] = paramsTempArray[paramsIndex]; ++paramsSize; } paramsTempArray.clear(); //这里特别注意,g是函数的识别符,需要和运算符做区分 tree = tree + "g" + to_string(valueStack[i].count) + ")"; //在这里调用获取函数结果方法 long funVal = analyze->getFunctionValue(valueStack[i].name, paramsStack, paramsSize, ""); if (funVal == 0) { tempR.name = "null"; tempR.token = "null"; tempR.count = valueStack[i].count; --valueSize; isFunction = false; paramsSize = 0; break; } GXValue *fun = (GXValue *) funVal; tempR.count = valueStack[i].count; //取出结果 if (fun->tag == GX_TAG_FLOAT) { tempR.name = to_string(fun->float64); if (tempR.name.find('.') != -1) { tempR.name = regex_replace(tempR.name, regex("0+?$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 tempR.name = regex_replace(tempR.name, regex("[.]$"), ""); // 除了捕捉到的组以外,其他的东西均舍弃 } tempR.token = "num"; } else if (fun->tag == GX_TAG_LONG) { tempR.name = to_string(fun->intNum); tempR.token = "long"; } else if (fun->tag == GX_TAG_BOOL) { if (fun->int32 == 1) { tempR.name = "true"; tempR.token = "bool"; } else { tempR.name = "false"; tempR.token = "bool"; } } else if (fun->tag == GX_TAG_STRING) { tempR.name = fun->str; tempR.token = "string"; } else if (fun->tag == GX_TAG_MAP) { tempR.name = to_string((long) fun->ptr); tempR.token = "map"; } else if (fun->tag == GX_TAG_ARRAY) { tempR.name = to_string((long) fun->ptr); tempR.token = "array"; } else if (fun->tag == GX_TAG_NULL) { tempR.name = "null"; tempR.token = "null"; } else { tempR.name = "null"; tempR.token = "null"; } --valueSize; isFunction = false; paramsSize = 0; if (fun->tag == GX_TAG_STRING && fun->str != NULL) { delete[] fun->str; fun->str = NULL; } delete fun; break; } else { if (valueStack[i - 1].token != "id") { tree = tree + to_string(valueStack[i].count) + ","; } else { tree = tree + to_string(valueStack[i].count); } //往vector<GXValue>逐个扔进去参数,然后通过id调用 if (valueStack[i].token == "num") { GXValue *par = new GXValue(GX_TAG_FLOAT, (float) atof( valueStack[i].name.c_str())); paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "long") { GXValue *par = new GXValue(GX_TAG_LONG, (int64_t) atoll( valueStack[i].name.c_str())); paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "string") { GXValue *par = new GXValue(GX_TAG_STRING, valueStack[i].name.c_str()); paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "bool") { if (valueStack[i].name == "true") { GXValue *par = new GXValue(GX_TAG_BOOL, 1); paramsTempArray.push_back((long) par); } else { GXValue *par = new GXValue(GX_TAG_BOOL, 0); paramsTempArray.push_back((long) par); } } else if (valueStack[i].token == "map") { GXValue *par = new GXValue(GX_TAG_MAP, (void *) atol( valueStack[i].name.c_str())); paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "array") { GXValue *par = new GXValue(GX_TAG_ARRAY, (void *) atol( valueStack[i].name.c_str())); paramsTempArray.push_back((long) par); } else if (valueStack[i].token == "null") { GXValue *par = new GXValue(GX_TAG_NULL, 1); paramsTempArray.push_back((long) par); } else { GXValue *par = new GXValue(GX_TAG_NULL, 1); paramsTempArray.push_back((long) par); } --valueSize; } } } else { delete[] statusStack; delete[] symbolStack; delete[] valueStack; delete[] paramsStack; analyze->throwError("expressionError: wrong function expression"); return 0L; } } else { valueSize = valueSize - 2; tempR = doubleCalculate(t1, t2, op); tempR.count = t2.count; tree = tree + '(' + to_string(t1.count) + op + to_string(t2.count) + ')'; if (tempR.token == "error") { delete[] statusStack; delete[] symbolStack; delete[] valueStack; delete[] paramsStack; analyze->throwError(tempR.name); return 0L; } } } else { if (valueSize < 1) { delete[] statusStack; delete[] symbolStack; delete[] valueStack; delete[] paramsStack; analyze->throwError( "expressionError: expression has 0 value after operator, but must have 1 value"); return 0L; } t1 = valueStack[valueSize - 1]; --valueSize; tempR = singleCalculate(t1, op); tempR.count = t1.count; if (op != ")" && op != ",") { tree = tree + '(' + to_string(t1.count) + op + ')'; } if (tempR.token == "error") { analyze->throwError(tempR.name); return 0L; } } if (isFunction && op == ",") { valueStack[valueSize] = tempR; valueStack[valueSize + 1] = tempR2; valueSize = valueSize + 2; } else { valueStack[valueSize] = tempR; ++valueSize; } } string m = statusStack[statusSize - 1] + reduced_symbol; new_status = gotoTable[m]; statusStack[statusSize] = new_status; ++statusSize; symbolStack[symbolSize] = reduced_symbol; ++symbolSize; } } else { if (valueStep <= 0) { valueStep = 1; } string value = array[valueStep - 1].name; delete[] statusStack; delete[] symbolStack; delete[] valueStack; delete[] paramsStack; analyze->throwError( "expressionError: unexpected identifier '" + value + "' in expression '" + expression + "'"); return 0L; } } }