From 7a07e0b2661eb655eab9dcc29c4b266c8db71919 Mon Sep 17 00:00:00 2001 From: codeboss <2422523675@qq.com> Date: Fri, 12 Jul 2024 17:35:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=80=E6=96=B0=E6=94=B9=E8=BF=9B=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86=E9=94=99=E8=AF=AF=E8=AF=86=E5=88=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- WsNovelParser/main.cpp | 8 +++ libSyntax/ast_basic.cpp | 10 ++-- libSyntax/ast_basic.h | 6 +-- libSyntax/libsyntax.cpp | 28 +++++----- libSyntax/libsyntax.h | 7 ++- libSyntax/syntax_novel.cpp | 106 +++++++++++++++---------------------- libToken/libtoken.cpp | 2 +- libToken/tokens_novel.cpp | 9 ---- libToken/tokens_novel.h | 7 --- 9 files changed, 79 insertions(+), 104 deletions(-) diff --git a/WsNovelParser/main.cpp b/WsNovelParser/main.cpp index ef16d31..2c58156 100644 --- a/WsNovelParser/main.cpp +++ b/WsNovelParser/main.cpp @@ -70,6 +70,14 @@ int main(int argc, char* argv[]) { try { auto parser = std::make_shared(); access_ptr = parser->parse(files); + + auto errors_list = std::dynamic_pointer_cast(access_ptr->element())->errors(); + if (errors_list.size()) { + for (auto& err : errors_list) { + qDebug().noquote() << err; + } + exit(0); + } } catch (lib_syntax::SyntaxException* e) { qDebug().noquote() << e->message(); diff --git a/libSyntax/ast_basic.cpp b/libSyntax/ast_basic.cpp index c40b209..5c5a62b 100644 --- a/libSyntax/ast_basic.cpp +++ b/libSyntax/ast_basic.cpp @@ -80,22 +80,22 @@ std::shared_ptr ExpressionContext::popExpressionRule() return rule_stack.takeLast(); } -void ExpressionContext::appendParseErrors(int start, const QString& e) { - this->errors_storage.append(std::make_tuple(start, e)); +void ExpressionContext::appendParseErrors(const QString& file_path, int start, const QString& e) { + this->errors_storage.append(std::make_tuple(file_path, start, e)); } QStringList ExpressionContext::errors() const { QStringList values; for (auto& tp : this->errors_storage) - values.append(std::get<1>(tp)); + values.append(QString(u8"%2\n\t文件(%1)").arg(std::get<0>(tp)).arg(std::get<2>(tp))); return values; } -void ExpressionContext::clearErrors(int start) { +void ExpressionContext::clearErrors(const QString &file_path, int start) { for (int idx = 0; idx < this->errors_storage.size(); ++idx) { auto &tp = errors_storage[idx]; - if(std::get<0>(tp) >= start) + if(std::get<0>(tp) == file_path && std::get<1>(tp) >= start) errors_storage.removeAt(idx--); } } diff --git a/libSyntax/ast_basic.h b/libSyntax/ast_basic.h index 12a3a9a..ffd5b33 100644 --- a/libSyntax/ast_basic.h +++ b/libSyntax/ast_basic.h @@ -90,7 +90,7 @@ namespace ast_basic { QList> expression_stack; QList> document_store; QString current_file_path; - QList> errors_storage; + QList> errors_storage; public: ExpressionContext(); @@ -111,8 +111,8 @@ namespace ast_basic { virtual void appendDoc(std::shared_ptr inst) override; virtual QList> getDocs() const override; - void appendParseErrors(int start, const QString& error_msg) override; + void appendParseErrors(const QString& file_path, int start, const QString& error_msg) override; QStringList errors() const override; - void clearErrors(int start) override; + void clearErrors(const QString& file_path, int start) override; }; } \ No newline at end of file diff --git a/libSyntax/libsyntax.cpp b/libSyntax/libsyntax.cpp index cc4c0a9..2a06257 100644 --- a/libSyntax/libsyntax.cpp +++ b/libSyntax/libsyntax.cpp @@ -13,7 +13,7 @@ QList> TokenMatch::children() const { return QLi std::tuple> TokenMatch::parse(std::shared_ptr rt_inst, std::shared_ptr head) const { if (!head) { - rt_inst->appendParseErrors(-1, QString(u8"Syntax[0x0000]token流(%1)提前终止").arg(rt_inst->currentFile())); + rt_inst->appendParseErrors(rt_inst->currentFile(), - 1, QString(u8"Syntax[0x0000]token流(%1)提前终止").arg(rt_inst->currentFile())); return std::make_tuple(BaseRule::MatchResult::Fail, head); } @@ -22,9 +22,9 @@ std::tuple> TokenMatch:: rt_inst->currentInst()->addToken(std::get<0>(match_result)); } else { - rt_inst->appendParseErrors(head->position(), + rt_inst->appendParseErrors(rt_inst->currentFile(), head->position(), QString(u8"Syntax[0x00001]语法匹配错误,不能识别token:%1<%2,%3>(%4)") - .arg(head->content()).arg(head->row()).arg(head->column()).arg(head->file())); + .arg(head->content()).arg(head->row()).arg(head->column()).arg(head->file())); return std::make_tuple(BaseRule::MatchResult::Part, head); } @@ -136,7 +136,7 @@ public: } }; std::tuple> Any::parse(std::shared_ptr rt_inst, std::shared_ptr head) const { - std::tuple, int> temp_result = std::make_tuple(nullptr, -1); + std::tuple, uint64_t> temp_result = std::make_tuple(nullptr, 0); auto rule_present = this->token_present(); for (auto& fork : mbrs_store) { @@ -151,7 +151,7 @@ std::tuple> Any::parse(s }break; case BaseRule::MatchResult::Part: { auto span = std::get<1>(gen)->position() - head->position(); - if (span > std::get<1>(temp_result)) + if (span >= std::get<1>(temp_result)) temp_result = std::make_tuple(fork, span); } default: @@ -160,7 +160,7 @@ std::tuple> Any::parse(s } // 分析最匹配的分支 - rt_inst->clearErrors(head->position()); + rt_inst->clearErrors(rt_inst->currentFile(), head->position()); auto temp = std::get<0>(temp_result)->parse(rt_inst, head); return std::make_tuple(BaseRule::MatchResult::Part, std::get<1>(temp)); } @@ -180,14 +180,12 @@ SyntaxException::SyntaxException(const QString& message) { this->msg_store = mes QString SyntaxException::message() const { return msg_store; } ExprRule::ExprRule(const QString& rule_name, int expr_mark) : name_store(rule_name) { - this->filter_proc = [](const TokenSeqs& seqs) { return seqs; }; this->mark_store = expr_mark; } -std::shared_ptr ExprRule::reloadRule(std::function filter, std::shared_ptr rule) { +std::shared_ptr ExprRule::reloadRule(std::shared_ptr rule) { auto ninst = makeCopy(); ninst->child_store = rule; - ninst->filter_proc = filter; return ninst; } @@ -199,6 +197,7 @@ QList> ExprRule::children() const { return QList>() << this->child_store; } +#include std::tuple> ExprRule::parse(std::shared_ptr rt_inst, std::shared_ptr head) const { std::shared_ptr elm_ast = this->newEmptyInstance(); @@ -208,8 +207,7 @@ ExprRule::parse(std::shared_ptr rt_inst, std::shared_ptrpushInst(elm_ast); auto rstg = child_store->parse(rt_inst, head); - auto tokens_decl = this->filter_proc(elm_ast->tokens()); - elm_ast->tokensReset(tokens_decl); + auto tokens_decl = elm_ast->tokens(); switch (std::get<0>(rstg)) { case BaseRule::MatchResult::Fail: @@ -218,7 +216,11 @@ ExprRule::parse(std::shared_ptr rt_inst, std::shared_ptrpopExpressionRule(); break; case BaseRule::MatchResult::Success: { - rt_inst->clearErrors(tokens_decl.first()->position()); + if (!std::dynamic_pointer_cast(elm_ast)) { + auto start_pos = tokens_decl.first()->position(); + rt_inst->clearErrors(rt_inst->currentFile(), start_pos); + } + rt_inst->popInst(); rt_inst->popExpressionRule(); @@ -237,5 +239,5 @@ ExprRule::parse(std::shared_ptr rt_inst, std::shared_ptrtoken_present()); + return child_store->token_present(); } diff --git a/libSyntax/libsyntax.h b/libSyntax/libsyntax.h index 600528b..f9bd378 100644 --- a/libSyntax/libsyntax.h +++ b/libSyntax/libsyntax.h @@ -38,9 +38,9 @@ namespace lib_syntax { virtual void setCurrentFile(const QString &path) = 0; virtual QString currentFile() const = 0; - virtual void appendParseErrors(int start, const QString &error_msg) = 0; + virtual void appendParseErrors(const QString & file_path, int start, const QString &error_msg) = 0; virtual QStringList errors() const = 0; - virtual void clearErrors(int start) = 0; + virtual void clearErrors(const QString &file_path, int start) = 0; virtual void appendDoc(std::shared_ptr inst) = 0; virtual QList> getDocs() const = 0; @@ -183,7 +183,7 @@ namespace lib_syntax { typedef QList> TokenSeqs; ExprRule(const QString& rule_name, int expr_mark); - virtual std::shared_ptr reloadRule(std::function filter, std::shared_ptr rule); + virtual std::shared_ptr reloadRule(std::shared_ptr rule); virtual QString name() const; virtual int typeMark() const; @@ -198,7 +198,6 @@ namespace lib_syntax { virtual QString token_present() const override; private: - std::function filter_proc; std::shared_ptr child_store; QString name_store; int mark_store; diff --git a/libSyntax/syntax_novel.cpp b/libSyntax/syntax_novel.cpp index e8940a4..90d13ee 100644 --- a/libSyntax/syntax_novel.cpp +++ b/libSyntax/syntax_novel.cpp @@ -23,9 +23,6 @@ auto split_mark = std::make_shared(); // auto vtext = std::make_shared(); // ^([^\\{\\}\\n@&]+) auto name_text = std::make_shared(); // ^([^:\\{\\}\\n@&][^\\{\\}\\n@&]*) -auto newl = std::make_shared(); - - // rule-parts =============================================================================== @@ -40,74 +37,59 @@ auto newl = std::make_shared(); #define MultiR(rule) std::make_shared(rule, 1, INT_MAX) -QList> LinesMerge(const QList>& mbrs) { - QList> values_ret; - for (auto& item : mbrs) { - values_ret << item << OptMulT(newl); - } - return values_ret; -} -QList> LinesMerge(std::shared_ptr item) { - return QList>() << item << OptMulT(newl); -} - -// remove-return -auto remove_nl = [](const ExprRule::TokenSeqs& p)->ExprRule::TokenSeqs { - ExprRule::TokenSeqs result; - for (auto& n : p) { - if (n->define()->typeMark() == newl->typeMark()) - continue; - result.append(n); - } - return result; -}; auto decl_comp = std::make_shared(Rules{ MR(numbers), MR(vtext), MR(name_text), MR(split_mark) }); -auto decl_expr = ElementRule(u8"decl_section", (int)NovelExprs::DESC_SECTION).reloadRule(remove_nl, - std::make_shared(LinesMerge(MultiR(decl_comp)) +auto decl_expr = ElementRule(u8"decl_section", (int)NovelExprs::DESC_SECTION).reloadRule( + MultiR(decl_comp)); + +auto fragment_decl = ElementRule(u8"fragment_define", (int)NovelExprs::FRAG_DEFINES).reloadRule( + std::make_shared( + Rules{ MR(leftb), MR(frag_key), MR(name_text) } << + OptMulR(decl_expr) << + MR(rightb) )); -auto fragment_decl = ElementRule(u8"fragment_define", (int)NovelExprs::FRAG_DEFINES).reloadRule(remove_nl, std::make_shared( - LinesMerge(Rules{ MR(leftb), MR(frag_key), MR(name_text) }) << - OptMulR(decl_expr) << - LinesMerge(MR(rightb)) -)); - -auto fragment_refer = ElementRule(u8"fragment_refer", (int)NovelExprs::FRAG_REFERS).reloadRule(remove_nl, std::make_shared( - LinesMerge(Rules{ MR(leftb), MR(refers), MR(frag_key), MR(name_text), MR(split_mark), MR(name_text) }) << - OptMulR(decl_expr) << - LinesMerge(MR(rightb)) -)); +auto fragment_refer = ElementRule(u8"fragment_refer", (int)NovelExprs::FRAG_REFERS).reloadRule( + std::make_shared( + Rules{ MR(leftb), MR(refers), MR(frag_key), MR(name_text), MR(split_mark), MR(name_text) } << + OptMulR(decl_expr) << + MR(rightb) + )); auto fragment_comp = std::make_shared(Rules{ fragment_decl, fragment_refer, decl_expr }); -auto story_define = ElementRule(u8"story_define", (int)NovelExprs::STORY_DEFINES).reloadRule(remove_nl, std::make_shared( - LinesMerge(Rules{ MR(leftb), MR(story_key), MR(name_text) }) << - OptMulR(fragment_comp) << - LinesMerge(MR(rightb)) -)); +auto story_define = ElementRule(u8"story_define", (int)NovelExprs::STORY_DEFINES).reloadRule( + std::make_shared( + Rules{ MR(leftb), MR(story_key), MR(name_text) } << + OptMulR(fragment_comp) << + MR(rightb) + )); // =================================================================== -auto article_decl = ElementRule(u8"article_define", (int)NovelExprs::ARTICLE_DEFINE).reloadRule(remove_nl, std::make_shared( - LinesMerge(Rules{ MR(leftb), MR(article_key), MR(name_text) }) << - OptMulR(std::make_shared(Rules{ fragment_refer, decl_expr })) << - LinesMerge(MR(rightb)) -)); +auto article_decl = ElementRule(u8"article_define", (int)NovelExprs::ARTICLE_DEFINE).reloadRule( + std::make_shared( + Rules{ MR(leftb), MR(article_key), MR(name_text) } << + OptMulR(std::make_shared(Rules{ fragment_refer, decl_expr })) << + MR(rightb) + )); -auto volume_decl = ElementRule(u8"volume_define", (int)NovelExprs::VOLUME_DEFINE).reloadRule(remove_nl, std::make_shared( - LinesMerge(Rules{ MR(leftb), MR(volume_key), MR(name_text) }) << - OptMulR(std::make_shared(Rules{ decl_expr, article_decl })) << - LinesMerge(MR(rightb)) -)); +auto volume_decl = ElementRule(u8"volume_define", (int)NovelExprs::VOLUME_DEFINE).reloadRule( + std::make_shared( + Rules{ MR(leftb), MR(volume_key), MR(name_text) } << + OptMulR(std::make_shared(Rules{ decl_expr, article_decl })) << + MR(rightb) + )); -auto rank_define = ElementRule(u8"rank_define", (int)NovelNode::RankDeclaration).reloadRule(remove_nl, std::make_shared( - Rules{ MR(declare), MR(rank_key), MR(numbers), OptMulT(newl)} -)); +auto rank_define = ElementRule(u8"rank_define", (int)NovelNode::RankDeclaration).reloadRule( + std::make_shared( + Rules{ MR(declare), MR(rank_key), MR(numbers) } + )); -auto document_define = ElementRule(u8"decls-doc", (int)NovelExprs::DOC_DEFINES).reloadRule(remove_nl, std::make_shared( - Rules{ - std::make_shared(rank_define, 0, 1), - MultiR(std::make_shared(Rules{story_define, volume_decl})) - } -)); +auto document_define = ElementRule(u8"decls-doc", (int)NovelExprs::DOC_DEFINES).reloadRule( + std::make_shared( + Rules{ + std::make_shared(rank_define, 0, 1), + MultiR(std::make_shared(Rules{story_define, volume_decl})) + } + )); std::shared_ptr NovalSyntax::getParseTree() { return document_define; } std::shared_ptr NovalSyntax::tidy(std::shared_ptr root, QList> children) @@ -136,7 +118,7 @@ void NovalSyntax::node_register(std::shared_ptr ro for (auto& child : children) { if (!child->isAnonymous()) { auto check_result = ast_gen::GlobalElement::UniquePtr->appendToCache(child); - if(check_result) + if (check_result) throw new lib_syntax::SyntaxException(QString(u8"SyntaxError[0x0004]系统中包含同类型重名命名节点:%1(%3,%4)") .arg(child->signature()).arg(child->typeMark()).arg(child->path()).arg(check_result->path())); } diff --git a/libToken/libtoken.cpp b/libToken/libtoken.cpp index 403e878..82dfd9b 100644 --- a/libToken/libtoken.cpp +++ b/libToken/libtoken.cpp @@ -32,7 +32,7 @@ QList> WordReader::extract_from(const QString& while (!tin.atEnd()) { uint64_t relative_offset = line_number; relative_offset = relative_offset << 32; - auto line = tin.readLine() + "\n"; + auto line = tin.readLine(); ret_list.append(this->parse_line(relative_offset, line_number++, line, path)); } diff --git a/libToken/tokens_novel.cpp b/libToken/tokens_novel.cpp index 781f86c..d2cd944 100644 --- a/libToken/tokens_novel.cpp +++ b/libToken/tokens_novel.cpp @@ -93,15 +93,6 @@ Keywords::analysis(std::shared_ptr content) const { return std::make_tuple(token_inst, nullptr); } -QString NewLine::typeName() const { return u8"new-line"; } - -int NewLine::typeMark() const -{ - return 0x04000000; -} - -QString NewLine::regex() const { return u8"\n"; } - QString Numbers::typeName() const { return u8"numbers"; } int Numbers::typeMark() const diff --git a/libToken/tokens_novel.h b/libToken/tokens_novel.h index d00c04f..0d9bd13 100644 --- a/libToken/tokens_novel.h +++ b/libToken/tokens_novel.h @@ -60,13 +60,6 @@ namespace example_novel { virtual QString regex() const override; }; - class LIBTOKEN_EXPORT NewLine : public LeftBracket { - public: - virtual QString typeName() const override; - virtual int typeMark() const override; - virtual QString regex() const override; - }; - class LIBTOKEN_EXPORT Split : public LeftBracket { public: virtual QString typeName() const override;