#include "libsyntax.h" #include "ast_basic.h" #include using namespace lib_syntax; using namespace std; using namespace lib_token; using namespace ast_basic; TokenMatch::TokenMatch(shared_ptr define) : define_peer(define) {} QList> TokenMatch::children() const { return QList>(); } QList TokenMatch::parse(const ParseFork& context) const { auto head = context.next; if (!head) { ParseFork result(context); result.error_messages << u8"输入流提前终止"; result.next = nullptr; result.occurs = ErrDeals::TerminalAOT; return QList{result}; } if (head->content() == u8"SDK反拉扥") { qDebug() << true; } QList result_list; auto match_result = define_peer->analysis(head); if (get<0>(match_result)) { ParseFork success_fork(context); success_fork.tokens_list << get<0>(match_result); if (get<1>(match_result)) { success_fork.next = make_shared(get<1>(match_result), head->nextWord()); } else { success_fork.next = head->nextWord(); } result_list << success_fork; } else { if (context.occurs != ErrDeals::None) { ParseFork fail_fork(context); fail_fork.error_messages << QString(u8"Syntax[0x0001]解析终止,Token匹配失败('%1')。") .arg(head->content()).arg(head->row()).arg(head->column()); fail_fork.next = nullptr; fail_fork.occurs = ErrDeals::Abort; return result_list << fail_fork; } // 缺一个 ParseFork absence_fork(context); result_list << absence_fork; absence_fork.error_messages << QString(u8"Syntax[0x0002]缺失Token('%1')。") .arg(this->token_present()).arg(head->row()).arg(head->column()); absence_fork.next = head; absence_fork.occurs = ErrDeals::Absence; // 错一个 ParseFork replace_fork(context); result_list << replace_fork; replace_fork.error_messages << QString(u8"Syntax[0x0003]纠正Token('%1',应该为'%4')。") .arg(head->content()).arg(head->row()).arg(head->column()).arg(this->token_present()); replace_fork.next = head->nextWord(); replace_fork.occurs = ErrDeals::Replace; // 多一个 auto temp_head = head->nextWord(); auto match_result = define_peer->analysis(temp_head); if (get<0>(match_result)) { ParseFork surplus_fork(context); result_list << surplus_fork; surplus_fork.error_messages << QString(u8"Syntax[0x0004]发现冗余Token('%1')。") .arg(head->content()).arg(head->row()).arg(head->column()); surplus_fork.occurs = ErrDeals::Surplus; surplus_fork.tokens_list << get<0>(match_result); if (get<1>(match_result)) surplus_fork.next = make_shared(get<1>(match_result), temp_head->nextWord()); else surplus_fork.next = temp_head->nextWord(); } } return result_list; } QString TokenMatch::token_present() const { return QString(u8"%1 ").arg(this->define_peer->reviseWords()); } Rept::Rept(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 tidy_results(QList temp_results) { QList ret_forks; std::copy_if(temp_results.begin(), temp_results.end(), std::back_inserter(ret_forks), [](ParseFork elm)->bool { return elm.occurs == ErrDeals::None; }); // 成功匹配 if (ret_forks.size()) return ret_forks; std::copy_if(temp_results.begin(), temp_results.end(), std::back_inserter(ret_forks), [](ParseFork elm)->bool { return elm.occurs == ErrDeals::Absence || elm.occurs == ErrDeals::Surplus || elm.occurs == ErrDeals::Replace; }); // 修正匹配 if (ret_forks.size()) return ret_forks; // 失败匹配 return temp_results; } QList Rept::parse(const ParseFork& context) const { std::function(const ParseFork&, int)> min_match_calc = [&](const ParseFork& context, int times_remains)->QList { QList retvs; if (!times_remains) return retvs << context; auto result_present = rule_peer->token_present(); auto result_forks = rule_peer->parse(context); for (auto it : result_forks) { switch (it.occurs) { case ErrDeals::Abort: case ErrDeals::TerminalAOT: retvs << it; break; default: retvs << min_match_calc(it, times_remains - 1); break; } } return retvs; }; std::function(const ParseFork&, int)> max_match_calc = [&](const ParseFork& context, int times_remains) -> QList { QList retvs; if (!times_remains) return retvs << context; auto result_present = rule_peer->token_present(); auto result_forks = rule_peer->parse(context); for (auto rst : result_forks) { switch (rst.occurs) { case ErrDeals::Abort: case ErrDeals::TerminalAOT: retvs << context; break; case ErrDeals::Surplus: case ErrDeals::Absence: case ErrDeals::Replace: if (context.occurs == ErrDeals::None) retvs << context; default: retvs << max_match_calc(rst, times_remains - 1); break; } } return retvs;; }; auto temp_results = min_match_calc(context, min_match); auto rst_itor = std::find_if(temp_results.begin(), temp_results.end(), [](ParseFork e) -> bool { return QList{ ErrDeals::None, ErrDeals::Surplus, ErrDeals::Absence, ErrDeals::Replace }.contains(e.occurs); }); if (rst_itor == temp_results.end()) return temp_results; decltype(temp_results) result_x2; for (auto xit : temp_results) result_x2 << max_match_calc(xit, max_match - min_match); return tidy_results(result_x2); } QString Rept::token_present() const { return u8"(" + this->rule_peer->token_present() + QString(u8"){%1, %2}").arg(min_match).arg(max_match); } Seqs::Seqs(const QList> mbrs) : mbrs_store(mbrs) {} QList> Seqs::children() const { return mbrs_store; } QList Seqs::parse(const ParseFork& context) const { function(const ParseFork&, QList>::const_iterator)> match_seqs = [&](const ParseFork& context, QList>::const_iterator rule_it) -> QList { QList retvs; auto cendx = mbrs_store.cend(); if (rule_it == mbrs_store.cend()) return retvs << context; auto rule_present = (*rule_it)->token_present(); auto result_forks = (*rule_it)->parse(context); for (auto fork : result_forks) { switch (fork.occurs) { case ErrDeals::Abort: case ErrDeals::TerminalAOT: retvs << fork; break; default: retvs << match_seqs(fork, rule_it + 1); break; } } return retvs; }; auto temp_results = match_seqs(context, mbrs_store.cbegin()); return tidy_results(temp_results); } QString Seqs::token_present() const { QString content; for (auto& it : children()) content += it->token_present(); return content; } Any::Any(const QList> mbrs) : mbrs_store(mbrs) {} QList> Any::children() const { return mbrs_store; } QList Any::parse(const ParseFork& context) const { auto rule_present = this->token_present(); QList temp_results; for (auto& fork : mbrs_store) { auto result_forks = fork->parse(context); for (auto rst_fork : result_forks) { switch (rst_fork.occurs) { case ErrDeals::None: return QList{ rst_fork }; default: temp_results << rst_fork; break; } } } return tidy_results(temp_results); } QString Any::token_present() const { QString members_content; for (auto& it : children()) { members_content += it->token_present() + u8"|"; } return members_content.mid(0, members_content.size() - 1); } 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) { this->mark_store = expr_mark; } shared_ptr ExprRule::reloadRule(shared_ptr rule) { auto ninst = makeCopy(); 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 QList ExprRule::parse(const ParseFork& context) const { auto text_present = this->token_present(); ParseFork elm_start; elm_start.next = context.next; QList temp_returns; auto result_forks = child_store->parse(elm_start); for (auto fork : result_forks) { switch (fork.occurs) { case ErrDeals::None: { ParseFork value(context); shared_ptr elm_ast = this->newEmptyInstance(); for (auto& token : fork.tokens_list) elm_ast->addToken(token); for (auto& child : fork.mbrs_list) elm_ast->addChild(child); value.mbrs_list << elm_ast; value.next = fork.next; return QList{ value }; } case ErrDeals::Surplus: case ErrDeals::Absence: case ErrDeals::Replace: { ParseFork value(context); value.error_messages << fork.error_messages; shared_ptr elm_ast = this->newEmptyInstance(); for (auto& token : fork.tokens_list) elm_ast->addToken(token); for (auto& child : fork.mbrs_list) elm_ast->addChild(child); value.mbrs_list << elm_ast; value.next = fork.next; temp_returns << value; } break; default: break; } } // 修正后的完整匹配结果 if (temp_returns.size()) return temp_returns; return result_forks; } QString ExprRule::token_present() const { return child_store->token_present(); } ParseFork::ParseFork() : occurs(ErrDeals::None) {} ParseFork::ParseFork(const ParseFork& other) : occurs(other.occurs), error_messages(other.error_messages), mbrs_list(other.mbrs_list), tokens_list(other.tokens_list), next(other.next) {}