#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; auto content_extractm = [](std::shared_ptr token) { QString content; while (token) { if (token->defines()) content.prepend(token->content() + " "); token = token->prevToken(); } return content; }; __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) const { if (cursor->parseFailure() || cursor->parseComplete()) return QList>() << cursor; auto syntax = present(); QList> result_list; for (auto rx : this->children()) result_list.append(rx->parse(cursor)); // 完全匹配分支,必须有匹配进展 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() && ins->operator>(*cursor)) || ins->parseComplete(); }); if (completely_list.size()) return completely_list.mid(0,1); // 经过修正的分支,必须有变化 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->parseFailure() && ins->totalErrorCount() > cursor->totalErrorCount(); }); if (modify_list.size()) return modify_list; // 匹配失败的分支 decltype(result_list) errors_list; std::copy_if(result_list.begin(), result_list.end(), std::back_inserter(errors_list), [](std::shared_ptr it) { return it->parseFailure(); }); return errors_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) const { if (cursor->parseFailure() || cursor->parseComplete()) return QList>() << cursor; QList> bridge_list{ cursor }; for (auto rule : this->children()) { QList> current_result; for (auto vcurs : bridge_list) { if (!vcurs->parseFailure()) { current_result.append(rule->parse(vcurs)); } } // 完全匹配的分支 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() || ins->parseComplete(); }); if (temprary_list.size()) { bridge_list = temprary_list.mid(0,1); continue; } // 经过修复的分支 std::copy_if(current_result.begin(), current_result.end(), std::back_inserter(temprary_list), [&](std::shared_ptr ins) { return !ins->parseFailure(); }); if (temprary_list.size()) { bridge_list = temprary_list; continue; } bridge_list = current_result; break; } decltype(bridge_list) temprary_list; // 匹配代码有进展或者匹配成功 std::copy_if(bridge_list.begin(), bridge_list.end(), std::back_inserter(temprary_list), [&](std::shared_ptr ins) { return ins->operator>(*cursor) || ins->parseComplete(); }); if (temprary_list.size()) return temprary_list; std::copy_if(bridge_list.begin(), bridge_list.end(), std::back_inserter(temprary_list), [](std::shared_ptr ins) { return ins->parseFailure(); }); return temprary_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 QList> __repeat_impl::parse(std::shared_ptr cursor) const { if (cursor->parseFailure() || cursor->parseComplete()) 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); } // 如果不满足最小重复匹配次数要求,则返回 int continue_count = std::count_if(max_match_begin.begin(), max_match_begin.end(), [](std::shared_ptr ins) { return !ins->parseFailure(); }); 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->parseFailure()) 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)); QList contents; for (auto bx : current_list) contents << content_extractm(bx->token()) + 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) > (*cursor)) || ins->parseComplete(); }); if (temprary_branchs.size()) { bridge_list = temprary_branchs.mid(0, 1); continue; } // 提取语法修正分支 std::copy_if(current_list.begin(), current_list.end(), std::back_inserter(temprary_branchs), [&](std::shared_ptr ins) { return !ins->parseFailure() && (*ins) > (*cursor); }); 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->operator>(*b); }); // 提取完全匹配的分支 decltype(results) rets_completely; for (auto ins : results) { if (ins->totalErrorCount() == cursor->totalErrorCount() && !rets_completely.size()) { rets_completely.append(ins); break; } else if (ins->parseComplete()) rets_completely.append(ins); } // 提取经过修正的分支 decltype(results) rets_modified; for (auto ins : results) { if (!ins->parseFailure()) { if (!rets_modified.size()) { rets_modified.append(ins); } else if (rets_modified.last()->token()->position() == ins->token()->position()) { rets_modified.append(ins); } } } // 允许持续的集合 for (auto rst : rets_modified) if (!rets_completely.contains(rst)) rets_completely.append(rst); 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); } } bool lib_syntax::MatchCursor::operator>(const MatchCursor& other) const { return _current_token->position() > other._current_token->position() || (_current_token->position() == other._current_token->position() && _total_errors.size() > other._total_errors.size()); } 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_splitx; switch (this->token()->tokenType()) { case lib_token::IActionToken::Type::ElementBegin: token_splitx = ""; break; case lib_token::IActionToken::Type::TokenBind: token_splitx = this->token()->defines()->regex(); break; case lib_token::IActionToken::Type::ElementEnd: token_splitx = ""; break; } return this->previous()->parseSyntax() + " " + token_splitx; } void MatchCursor::enterExprs() { auto new_expr = std::make_shared(); this->_exprs_errors.push_back(new_expr); } void lib_syntax::MatchCursor::logExprsError(std::shared_ptr t, const QString& msg) { if(!this->_total_errors.contains(t->position())) this->_total_errors[t->position()] = QStringList(); auto exists = this->_total_errors[t->position()]; exists.append(msg); this->_total_errors[t->position()] = exists; this->_exprs_errors.last()->addError(t, msg); // 普适性质的判定标准 this->setFailure(this->exprsErrorCount() > 1); } void MatchCursor::quitExprs() { this->_exprs_errors.pop_back(); } bool lib_syntax::MatchCursor::parseFailure() const { return this->_parse_stop_with_errors; } void lib_syntax::MatchCursor::setFailure(bool mark) { this->_parse_stop_with_errors = mark; } bool lib_syntax::MatchCursor::parseComplete() const { return this->_parse_complete; } void lib_syntax::MatchCursor::setComplete(bool mark) { this->_parse_complete = 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 { QStringList flist; for(auto set : this->_total_errors) flist.append(set); return flist; } void lib_syntax::MatchCursor::mergeWith(const MatchCursor& other) { for(auto key : other._total_errors.keys()){ if (!this->_total_errors.contains(key)) this->_total_errors[key] = QStringList(); auto values = other._total_errors[key]; auto this_values = this->_total_errors[key]; this_values.append(values); this->_total_errors[key] = this_values; } for (auto key : this->_total_errors.keys()) { auto values = this->_total_errors[key]; values = values.toSet().toList(); this->_total_errors[key] = values; } } void MatchCursor::setCurrent(std::shared_ptr t, std::shared_ptr remains) { this->_current_token = t; this->_remains_word = remains; } std::shared_ptr MatchCursor::token() const { return this->_current_token; } std::shared_ptr MatchCursor::words() const { return this->_remains_word; } lib_syntax::MatchCursor::ErrsPack::ErrsPack() { } lib_syntax::MatchCursor::ErrsPack::ErrsPack(const ErrsPack& other) : _error_collection(other._error_collection) { } void lib_syntax::MatchCursor::ErrsPack::addError(std::shared_ptr t, const QString& msg) { this->_error_collection << std::make_pair(t, msg); } QList, QString>> MatchCursor::ErrsPack::errors() const { return _error_collection; } uint64_t MatchCursor::ErrsPack::errorCount() const { return _error_collection.size(); }