long GXAnalyze::check()

in GaiaXiOS/GaiaXiOS/Binding/Expression/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;
        }
    }
}