void getClosure()

in GaiaXHarmony/GaiaXAnalyze/GXAnalyzeCore/GXAnalyze.cpp [224:362]


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++;
    }
}