#include "libsyntax.h" #include "ast_basic.h" #include #include using namespace lib_syntax; using namespace std; using namespace lib_token; using namespace lib_words; using namespace ast_basic; __anyone_impl::__anyone_impl(const QList> mbrs) : mbrs_store(mbrs) { } QList> __anyone_impl::children() const { return mbrs_store; } QList> __anyone_impl::parse(std::shared_ptr cursor, QList>& out) const { if (cursor->parseStop()) return QList>() << cursor; auto syntax = present(); QList> result_list; for (auto rx : this->children()) result_list.append(rx->parse(cursor, out)); // 完全匹配分支 decltype(result_list) completely_list; std::copy_if(result_list.begin(), result_list.end(), std::back_inserter(completely_list), [&](std::shared_ptr ins) { return cursor->totalErrorCount() == ins->totalErrorCount(); }); if (completely_list.size()) return completely_list; // 经过修正的分支 decltype(result_list) modify_list; std::copy_if(result_list.begin(), result_list.end(), std::back_inserter(modify_list), [&](std::shared_ptr ins) { return !ins->parseStop(); }); if (modify_list.size()) return modify_list; return result_list; } QString __anyone_impl::present() const { QString members_content; for (auto& it : children()) { members_content += it->present() + "|"; } return members_content.mid(0, members_content.size() - 1); } __sequence_impl::__sequence_impl(const QList> mbrs) : mbrs_store(mbrs) { } QList> __sequence_impl::children() const { return mbrs_store; } QList> __sequence_impl::parse(std::shared_ptr cursor, QList>& out) const { if (cursor->parseStop()) return QList>() << cursor; QList> bridge_list{ cursor }; for (auto rule : this->children()) { QList> current_result; for (auto vcurs : bridge_list) { if (!vcurs->parseStop()) { current_result.append(rule->parse(vcurs, out)); } } // 完全匹配的分支 decltype(current_result) temprary_list; std::copy_if(current_result.begin(), current_result.end(), std::back_inserter(temprary_list), [&](std::shared_ptr ins) { return cursor->totalErrorCount() == ins->totalErrorCount(); }); if (temprary_list.size()) { bridge_list = temprary_list; continue; } // 经过修复的分支 std::copy_if(current_result.begin(), current_result.end(), std::back_inserter(temprary_list), [&](std::shared_ptr ins) { return !ins->parseStop(); }); if (temprary_list.size()) { bridge_list = temprary_list; continue; } bridge_list = current_result; break; } return bridge_list; } QString __sequence_impl::present() const { QString content; for (auto& it : children()) content += it->present() + " "; return content.mid(0, content.size() - 1); } __repeat_impl::__repeat_impl(std::shared_ptr rule, int min, int max) : rule_peer(rule), min_match(min), max_match(max) { } QList> __repeat_impl::children() const { return QList>() << rule_peer; } #include auto content_extractw = [](std::shared_ptr token) { QString content; while (token) { if (token->defines()) content.prepend(token->content() + " "); token = token->prevToken(); } return content; }; QList> __repeat_impl::parse(std::shared_ptr cursor, QList>& out) const { if (cursor->parseStop()) return QList>() << cursor; auto syntax = present(); QList> max_match_begin = { cursor }; if (min_match) { QList> temp_rules; for (auto idx = 0; idx < min_match; ++idx) temp_rules << this->rule_peer; auto seqs_rule = std::make_shared<__sequence_impl>(temp_rules); max_match_begin = seqs_rule->parse(cursor, out); } // 如果不满足最小重复匹配次数要求,则返回 int continue_count = std::count_if(max_match_begin.begin(), max_match_begin.end(), [](std::shared_ptr ins) { return !ins->parseStop(); }); if (!continue_count) return max_match_begin; // 最小匹配次数中所有错误分支都是无用的、需要舍弃 for (auto idx = 0; idx < max_match_begin.size(); ++idx) { auto current_cursor = max_match_begin.at(idx); if (current_cursor->parseStop()) max_match_begin.removeAt(idx--); } QList> results; decltype(results) bridge_list = max_match_begin; // 尝试重复匹配最大次数 for (auto idx = min_match; idx < max_match; ++idx) { QList> current_list; // 匹配迭代一次 for (auto ins : bridge_list) current_list.append(this->rule_peer->parse(ins, out)); QList contents; for (auto bx : current_list) contents << content_extractw(bx->currentToken()) + QStringList(bx->totalErrors()).join(','); // 提取完全匹配的分支 QList> temprary_branchs; std::copy_if(current_list.begin(), current_list.end(), std::back_inserter(temprary_branchs), [&](std::shared_ptr ins) { return cursor->totalErrorCount() == ins->totalErrorCount() && ins->currentToken()->position() > cursor->currentToken()->position(); }); if (temprary_branchs.size()) { bridge_list = temprary_branchs; continue; } // 提取语法修正分支 std::copy_if(current_list.begin(), current_list.end(), std::back_inserter(temprary_branchs), [&](std::shared_ptr ins) { return !ins->parseStop() && ins->currentToken()->position() > cursor->currentToken()->position(); }); if (temprary_branchs.size()) { bridge_list = temprary_branchs; continue; } break; } results.append(bridge_list); std::sort(results.begin(), results.end(), [](std::shared_ptr a, std::shared_ptr b) { return a->currentToken()->position() > b->currentToken()->position(); }); // 提取完全匹配的分支 decltype(results) rets_completely; for (auto ins : results) { if (ins->totalErrorCount() == cursor->totalErrorCount()) { if (!rets_completely.size()) { rets_completely.append(ins); } else if (rets_completely.last()->currentToken()->position() == ins->currentToken()->position()) { rets_completely.append(ins); } } } // 提取经过修正的分支 decltype(results) rets_modified; for (auto ins : results) { if (!ins->parseStop()) { if (!rets_modified.size()) { rets_modified.append(ins); } else if (rets_modified.last()->currentToken()->position() == ins->currentToken()->position()) { rets_modified.append(ins); } } } // 允许持续的集合 rets_completely.append(rets_modified); if (rets_completely.size()) return rets_completely; return results; } QString __repeat_impl::present() const { if (min_match == 0 && max_match == INT_MAX) return "(" + this->rule_peer->present() + QString(")*"); else if (min_match == 1 && max_match == INT_MAX) return "(" + this->rule_peer->present() + QString(")+"); else if (min_match == 0 && max_match == 1) return "(" + this->rule_peer->present() + QString(")?"); return "(" + this->rule_peer->present() + QString("){%1, %2}").arg(min_match).arg(max_match); } SyntaxException::SyntaxException(const QString& message) { this->msg_store = message; } QString SyntaxException::message() const { return msg_store; } ExprRule::ExprRule(const QString& rule_name, int expr_mark) : name_store(rule_name), mark_store(expr_mark) { } QString ExprRule::name() const { return name_store; } int ExprRule::typeMark() const { return this->mark_store; } #include MatchCursor::MatchCursor(const QString& path) :_file_path(path) { } MatchCursor::MatchCursor(std::shared_ptr other_ptr) : _prev_cursor(other_ptr), _file_path(other_ptr->_file_path), _total_errors(other_ptr->_total_errors), _current_token(other_ptr->_current_token), _remains_word(other_ptr->_remains_word) { for (auto err_pack : other_ptr->_exprs_errors) { _exprs_errors << std::make_shared(*err_pack); } } std::shared_ptr MatchCursor::previous() const { return _prev_cursor; } QString MatchCursor::filePath() const { return _file_path; } QString lib_syntax::MatchCursor::parseSyntax() const { if (!this->previous()) return QString(); QString token_split = this->currentToken()->defines() ? this->currentToken()->defines()->regex() : ""; return this->previous()->parseSyntax() + " " + token_split; } void MatchCursor::enterExprs() { auto new_expr = std::make_shared(); this->_exprs_errors.push_back(new_expr); } void MatchCursor::logExprsError(const QString& msg) { this->_total_errors.push_back(msg); this->_exprs_errors.last()->addError(msg); // 普适性质的判定标准 this->setStop(this->exprsErrorCount() > 1); } void MatchCursor::quitExprs() { this->_exprs_errors.pop_back(); } bool lib_syntax::MatchCursor::parseStop() const { return this->_parse_proc_stop; } void lib_syntax::MatchCursor::setStop(bool mark) { this->_parse_proc_stop = mark; } int MatchCursor::exprsErrorCount() const { if (this->_exprs_errors.size()) return this->_exprs_errors.last()->errorCount(); return 0; } int MatchCursor::totalErrorCount() const { return this->_total_errors.size(); } QList MatchCursor::totalErrors() const { return this->_total_errors; } void MatchCursor::setCurrent(std::shared_ptr t, std::shared_ptr remains) { this->_current_token = t; this->_remains_word = remains; } std::shared_ptr MatchCursor::currentToken() const { return this->_current_token; } std::shared_ptr MatchCursor::currentWords() const { return this->_remains_word; } lib_syntax::MatchCursor::ErrsPack::ErrsPack() { } lib_syntax::MatchCursor::ErrsPack::ErrsPack(const ErrsPack& other) : _error_collection(other._error_collection) { } void MatchCursor::ErrsPack::addError(const QString& msg) { this->_error_collection.append(msg); } QList MatchCursor::ErrsPack::errors() const { return _error_collection; } uint64_t MatchCursor::ErrsPack::errorCount() const { return _error_collection.size(); }