#pragma once #include "ast_gen.h" namespace example_novel { enum class NovelNode { GlobalElement = 0, TextSection = 1, PointRefers = 2, PointDefines = 3, StoryDefine = 4, Document = 5, ArticleDefine = 6, VolumeDefine = 7, RankDeclaration = 8, FragmentSlice = 9, }; class LIBSYNTAX_EXPORT AbstractImpl : public ast_basic::ExprElement, public ast_gen::SyntaxElement { private: std::weak_ptr parent_store; public: explicit AbstractImpl(std::shared_ptr rule_bind); // 通过 SyntaxElement 继承 virtual std::shared_ptr bindExpression() const override; QString path() const override; virtual std::shared_ptr parent() const override; virtual void setParent(std::shared_ptr inst) override; virtual QList> selfTokens() const override; }; class LIBSYNTAX_EXPORT TextSection : public AbstractImpl { public: TextSection(std::shared_ptr rule_bind); QString content() const; // SyntaxElement interface public: virtual int typeMark() const override; virtual bool isAnonymous() const override; virtual QString signature() const override; }; class LIBSYNTAX_EXPORT PointRefers : public AbstractImpl { public: PointRefers(std::shared_ptr rule_bind); QString storyRefer() const; void setStoryRefer(const QString& refer); QString fragmentRefer() const; void setFragmentRefer(const QString& refer); QString referSignature() const; // SyntaxElement interface public: virtual int typeMark() const override; virtual bool isAnonymous() const override; virtual QString signature() const override; private: QString story_refs, fragment_ref; }; class LIBSYNTAX_EXPORT PointDefines : public AbstractImpl { public: PointDefines(std::shared_ptr rule_bind); QString name() const; void setName(const QString& nm); // SyntaxElement interface public: virtual int typeMark() const override; virtual bool isAnonymous() const override; virtual QString signature() const override; private: QString name_store; }; class LIBSYNTAX_EXPORT ArticleDefine : public AbstractImpl { public: ArticleDefine(std::shared_ptr rule_bind); QString name() const; void setName(const QString& nm); // SyntaxElement interface public: virtual int typeMark() const override; virtual bool isAnonymous() const override; virtual QString signature() const override; private: QString name_store; }; class LIBSYNTAX_EXPORT VolumeDefine : public AbstractImpl { public: VolumeDefine(std::shared_ptr rule_bind); QString name() const; void setName(const QString& nm); // SyntaxElement interface public: virtual int typeMark() const override; virtual bool isAnonymous() const override; virtual QString signature() const override; private: QString name_store; }; class LIBSYNTAX_EXPORT StoryDefine : public AbstractImpl { public: StoryDefine(std::shared_ptr rule_bind); QString name() const; void setName(const QString& nm); void setSort(int value); int sort() const; // SyntaxElement interface public: virtual int typeMark() const override; virtual bool isAnonymous() const override; virtual QString signature() const override; private: QString name_store; int sort_index; }; class LIBSYNTAX_EXPORT Document : public AbstractImpl { public: Document(std::shared_ptr rule_bind); // SyntaxElement interface public: virtual int typeMark() const override; virtual bool isAnonymous() const override; virtual QString signature() const override; }; class LIBSYNTAX_EXPORT RankDeclare : public AbstractImpl { private: int page_rank = 0; public: RankDeclare(std::shared_ptr rule); int rankNumber() const; void setRank(int nums); // 通过 AbstractImpl 继承 int typeMark() const override; bool isAnonymous() const override; QString signature() const override; }; } namespace lib_syntax { template<> class ElementRule : public ExprRule { public: ElementRule(const QString& rule_name, int expr_mark) :ExprRule(rule_name, expr_mark) { } // 通过 ExprRule 继承 virtual std::shared_ptr newEmptyInstance() const { return std::dynamic_pointer_cast( std::make_shared(this->shared_from_this())); } virtual std::shared_ptr makeCopy() const { return std::make_shared>(name(), typeMark()); } virtual std::tuple> parse(std::shared_ptr rt_inst, std::shared_ptr head) const override { std::shared_ptr elm_ast = this->newEmptyInstance(); auto text_present = this->token_present(); rt_inst->pushExprRule(this->shared_from_this()); rt_inst->pushExprInst(elm_ast); auto rstg = child_store->parse(rt_inst, head); auto tokens_decl = elm_ast->tokens(); switch (std::get<0>(rstg)) { case IBasicRule::MatchResult::Fail: case IBasicRule::MatchResult::Part: rt_inst->popExprInst(); rt_inst->popExprRule(); break; case IBasicRule::MatchResult::Success: { if (!std::dynamic_pointer_cast(elm_ast)) { auto start_pos = tokens_decl.first()->position(); rt_inst->clearErrors(rt_inst->currentFile(), start_pos); } rt_inst->popExprInst(); rt_inst->popExprRule(); while (tokens_decl.size()) { auto text_paragraph = this->newEmptyInstance(); int row_n = tokens_decl.first()->row(); for (int idx = 0; idx < tokens_decl.size(); ++idx) { auto target_token = tokens_decl.at(idx); if (target_token->row() == row_n) { text_paragraph->addToken(target_token); tokens_decl.removeAt(idx--); } } if (rt_inst->currentExprInst()) { rt_inst->currentExprInst()->addChild(text_paragraph); } else { rt_inst->appendDocInst(text_paragraph); } } }break; default: break; } return rstg; } }; }