in GaiaXAnalyze/GXAnalyzeCore/GXAnalyze.cpp [1470:1951]
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;
}
}
}