#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; Any::Any(const QList> mbrs) : mbrs_store(mbrs) { } QList> Any::children() const { return mbrs_store; } QList> Any::parse(std::shared_ptr cursor) const { if (cursor->mustStop()) return QList>() << cursor; QList> result_list; for (auto rx : this->children()) result_list.append(rx->parse(cursor)); return result_list; } QString Any::present() const { QString members_content; for (auto& it : children()) { members_content += it->present() + u8"|"; } return members_content.mid(0, members_content.size() - 1); } Seqs::Seqs(const QList> mbrs) : mbrs_store(mbrs) { } QList> Seqs::children() const { return mbrs_store; } QList> Seqs::parse(std::shared_ptr cursor) const { if (cursor->mustStop()) return QList>() << cursor; QList> results; QList> bridge_list{ cursor }; for (auto rule : this->children()) { QList> current_result; std::for_each(bridge_list.begin(), bridge_list.end(), [&](std::shared_ptr vcurs) { if (vcurs->mustStop()) results.push_back(vcurs); else { current_result.append(rule->parse(vcurs)); } }); bridge_list = current_result; } results.append(bridge_list); return results; } QString Seqs::present() const { QString content; for (auto& it : children()) content += it->present() + " "; return content.mid(0, content.size() - 1); } Rept::Rept(std::shared_ptr rule, int min, int max) : rule_peer(rule), min_match(min), max_match(max) { } QList> Rept::children() const { return QList>() << rule_peer; } QList> Rept::parse(std::shared_ptr cursor) const { if (cursor->mustStop()) return QList>() << cursor; QList> results; QList> bridge_list{ cursor }; // 最小重复次数匹配 for (auto idx = 0; idx < min_match; ++idx) { QList> current_list; // 迭代每一次可能匹配 std::for_each(bridge_list.begin(), bridge_list.end(), [&](std::shared_ptr curs) { if (curs->mustStop()) results.push_back(curs); else { current_list.append(this->rule_peer->parse(curs)); } }); bridge_list = current_list; } // 归并失败分支 std::copy_if(bridge_list.begin(), bridge_list.end(), std::back_inserter(results), [&](std::shared_ptr ins) { return ins->mustStop(); }); // 清除匹配失败分支 for (auto idx = 0; idx < bridge_list.size(); ++idx) if (bridge_list.at(idx)->mustStop()) bridge_list.removeAt(idx--); // 不满足最小匹配 if (!bridge_list.size()) return results; // 尝试重复匹配最大次数 for (auto idx = min_match; idx < max_match; ++idx) { QList> current_list; // 匹配迭代一次 std::for_each(bridge_list.begin(), bridge_list.end(), [&](std::shared_ptr ins) { current_list.append(this->rule_peer->parse(ins)); }); // 移除失败分支 for (auto idx = 0; idx < current_list.size(); ++idx) { auto rst_branch = current_list.at(idx); if (rst_branch->mustStop() && rst_branch->currentWords()) { results.append(rst_branch->previous()); current_list.removeAt(idx--); } if (rst_branch->mustStop() && !rst_branch->currentWords()) { results.append(rst_branch); current_list.removeAt(idx--); } } if (!current_list.size()) break; bridge_list = current_list; } results.append(bridge_list); return results; } QString Rept::present() const { if (min_match == 0 && max_match == INT_MAX) return u8"(" + this->rule_peer->present() + QString(u8")*"); else if (min_match == 1 && max_match == INT_MAX) return u8"(" + this->rule_peer->present() + QString(u8")+"); else if (min_match == 0 && max_match == 1) return u8"(" + this->rule_peer->present() + QString(u8")?"); return u8"(" + this->rule_peer->present() + QString(u8"){%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) { } std::shared_ptr ExprRule::reloadRule(std::shared_ptr rule) const { auto ninst = this->make_copy(); ninst->child_store = rule; return ninst; } QString ExprRule::name() const { return name_store; } int ExprRule::typeMark() const { return this->mark_store; } QList> ExprRule::children() const { return QList>() << this->child_store; } #include QString ExprRule::present() const { return child_store->present(); } 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), _exprs_errors(other_ptr->_exprs_errors), _current_token(other_ptr->_current_token), _remains_word(other_ptr->_remains_word) { } std::shared_ptr MatchCursor::previous() const { return _prev_cursor; } QString MatchCursor::filePath() const { return _file_path; } 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); } void MatchCursor::quitExprs() { this->_exprs_errors.pop_back(); } bool MatchCursor::mustStop() const { return exprsErrorCount() >= 2 || parse_stop(); } 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; } bool lib_syntax::MatchCursor::parse_stop() const { return !currentWords(); } 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(); }