From eb20475b2636941e3b3bb87ad11a675df0b7ced3 Mon Sep 17 00:00:00 2001 From: codeboss <2422523675@qq.com> Date: Fri, 7 Feb 2025 23:26:20 +0800 Subject: [PATCH] halfs --- libSyntax/ast_access.cpp | 98 ++++++++ libSyntax/ast_access.h | 136 +++++++++++ libSyntax/ast_basic.cpp | 31 ++- libSyntax/ast_basic.h | 152 +++++++------ libSyntax/ast_gen.cpp | 94 +++----- libSyntax/ast_gen.h | 148 ++---------- libSyntax/ast_novel.cpp | 247 +++++++++----------- libSyntax/ast_novel.h | 250 ++++++++++---------- libSyntax/libSyntax.vcxproj | 3 + libSyntax/libSyntax.vcxproj.filters | 9 + libSyntax/libsyntax.cpp | 338 +++++++++++++--------------- libSyntax/libsyntax.h | 294 +++++++++++++----------- libSyntax/libtokens.cpp | 33 ++- libSyntax/libtokens.h | 79 +++---- libSyntax/syntax_novel.cpp | 194 +++++++++------- libSyntax/syntax_novel.h | 39 +--- libSyntax/tokens_impl.h | 185 +++++++++++++++ libSyntax/tokens_novel.cpp | 23 +- 18 files changed, 1317 insertions(+), 1036 deletions(-) create mode 100644 libSyntax/ast_access.cpp create mode 100644 libSyntax/ast_access.h create mode 100644 libSyntax/tokens_impl.h diff --git a/libSyntax/ast_access.cpp b/libSyntax/ast_access.cpp new file mode 100644 index 0000000..e607483 --- /dev/null +++ b/libSyntax/ast_access.cpp @@ -0,0 +1,98 @@ +#include "ast_access.h" + +using namespace ast_gen; +using namespace ast_basic; + + +GlobalElement* GlobalElement::UniquePtr = nullptr; + +GlobalElement::GlobalElement(const QString& name) :names_store(name) { + UniquePtr = this; +} + +void GlobalElement::clearCache() { + node_cache.clear(); +} + +std::shared_ptr GlobalElement::appendToCache(std::shared_ptr named_node) { + auto mixed_key = QString(u8"%1<%2>").arg(named_node->signature()).arg(named_node->typeMark()); + if (node_cache.contains(mixed_key)) + return node_cache[mixed_key]; + node_cache[mixed_key] = named_node; + return nullptr; +} + +std::shared_ptr GlobalElement::getNamedNodeBy(int paramType, const QString& signature) const { + auto mixed_key = QString(u8"%1<%2>").arg(signature).arg(paramType); + if (!node_cache.contains(mixed_key)) + return nullptr; + return node_cache[mixed_key]; +} + +int GlobalElement::typeMark() const { + return 0; +} + +bool GlobalElement::isAnonymous() const { + return true; +} + +QString GlobalElement::signature() const { + return u8"::global"; +} + +QString GlobalElement::path() const { + return u8""; +} + +std::weak_ptr GlobalElement::parent() const { + return std::weak_ptr(); +} + +void GlobalElement::setParent(std::shared_ptr inst) { } + +QList> GlobalElement::selfTokens() const { + return QList>(); +} + +std::shared_ptr GlobalElement::bindExpression() const { + return nullptr; +} + +void GlobalElement::addChild(std::shared_ptr citem) { +} + +ElementAccess::ElementAccess(std::shared_ptr point) { + peers = point; +} + +std::shared_ptr ElementAccess::element() const { + return peers; +} + +QList> ElementAccess::children() const { + auto expression_inst = element()->bindExpression(); + auto children = expression_inst->children(); + + QList> retvalues; + for (auto item : children) { + auto elem_inst = std::dynamic_pointer_cast(item); + retvalues.append(std::make_shared(elem_inst)); + } + return retvalues; +} + +QList> ElementAccess::tokens() const { + return element()->selfTokens(); +} + +TokenAccess::TokenAccess(std::shared_ptr elm_inst, std::shared_ptr token_inst) + : element_bind(elm_inst), token_store(token_inst) { } + +std::shared_ptr TokenAccess::bind() const { + return element_bind; +} + +std::shared_ptr TokenAccess::token() const { + return token_store; +} diff --git a/libSyntax/ast_access.h b/libSyntax/ast_access.h new file mode 100644 index 0000000..496c1d0 --- /dev/null +++ b/libSyntax/ast_access.h @@ -0,0 +1,136 @@ +#pragma once + +#include +#include +#include +#include "ast_basic.h" + + +namespace ast_gen { + class TokenAccess; + + /** + * @brief 解析上下文 + */ + class SyntaxElement { + public: + virtual ~SyntaxElement() = default; + /** + * 绑定表达式实体. + * + * \return 表达式实例 + */ + virtual std::shared_ptr bindExpression() const = 0; + + /** + * @brief 类型标记 + * @return + */ + virtual int typeMark() const = 0; + + /** + * 是否属于匿名节点. + * + * \return 匿名标志 + */ + virtual bool isAnonymous() const = 0; + + /** + * @brief 文件路径 + * @return + */ + virtual QString path() const = 0; + + /** + * @brief 元素签名,如果是匿名元素返回空字符串 + * @return + */ + virtual QString signature() const = 0; + + /** + * @brief 获取父元素 + * @return 未设置parent,返回nullptr + */ + virtual std::weak_ptr parent() const = 0; + /** + * @brief 重置父指针. + * + * \param inst + */ + virtual void setParent(std::shared_ptr inst) = 0; + + /** + * @brief 定义元素自身的Token集合 + * @return + */ + virtual QList> selfTokens() const = 0; + }; + + /** + * @brief 语法元素整理访问接口 + */ + class LIBSYNTAX_EXPORT ElementAccess { + private: + std::shared_ptr peers; + + public: + ElementAccess(std::shared_ptr point); + + std::shared_ptr element() const; + QList> children() const; + + /** + * @brief 获取该元素下所有Token定义 + * @return + */ + virtual QList> tokens() const; + }; + + class LIBSYNTAX_EXPORT TokenAccess { + private: + std::shared_ptr element_bind; + std::shared_ptr token_store; + + public: + TokenAccess(std::shared_ptr elm_inst, std::shared_ptr token_inst); + virtual std::shared_ptr bind() const; + virtual std::shared_ptr token() const; + }; + + /** + * @brief 根元素定义 + */ + class LIBSYNTAX_EXPORT GlobalElement : public SyntaxElement { + private: + QString names_store; + QHash> node_cache; + + public: + static GlobalElement* UniquePtr; + GlobalElement(const QString& name); + + virtual void clearCache(); + virtual std::shared_ptr appendToCache(std::shared_ptr named_node); + /** + * @brief 通过节点签名获取定义节点 + * @param signature 完全签名 + * @return + * @throws 没有指定节点抛出异常 + */ + virtual std::shared_ptr getNamedNodeBy(int paramType, const QString& signature) const; + virtual void addChild(std::shared_ptr citem); + + // ParseElement interface + public: + virtual int typeMark() const override; + virtual bool isAnonymous() const override; + virtual QString signature() const override; + virtual QString path() const override; + virtual std::weak_ptr parent() const override; + virtual void setParent(std::shared_ptr inst) override; + virtual QList> selfTokens() const override; + + // 通过 SyntaxElement 继承 + virtual std::shared_ptr bindExpression() const override; + }; +} \ No newline at end of file diff --git a/libSyntax/ast_basic.cpp b/libSyntax/ast_basic.cpp index 3e061a9..10fd45f 100644 --- a/libSyntax/ast_basic.cpp +++ b/libSyntax/ast_basic.cpp @@ -1,11 +1,12 @@ #include "ast_basic.h" +#include "libsyntax.h" #include using namespace ast_basic; using namespace lib_token; using namespace lib_syntax; -ExprInstance::ExprInstance(std::shared_ptr bind) : _expr_rule(bind) {} +ExprInstance::ExprInstance(std::shared_ptr bind) : _expr_rule(bind) { } std::shared_ptr ExprInstance::definedRule() const { return _expr_rule; @@ -22,14 +23,38 @@ void ExprInstance::addToken(std::shared_ptr token_inst) { this->tokens_bind.append(token_inst); } -QList> ExprInstance::children() const { +QList> ExprInstance::children() const { return this->children_store; } -void ExprInstance::addChild(std::shared_ptr inst) { +void ExprInstance::addChild(std::shared_ptr inst) { this->children_store.append(inst); } QList> ExprInstance::tokens() const { return this->tokens_bind; } + +ExprProgram::ExprProgram(const QString& root) : _program_root(root) { } + +std::shared_ptr ExprProgram::definedRule() const { + return std::shared_ptr(); +} + +QString ExprProgram::filePath() const { + return this->_program_root; +} + +QList> ExprProgram::tokens() const { + return QList>(); +} + +void ExprProgram::addToken(std::shared_ptr token_inst) { } + +QList> ExprProgram::children() const { + return _children_store; +} + +void ExprProgram::addChild(std::shared_ptr inst) { + _children_store.append(inst); +} diff --git a/libSyntax/ast_basic.h b/libSyntax/ast_basic.h index f2cf30c..b5d1ef8 100644 --- a/libSyntax/ast_basic.h +++ b/libSyntax/ast_basic.h @@ -3,77 +3,99 @@ #include #include #include "libtokens.h" -#include "libsyntax.h" + +namespace lib_syntax { + class ExprRule; +} + +// 抽象语法树结构 ==================================================================== namespace ast_basic { - // 抽象语法树 ================================================================================================ - /** - * @brief 抽象语法树集合节点/表达式节点 - */ - class IExprInst { - public: - virtual ~IExprInst() = default; - - /** - * @brief 获取表达式的解析规则 - * @return - */ - virtual std::shared_ptr definedRule() const = 0; - //===================================================== - /** - * 获取语法节点的源码文件路径. - * - * \return 文件路径 - */ - virtual QString filePath() const = 0; - /** - * 获取语法节点关联token序列. - * - * \return token序列 - */ - virtual QList> tokens() const = 0; - /** - * 解析过程中,向表达式内部添加token实例. - * - * \param token_inst 实例 - */ - virtual void addToken(std::shared_ptr token_inst) = 0; - //===================================================== - /** - * @brief 子表达式集合 - * @return - */ - virtual QList> children() const = 0; - /** - * @brief 添加子表达式. - * - * \param inst 子表达式实例 - */ - virtual void addChild(std::shared_ptr inst) = 0; - }; + /** + * @brief 抽象语法树集合节点/表达式节点 + */ + class IExprInstance { + public: + /** + * @brief 获取表达式的解析规则 + * @return + */ + virtual std::shared_ptr definedRule() const = 0; + //===================================================== + /** + * 获取语法节点的源码文件路径. + * + * \return 文件路径 + */ + virtual QString filePath() const = 0; + /** + * 获取语法节点关联token序列. + * + * \return token序列 + */ + virtual QList> tokens() const = 0; + /** + * 解析过程中,向表达式内部添加token实例. + * + * \param token_inst 实例 + */ + virtual void addToken(std::shared_ptr token_inst) = 0; + //===================================================== + /** + * @brief 子表达式集合 + * @return + */ + virtual QList> children() const = 0; + /** + * @brief 添加子表达式. + * + * \param inst 子表达式实例 + */ + virtual void addChild(std::shared_ptr inst) = 0; + }; - // 基础语法树构成 ========================================================================================== - /** - * @brief 表达式节点 - */ - class LIBSYNTAX_EXPORT ExprInstance : public ast_basic::IExprInst, public std::enable_shared_from_this { - private: - std::shared_ptr _expr_rule; - QList> children_store; - QList> tokens_bind; + // 基础语法树构成 ========================================================================================== + /** + * @brief 表达式节点 + */ + class LIBSYNTAX_EXPORT ExprInstance : public IExprInstance, public std::enable_shared_from_this { + private: + std::shared_ptr _expr_rule; + QList> children_store; + QList> tokens_bind; - public: - ExprInstance(std::shared_ptr bind); + public: + ExprInstance(std::shared_ptr bind); - // 通过 Expression 继承 - std::shared_ptr definedRule() const override; - QString filePath() const override; + // 通过 Expression 继承 + std::shared_ptr definedRule() const override; + QString filePath() const override; - QList> tokens() const override; - void addToken(std::shared_ptr token_inst) override; + QList> tokens() const override; + void addToken(std::shared_ptr token_inst) override; - QList> children() const override; - void addChild(std::shared_ptr inst) override; - }; + QList> children() const override; + void addChild(std::shared_ptr inst) override; + }; + + /** + * @brief 表达式树根节点 + */ + class LIBSYNTAX_EXPORT ExprProgram : public IExprInstance, public std::enable_shared_from_this { + private: + QList> _children_store; + QString _program_root; + + public: + ExprProgram(const QString &root); + + // 通过 IExprInstance 继承 + std::shared_ptr definedRule() const override; + QString filePath() const override; + QList> tokens() const override; + void addToken(std::shared_ptr token_inst) override; + QList> children() const override; + void addChild(std::shared_ptr inst) override; + }; } \ No newline at end of file diff --git a/libSyntax/ast_gen.cpp b/libSyntax/ast_gen.cpp index 6176487..b7a2a46 100644 --- a/libSyntax/ast_gen.cpp +++ b/libSyntax/ast_gen.cpp @@ -1,78 +1,36 @@ #include "ast_gen.h" +#include "ast_access.h" using namespace ast_gen; +using namespace ast_basic; +using namespace lib_token; +using namespace lib_syntax; +using namespace lib_words; -GlobalElement* GlobalElement::UniquePtr = nullptr; +SyntaxParser::SyntaxParser(std::shared_ptr rule) + : _rule_bind(rule) { } -GlobalElement::GlobalElement(const QString& name) :names_store(name) { - UniquePtr = this; +QList> SyntaxParser::parse(std::shared_ptr words) { + auto cursor = std::make_shared(); + cursor->setCurrent(nullptr, words); + + auto list = this->_rule_bind->parse(cursor); + std::sort(list.begin(), list.end(), + [&](std::shared_ptr a, std::shared_ptr b) { + return a->totalErrorCount() < b->totalErrorCount(); + }); + + return list; } -void GlobalElement::clearCache() { node_cache.clear(); } +#include "tokens_impl.h" +std::shared_ptr ast_gen::SyntaxParser::getAst( + std::shared_ptr cursor, std::shared_ptr root) { -std::shared_ptr GlobalElement::appendToCache(std::shared_ptr named_node) { - auto mixed_key = QString(u8"%1<%2>").arg(named_node->signature()).arg(named_node->typeMark()); - if (node_cache.contains(mixed_key)) - return node_cache[mixed_key]; - node_cache[mixed_key] = named_node; - return nullptr; -} - -std::shared_ptr GlobalElement::getNamedNodeBy(int paramType, const QString& signature) const { - auto mixed_key = QString(u8"%1<%2>").arg(signature).arg(paramType); - if (!node_cache.contains(mixed_key)) - return nullptr; - return node_cache[mixed_key]; -} - -int GlobalElement::typeMark() const { return 0; } - -bool ast_gen::GlobalElement::isAnonymous() const { return true; } - -QString GlobalElement::signature() const { return u8"::global"; } - -QString GlobalElement::path() const { return u8""; } - -std::shared_ptr GlobalElement::parent() const { return nullptr; } - -void ast_gen::GlobalElement::setParent(std::shared_ptr inst) {} - -QList> GlobalElement::selfTokens() const { return QList>(); } - -std::shared_ptr ast_gen::GlobalElement::bindExpression() const -{ - return bind_exprs; -} - -void GlobalElement::addChild(std::shared_ptr citem) { - auto convx = std::dynamic_pointer_cast(citem); - bind_exprs->addChild(convx); -} - -ElementAccess::ElementAccess(std::shared_ptr point) { peers = point; } - -std::shared_ptr ElementAccess::element() const { return peers; } - -QList> ElementAccess::children() const { - auto expression_inst = element()->bindExpression(); - auto children = expression_inst->children(); - - QList> retvalues; - for (auto item : children) { - auto elem_inst = std::dynamic_pointer_cast(item); - retvalues.append(std::make_shared(elem_inst)); + std::shared_ptr action_token = cursor->currentToken(); + while (action_token->prevToken()) { + action_token = action_token->prevToken(); } - return retvalues; + + return std::const_pointer_cast(action_token)->makeSure(root); } - -QList> ElementAccess::tokens() const { - return element()->selfTokens(); -} - -TokenAccess::TokenAccess(std::shared_ptr elm_inst, std::shared_ptr token_inst) - : element_bind(elm_inst), token_store(token_inst) {} - -std::shared_ptr TokenAccess::bind() const { return element_bind; } - -std::shared_ptr TokenAccess::token() const { return token_store; } - diff --git a/libSyntax/ast_gen.h b/libSyntax/ast_gen.h index 8c963ee..df59712 100644 --- a/libSyntax/ast_gen.h +++ b/libSyntax/ast_gen.h @@ -1,139 +1,39 @@ #pragma once -#include -#include -#include +#include "libsyntax.h" #include "ast_basic.h" -#include "libsyntax_global.h" -namespace ast_gen -{ - class TokenAccess; +namespace ast_gen { + /** - * @brief 解析上下文 - */ - class SyntaxElement { - public: - virtual ~SyntaxElement() = default; - /** - * 绑定表达式实体. - * - * \return 表达式实例 - */ - virtual std::shared_ptr bindExpression() const = 0; - - /** - * @brief 类型标记 - * @return - */ - virtual int typeMark() const = 0; - - /** - * 是否属于匿名节点. - * - * \return 匿名标志 - */ - virtual bool isAnonymous() const = 0; - - /** - * @brief 文件路径 - * @return - */ - virtual QString path() const = 0; - - /** - * @brief 元素签名,如果是匿名元素返回空字符串 - * @return - */ - virtual QString signature() const = 0; - - /** - * @brief 获取父元素 - * @return 未设置parent,返回nullptr - */ - virtual std::shared_ptr parent() const = 0; - /** - * @brief 重置父指针. - * - * \param inst - */ - virtual void setParent(std::shared_ptr inst) = 0; - - /** - * @brief 定义元素自身的Token集合 - * @return - */ - virtual QList> selfTokens() const = 0; - }; - - /** - * @brief 语法元素整理访问接口 - */ - class LIBSYNTAX_EXPORT ElementAccess { + * @brief 语法解析器 + */ + class SyntaxParser { private: - std::shared_ptr peers; + std::shared_ptr _rule_bind = nullptr; public: - ElementAccess(std::shared_ptr point); - - std::shared_ptr element() const; - QList> children() const; + SyntaxParser(std::shared_ptr rule); /** - * @brief 获取该元素下所有Token定义 - * @return - */ - virtual QList> tokens() const; - }; - - class LIBSYNTAX_EXPORT TokenAccess { - private: - std::shared_ptr element_bind; - std::shared_ptr token_store; - - public: - TokenAccess(std::shared_ptr elm_inst, std::shared_ptr token_inst); - virtual std::shared_ptr bind() const; - virtual std::shared_ptr token() const; - }; - - /** - * @brief 根元素定义 - */ - class LIBSYNTAX_EXPORT GlobalElement : public SyntaxElement, public ast_basic::ExprsContext { - private: - QString names_store; - QHash> node_cache; - - std::shared_ptr bind_exprs = std::make_shared(nullptr); - - public: - static GlobalElement* UniquePtr; - GlobalElement(const QString& name); - - virtual void clearCache(); - virtual std::shared_ptr appendToCache(std::shared_ptr named_node); + * @brief 依据源码语法规则,解析源码链表 + * @param wods 源码链表 + * @return 所有解析路径,按照错误数量排序:少->多 + */ + QList> parse(std::shared_ptr words); + /** - * @brief 通过节点签名获取定义节点 - * @param signature 完全签名 - * @return - * @throws 没有指定节点抛出异常 - */ - virtual std::shared_ptr getNamedNodeBy(int paramType, const QString& signature) const; - virtual void addChild(std::shared_ptr citem); + * @brief 依据指定解析路径,提取程序解构 + * @param cursor 解析路径 + * @param root 表达式树预制根节点 + * @return 完善后的根节点 + */ + std::shared_ptr getAst( + std::shared_ptr cursor, std::shared_ptr root); - // ParseElement interface - public: - virtual int typeMark() const override; - virtual bool isAnonymous() const override; - virtual QString signature() const override; - virtual QString path() const override; - virtual std::shared_ptr parent() const override; - virtual void setParent(std::shared_ptr inst) override; - virtual QList> selfTokens() const override; - - // 通过 SyntaxElement 继承 - virtual std::shared_ptr bindExpression() const override; }; + + + } \ No newline at end of file diff --git a/libSyntax/ast_novel.cpp b/libSyntax/ast_novel.cpp index 1965d78..c63d044 100644 --- a/libSyntax/ast_novel.cpp +++ b/libSyntax/ast_novel.cpp @@ -3,12 +3,14 @@ using namespace example_novel; using namespace lib_syntax; +using namespace ast_basic; +using namespace ast_gen; + TextSection::TextSection(std::shared_ptr rule_bind) - : AbstractImpl(rule_bind) {} + : AbstractImpl(rule_bind) { } -QString TextSection::content() const -{ +QString TextSection::content() const { QString text; for (auto& t : selfTokens()) { text += t->token()->content() + " "; @@ -16,27 +18,34 @@ QString TextSection::content() const return text; } -int TextSection::typeMark() const { return (int)NovelNode::TextSection; } - -bool TextSection::isAnonymous() const -{ - return true; +QString TextSection::signature() const { + return u8"::section"; } -QString TextSection::signature() const { return u8"::section"; } - PointRefers::PointRefers(std::shared_ptr rule_bind) - : AbstractImpl(rule_bind) {} + : AbstractImpl(rule_bind) { } -QString PointRefers::storyRefer() const { return story_refs; } +QString PointRefers::storyRefer() const { + return story_refs; +} -void example_novel::PointRefers::setStoryRefer(const QString& refer) { +void PointRefers::setStoryRefer(const QString& refer) { this->story_refs = refer; } -QString PointRefers::pointRefer() const { return point_ref; } +QString PointRefers::sliceRefer() const { + return story_refs; +} -void example_novel::PointRefers::setPointRefer(const QString& refer) { +void PointRefers::setSliceRefer(const QString& refer) { + story_refs = refer; +} + +QString PointRefers::pointRefer() const { + return point_ref; +} + +void PointRefers::setPointRefer(const QString& refer) { this->point_ref = refer; } @@ -44,189 +53,149 @@ QString PointRefers::referSignature() const { return storyRefer() + u8"&" + sliceRefer() + u8"&" + pointRefer(); } -int PointRefers::typeMark() const { return (int)NovelNode::PointRefers; } - -bool PointRefers::isAnonymous() const -{ - return true; -} - QString PointRefers::signature() const { - QString signature = u8"@" + storyRefer() + u8"&" + fragmentRefer(); - return parent()->signature() + signature; + QString signature = u8"@" + referSignature(); + return parent().lock()->signature() + u8"&" + signature; } PointDefines::PointDefines(std::shared_ptr rule_bind) - : AbstractImpl(rule_bind) {} + : AbstractImpl(rule_bind) { } -QString PointDefines::name() const { return name_store; } +QString PointDefines::name() const { + return name_store; +} -void example_novel::PointDefines::setName(const QString& nm) -{ +void PointDefines::setName(const QString& nm) { this->name_store = nm; } -int PointDefines::typeMark() const { return (int)NovelNode::PointDefines; } - -bool PointDefines::isAnonymous() const -{ - return false; +QString PointDefines::signature() const { + return parent().lock()->signature() + u8"&" + name(); } -QString PointDefines::signature() const { return parent()->signature() + u8"&" + name(); } - StoryDefine::StoryDefine(std::shared_ptr rule_bind) - : AbstractImpl(rule_bind), sort_index(0) {} + : AbstractImpl(rule_bind), sort_index(0) { } -QString StoryDefine::name() const { return name_store; } +QString StoryDefine::name() const { + return name_store; +} -void example_novel::StoryDefine::setName(const QString& nm) -{ +void StoryDefine::setName(const QString& nm) { this->name_store = nm; } -void example_novel::StoryDefine::setSort(int value) { +void StoryDefine::setSort(int value) { sort_index = value; } -int StoryDefine::sort() const { return sort_index; } - -int StoryDefine::typeMark() const { return (int)NovelNode::StoryDefine; } - -bool StoryDefine::isAnonymous() const -{ - return false; +int StoryDefine::sort() const { + return sort_index; } -QString StoryDefine::signature() const { return name(); } +QString StoryDefine::signature() const { + return name(); +} #include "syntax_novel.h" Document::Document(std::shared_ptr rule_bind) - : AbstractImpl(rule_bind) {} + : AbstractImpl(rule_bind) { } -int Document::typeMark() const { return (int)NovelNode::Document; } - -bool Document::isAnonymous() const -{ - return true; -} - -QString Document::signature() const { return QString(u8"::document<%1>").arg(path()); } - -AbstractImpl::AbstractImpl(std::shared_ptr rule_bind) - : ExprElement(rule_bind) { - parent_store.reset(); -} - -QList > AbstractImpl::selfTokens() const { - auto tokensx = ast_basic::ExprElement::tokens(); - QList> values; - for (auto xit : tokensx) { - values.append(std::make_shared(std::dynamic_pointer_cast(shared_from_this()), xit)); - } - - return values; -} - -std::shared_ptr AbstractImpl::parent() const -{ - return this->parent_store.lock(); -} - -void AbstractImpl::setParent(std::shared_ptr inst) -{ - this->parent_store = inst; -} - - -// 通过 SyntaxElement 继承 -std::shared_ptr AbstractImpl::bindExpression() const { - return shared_from_this(); -} - -QString AbstractImpl::path() const -{ - return ast_basic::ExprElement::filePath(); +QString Document::signature() const { + return QString(u8"::document<%1>").arg(path()); } VolumeDefine::VolumeDefine(std::shared_ptr rule_bind) - : AbstractImpl(rule_bind) {} + : AbstractImpl(rule_bind) { } -QString VolumeDefine::name() const { return name_store; } +QString VolumeDefine::name() const { + return name_store; +} -void example_novel::VolumeDefine::setName(const QString& nm) -{ +void VolumeDefine::setName(const QString& nm) { this->name_store = nm; } -int VolumeDefine::typeMark() const { return (int)NovelNode::VolumeDefine; } - -bool VolumeDefine::isAnonymous() const -{ - return false; +QString VolumeDefine::signature() const { + return name(); } -QString VolumeDefine::signature() const { return name(); } - ArticleDefine::ArticleDefine(std::shared_ptr rule_bind) - : AbstractImpl(rule_bind) {} + : AbstractImpl(rule_bind) { } -QString ArticleDefine::name() const { return name_store; } +QString ArticleDefine::name() const { + return name_store; +} -void example_novel::ArticleDefine::setName(const QString& nm) -{ +void ArticleDefine::setName(const QString& nm) { this->name_store = nm; } -int ArticleDefine::typeMark() const { return (int)NovelNode::ArticleDefine; } - -bool ArticleDefine::isAnonymous() const -{ - return false; +QString ArticleDefine::signature() const { + return parent().lock()->signature() + u8"&" + name(); } -QString ArticleDefine::signature() const { return parent()->signature() + u8"&" + name(); } - RankDeclare::RankDeclare(std::shared_ptr rule) - : AbstractImpl(rule) -{ -} + : AbstractImpl(rule) { } -int example_novel::RankDeclare::rankNumber() const -{ +int RankDeclare::rankNumber() const { return page_rank; } -void example_novel::RankDeclare::setRank(int nums) -{ +void RankDeclare::setRank(int nums) { this->page_rank = nums; } -int RankDeclare::typeMark() const -{ - return (int)NovelNode::RankDeclaration; -} - -bool RankDeclare::isAnonymous() const -{ - return true; -} - -QString RankDeclare::signature() const -{ +QString RankDeclare::signature() const { return u8"::rank"; } -int example_novel::FragmentSlice::typeMark() const { - return 0; +FragmentSlice::FragmentSlice(std::shared_ptr rule) + :AbstractImpl(rule) { + _slice_name = QString(u8"名称未定义_%1").arg((uint64_t)this); } -bool example_novel::FragmentSlice::isAnonymous() const { - return false; +QString FragmentSlice::name() const { + return _slice_name; } -QString example_novel::FragmentSlice::signature() const { - return QString(); +void FragmentSlice::setName(const QString& nm) { + this->_slice_name = nm; } + +QString FragmentSlice::signature() const { + return parent().lock()->signature() + u8"&" + name(); +} + +std::shared_ptr NGlobalElement::bindExpression() const { + return shared_from_this(); +} + +int NGlobalElement::typeMark() const { + return (int)NovelNode::GlobalElement; +} + +bool NGlobalElement::isAnonymous() const { + return true; +} + +QString NGlobalElement::path() const { + return ExprProgram::filePath(); +} + +QString NGlobalElement::signature() const { + return u8"::program"; +} + +std::weak_ptr NGlobalElement::parent() const { + return std::weak_ptr(); +} + +void NGlobalElement::setParent(std::shared_ptr inst) { } + +QList> NGlobalElement::selfTokens() const { + return QList>(); +} + +NGlobalElement::NGlobalElement(const QString& root): ExprProgram(root) { } diff --git a/libSyntax/ast_novel.h b/libSyntax/ast_novel.h index ca0714e..523404f 100644 --- a/libSyntax/ast_novel.h +++ b/libSyntax/ast_novel.h @@ -1,6 +1,8 @@ #pragma once -#include "ast_gen.h" +#include "ast_access.h" +#include "ast_basic.h" +#include "libsyntax.h" namespace example_novel { enum class NovelNode { @@ -16,44 +18,104 @@ namespace example_novel { FragmentSlice = 9, }; - class LIBSYNTAX_EXPORT AbstractImpl : public ast_basic::ExprElement, public ast_gen::SyntaxElement { + /* + GlobalElement + \-Document + |-RankDeclaration + |-StoryDefine + | |-TextSection + | \-FragmentSlice + | |-TextSection + | |-PointDefines + | | \-TextSection + | \-PointRefers + | \-TextSection + \-VolumeDefine + |-TextSection + \-ArticleDefine + |-TextSection + \-PointRefers + \-TextSection + */ + + template + class AbstractImpl : public ast_basic::ExprInstance, public ast_gen::SyntaxElement { private: std::weak_ptr parent_store; public: - explicit AbstractImpl(std::shared_ptr rule_bind); + AbstractImpl(std::shared_ptr rule_bind) + : ExprInstance(rule_bind) { + parent_store.reset(); + } // 通过 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; + virtual int typeMark() const override { + return (int) type; + } + virtual bool isAnonymous() const override { + return !named; + } + virtual std::shared_ptr bindExpression() const override { + return shared_from_this(); + } + QString path() const override { + return ExprInstance::filePath(); + } + virtual std::weak_ptr parent() const override { + return this->parent_store; + } + virtual void setParent(std::shared_ptr inst) override { + this->parent_store = inst; + } + virtual QList> selfTokens() const override { + auto tokensx = ExprInstance::tokens(); + QList> values; + for (auto xit : tokensx) { + values.append(std::make_shared(std::dynamic_pointer_cast(shared_from_this()), xit)); + } + + return values; + } }; - - class LIBSYNTAX_EXPORT TextSection : public AbstractImpl { + /** + * @brief 文字段落 + */ + class LIBSYNTAX_EXPORT TextSection : public AbstractImpl { public: TextSection(std::shared_ptr rule_bind); + /** + * @brief 段落内容 + */ QString content() const; - // SyntaxElement interface - public: - virtual int typeMark() const override; - virtual bool isAnonymous() const override; + // 通过 AbstractImpl 继承 virtual QString signature() const override; }; - class LIBSYNTAX_EXPORT FragmentSlice : public AbstractImpl { + /** + * @brief 故事情节 + */ + class LIBSYNTAX_EXPORT FragmentSlice : public AbstractImpl { + private: + QString _slice_name; + public: + FragmentSlice(std::shared_ptr rule); + + QString name() const; + void setName(const QString& nm); + // 通过 AbstractImpl 继承 - int typeMark() const override; - bool isAnonymous() const override; QString signature() const override; }; - class LIBSYNTAX_EXPORT PointRefers : public AbstractImpl { + /** + * @brief 节点引用定义 + */ + class LIBSYNTAX_EXPORT PointRefers : public AbstractImpl { private: QString story_refs, slice_ref, point_ref; @@ -71,14 +133,14 @@ namespace example_novel { QString referSignature() const; - // SyntaxElement interface - public: - virtual int typeMark() const override; - virtual bool isAnonymous() const override; + // 通过 AbstractImpl 继承 virtual QString signature() const override; }; - class LIBSYNTAX_EXPORT PointDefines : public AbstractImpl { + /** + * @brief 节点定义 + */ + class LIBSYNTAX_EXPORT PointDefines : public AbstractImpl { private: QString name_store; @@ -88,48 +150,48 @@ namespace example_novel { QString name() const; void setName(const QString& nm); - // SyntaxElement interface - public: - virtual int typeMark() const override; - virtual bool isAnonymous() const override; + // 通过 AbstractImpl 继承 virtual QString signature() const override; }; - class LIBSYNTAX_EXPORT ArticleDefine : public AbstractImpl { + /** + * @brief 章节定义 + */ + 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; + // 通过 AbstractImpl 继承 virtual QString signature() const override; private: QString name_store; }; - class LIBSYNTAX_EXPORT VolumeDefine : public AbstractImpl { + /** + * @brief 卷宗定义 + */ + 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; + // 通过 AbstractImpl 继承 virtual QString signature() const override; private: QString name_store; }; - class LIBSYNTAX_EXPORT StoryDefine : public AbstractImpl { + /** + * @brief 故事定义 + */ + class LIBSYNTAX_EXPORT StoryDefine : public AbstractImpl { public: StoryDefine(std::shared_ptr rule_bind); @@ -139,10 +201,7 @@ namespace example_novel { void setSort(int value); int sort() const; - // SyntaxElement interface - public: - virtual int typeMark() const override; - virtual bool isAnonymous() const override; + // 通过 AbstractImpl 继承 virtual QString signature() const override; private: @@ -150,18 +209,10 @@ namespace example_novel { 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 { + /** + * @brief 排序声明 + */ + class LIBSYNTAX_EXPORT RankDeclare : public AbstractImpl { private: int page_rank = 0; public: @@ -171,83 +222,32 @@ namespace example_novel { 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 { + /** + * @brief 文档定义 + */ + class LIBSYNTAX_EXPORT Document : public AbstractImpl { public: - ElementRule(const QString& rule_name, int expr_mark) - :ExprRule(rule_name, expr_mark) { } + Document(std::shared_ptr rule_bind); - // 通过 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; - } + // 通过 AbstractImpl 继承 + virtual QString signature() const override; + }; + class LIBSYNTAX_EXPORT NGlobalElement : public ast_basic::ExprProgram, public ast_gen::SyntaxElement { + public: + NGlobalElement(const QString &root); + // 通过 SyntaxElement 继承 + std::shared_ptr bindExpression() const override; + int typeMark() const override; + bool isAnonymous() const override; + QString path() const override; + QString signature() const override; + std::weak_ptr parent() const override; + void setParent(std::shared_ptr inst) override; + QList> selfTokens() const override; }; } diff --git a/libSyntax/libSyntax.vcxproj b/libSyntax/libSyntax.vcxproj index 99945be..4482acc 100644 --- a/libSyntax/libSyntax.vcxproj +++ b/libSyntax/libSyntax.vcxproj @@ -108,9 +108,11 @@ + + @@ -122,6 +124,7 @@ + diff --git a/libSyntax/libSyntax.vcxproj.filters b/libSyntax/libSyntax.vcxproj.filters index 51732a2..e74e440 100644 --- a/libSyntax/libSyntax.vcxproj.filters +++ b/libSyntax/libSyntax.vcxproj.filters @@ -50,6 +50,12 @@ Header Files + + Header Files + + + Header Files + @@ -70,5 +76,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/libSyntax/libsyntax.cpp b/libSyntax/libsyntax.cpp index 19e1f11..3a64d30 100644 --- a/libSyntax/libsyntax.cpp +++ b/libSyntax/libsyntax.cpp @@ -9,46 +9,133 @@ using namespace lib_token; using namespace lib_words; using namespace ast_basic; -Rept::Rept(std::shared_ptr rule, int min, int max) : rule_peer(rule), min_match(min), max_match(max) { } +Any::Any(const QList> mbrs) : mbrs_store(mbrs) { } + +QList> Any::children() const { + return mbrs_store; +} + +QList> Any::parse(std::shared_ptr cursor) const { + QList> result_list; + + if (cursor->mustStop()) + result_list << cursor; + else + 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 { + 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; } -std::tuple> Rept::parse(std::shared_ptr rt_inst, std::shared_ptr head) const { - auto temp_head = head; +QList> Rept::parse(std::shared_ptr cursor) const { + QList> results; - // min-match + QList> bridge_list{ cursor }; + // 最小重复次数匹配 for (auto idx = 0; idx < min_match; ++idx) { - auto result_gen = rule_peer->parse(rt_inst, temp_head); - switch (std::get<0>(result_gen)) { - case IBasicRule::MatchResult::Fail: - return std::make_tuple(IBasicRule::MatchResult::Part, temp_head); - case IBasicRule::MatchResult::Part: - return std::make_tuple(IBasicRule::MatchResult::Part, std::get<1>(result_gen)); - default: - temp_head = std::get<1>(result_gen); - break; - } + 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; } - // max-match + // 归并失败分支 + 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) { - if (!temp_head) - break; + QList> current_list; - auto result_gen = rule_peer->parse(rt_inst, temp_head); - switch (std::get<0>(result_gen)) { - case IBasicRule::MatchResult::Fail: - case IBasicRule::MatchResult::Part: - return std::make_tuple(IBasicRule::MatchResult::Success, temp_head); - default: - temp_head = std::get<1>(result_gen); - break; + // 匹配迭代一次 + 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; idxmustStop()) { + results.append(rst_branch->previous()); + current_list.removeAt(idx--); + } } + + bridge_list = current_list; } - return std::make_tuple(IBasicRule::MatchResult::Success, temp_head); + results.append(bridge_list); + return results; } QString Rept::present() const { @@ -62,88 +149,6 @@ QString Rept::present() const { return u8"(" + this->rule_peer->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; -} - -std::tuple> Seqs::parse(std::shared_ptr rt_inst, std::shared_ptr head) const { - auto temp_head = head; - - for (auto& r : mbrs_store) { - auto rst_gene = r->parse(rt_inst, temp_head); - switch (std::get<0>(rst_gene)) { - case IBasicRule::MatchResult::Fail: - return std::make_tuple(IBasicRule::MatchResult::Part, temp_head); - case IBasicRule::MatchResult::Part: - return rst_gene; - case IBasicRule::MatchResult::Success: - temp_head = std::get<1>(rst_gene); - break; - default: - break; - } - } - - return std::make_tuple(IBasicRule::MatchResult::Success, temp_head); -} - -QString Seqs::present() const { - QString content; - for (auto& it : children()) - content += it->present() + " "; - return content.mid(0, content.size() - 1); -} - -//std::tuple, std::shared_ptr> -Any::Any(const QList> mbrs) : mbrs_store(mbrs) { } - -QList> Any::children() const { - return mbrs_store; -} - -std::tuple> Any::parse(std::shared_ptr rt_inst, std::shared_ptr head) const { - std::tuple, uint64_t> temp_result = std::make_tuple(nullptr, 0); - auto rule_present = this->present(); - - for (auto& fork : mbrs_store) { - auto gen = fork->parse(rt_inst, head); - switch (std::get<0>(gen)) { - // 遇到成功的直接返回解析结果 - case IBasicRule::MatchResult::Success: - return gen; - case IBasicRule::MatchResult::Fail: - { - if (!std::get<0>(temp_result)) - temp_result = std::make_tuple(fork, 0); - }break; - case IBasicRule::MatchResult::Part: - { - auto span = std::get<1>(gen)->position() - head->position(); - if (span >= std::get<1>(temp_result)) - temp_result = std::make_tuple(fork, span); - } - default: - break; - } - } - - // 分析最匹配的分支 - rt_inst->clearErrors(rt_inst->currentFile(), head->position()); - auto temp = std::get<0>(temp_result)->parse(rt_inst, head); - return std::make_tuple(IBasicRule::MatchResult::Part, std::get<1>(temp)); -} - -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); -} - - SyntaxException::SyntaxException(const QString& message) { this->msg_store = message; } @@ -152,12 +157,11 @@ 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; -} +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) { - auto ninst = makeCopy(); +std::shared_ptr ExprRule::reloadRule(std::shared_ptr rule) const { + auto ninst = this->make_copy(); ninst->child_store = rule; return ninst; } @@ -175,104 +179,74 @@ QList> ExprRule::children() const { } #include -std::tuple> -ExprRule::parse(std::shared_ptr rt_inst, std::shared_ptr head) const { - std::shared_ptr elm_ast = this->newEmptyInstance(); - auto text_present = this->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(); - - if (rt_inst->currentExprInst()) { - rt_inst->currentExprInst()->addChild(elm_ast); - } - else { - rt_inst->appendDocInst(elm_ast); - } - }break; - default: - break; - } - - return rstg; -} - QString ExprRule::present() const { return child_store->present(); } -lib_syntax::MatchCursor::MatchCursor() { } +MatchCursor::MatchCursor() { } -lib_syntax::MatchCursor::MatchCursor(const MatchCursor& other) - : _expr_through(other._expr_through), - _total_errors(other._total_errors), - _exprs_errors(other._exprs_errors), - _current_token(other._current_token), - _remains_word(other._remains_word) { } +lib_syntax::MatchCursor::MatchCursor(std::shared_ptr other_ptr) + : _prev_cursor(other_ptr), + _total_errors(other_ptr->_total_errors), + _exprs_errors(other_ptr->_exprs_errors), + _current_token(other_ptr->_current_token), + _remains_word(other_ptr->_remains_word) { } -void lib_syntax::MatchCursor::enterExprs(std::shared_ptr ins) { - this->_expr_through.push_back(ins); +std::shared_ptr lib_syntax::MatchCursor::previous() const { + return _prev_cursor; } -std::shared_ptr lib_syntax::MatchCursor::currentExprs() const { - return this->_expr_through.size()?this->_expr_through.last():nullptr; +void MatchCursor::enterExprs() { + auto new_expr = std::make_shared(); + this->_exprs_errors.push_back(new_expr); } -void lib_syntax::MatchCursor::logExprsError(const QString& msg) { - this->_exprs_errors.push_back(msg); +void MatchCursor::logExprsError(const QString& msg) { + this->_total_errors.push_back(msg); + this->_exprs_errors.last()->addError(msg); } -void lib_syntax::MatchCursor::quitExprs() { - this->_expr_through.pop_back(); - - this->_total_errors.append(this->_exprs_errors); - this->_exprs_errors.clear(); +void MatchCursor::quitExprs() { + this->_exprs_errors.pop_back(); } -bool lib_syntax::MatchCursor::mustStop() const { - return this->_exprs_errors.size() >= 2; +bool MatchCursor::mustStop() const { + return exprsErrorCount() >= 2; } -int lib_syntax::MatchCursor::exprsErrorCount() const { - return this->_exprs_errors.size(); +int MatchCursor::exprsErrorCount() const { + return this->_exprs_errors.last()->errorCount(); } -int lib_syntax::MatchCursor::totalErrorCount() const { - return this->_total_errors.size() + this->_exprs_errors.size(); +int MatchCursor::totalErrorCount() const { + return this->_total_errors.size(); } -QList lib_syntax::MatchCursor::totalErrors() const { +QList MatchCursor::totalErrors() const { return this->_total_errors; } -void lib_syntax::MatchCursor::setCurrent(std::shared_ptr t, std::shared_ptr remains) { +void MatchCursor::setCurrent(std::shared_ptr t, std::shared_ptr remains) { this->_current_token = t; this->_remains_word = remains; } -std::shared_ptr lib_syntax::MatchCursor::currentToken() const { +std::shared_ptr MatchCursor::currentToken() const { return this->_current_token; } -std::shared_ptr lib_syntax::MatchCursor::currentWords() const { +std::shared_ptr MatchCursor::currentWords() const { return this->_remains_word; } + +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(); +} diff --git a/libSyntax/libsyntax.h b/libSyntax/libsyntax.h index a9ee6f7..b0fab99 100644 --- a/libSyntax/libsyntax.h +++ b/libSyntax/libsyntax.h @@ -2,14 +2,12 @@ #include "libsyntax_global.h" #include "libtokens.h" +#include "tokens_impl.h" #include #include #include #include -namespace ast_basic { - class IExprInst; - class ExprElement; -} +#include "ast_basic.h" namespace lib_syntax { /** @@ -26,25 +24,33 @@ namespace lib_syntax { virtual QString message() const; }; - // 基础语法解析接口 =================================================================================================== + + + + + // 基础语法解析接口 ==================================================================================== /** * @brief 解析上下文接口 */ - class MatchCursor { - private: - QList> _expr_through; //表达式解析路径 - QList _total_errors; // 所有解析错误 - QList _exprs_errors; // 当前表达式解析错误 - std::shared_ptr _current_token = nullptr; // 当前Token - std::shared_ptr _remains_word = nullptr; // 剩余词语 - + class LIBSYNTAX_EXPORT MatchCursor { public: + class ErrsPack { + public: + void addError(const QString& msg); + QList errors() const; + uint64_t errorCount() const; + + private: + QList _error_collection; + }; + MatchCursor(); - MatchCursor(const MatchCursor& other); + MatchCursor(std::shared_ptr other_ptr); virtual ~MatchCursor() = default; - virtual void enterExprs(std::shared_ptr ins); - virtual std::shared_ptr currentExprs() const; + virtual std::shared_ptr previous() const; + + virtual void enterExprs(); virtual void logExprsError(const QString& msg); virtual void quitExprs(); @@ -53,9 +59,17 @@ namespace lib_syntax { virtual int totalErrorCount() const; virtual QList totalErrors() const; - virtual void setCurrent(std::shared_ptr t, std::shared_ptr remains); - virtual std::shared_ptr currentToken() const; - virtual std::shared_ptr currentWords() const; + virtual void setCurrent(std::shared_ptr t, std::shared_ptr remains); + virtual std::shared_ptr currentToken() const; + virtual std::shared_ptr currentWords() const; + + private: + std::shared_ptr _prev_cursor = nullptr; + + QList _total_errors; // 所有解析错误 + QList> _exprs_errors; // 当前表达式解析错误 + std::shared_ptr _current_token = nullptr; // 当前Token + std::shared_ptr _remains_word = nullptr; // 剩余词语 }; /** @@ -76,14 +90,8 @@ namespace lib_syntax { * @param head 列表头 * @return 返回结果<匹配完成新列表头,匹配长度> */ - virtual QList> parse(std::shared_ptr cursor) const = 0; - }; + virtual QList> parse(std::shared_ptr cursor) const = 0; - /** - * @brief 组合语法匹配规则接口 - */ - class ICompositRule : public IBasicRule { - public: /** * @brief 子规则 * @return @@ -91,82 +99,7 @@ namespace lib_syntax { virtual QList> children() const = 0; }; - template - using token_proc = void(*)(std::shared_ptr expr_inst, std::shared_ptr token); - - /** - * @brief token匹配 - */ - template xproc = nullptr> - class TokenMatch : public IBasicRule, public std::enable_shared_from_this> { - private: - std::shared_ptr _define_peers; - - public: - TokenMatch(std::shared_ptr define) : _define_peers(define) { } - - // IBasicRule interface - public: - virtual QList> parse(std::shared_ptr current) const override { - auto w_this = current->currentWords(); - - auto match_result = _define_peers->analysis(w_this); - if (std::get<0>(match_result)) { - auto current_inst = current->currentExprs(); - current_inst->addToken(std::get<0>(match_result)); - if (xproc) { - xproc(std::dynamic_pointer_cast(current_inst), std::get<0>(match_result)); - } - - auto remains = w_this->nextWord(); - if (std::get<1>(match_result)) { - remains = std::make_shared(std::get<1>(match_result), remains); - } - - auto clone_ins = std::make_shared(current); - auto chain = std::make_shared(std::get<0>(match_result), current->currentToken()); - clone_ins->setCurrent(std::get<0>(chain, remains)); - return QList>() << clone_ins; - } - else { - QList> retvals; - // 少一个 - auto short_one = std::make_shared(current); - short_one->logExprsError(QString(u8"Syntax[0x00001]语法匹配错误,缺失\"%1\"") - .arg(this->_define_peers->reviseWords()) - .arg(w_this->row()).arg(w_this->column()).arg(w_this->file())); - retvals << short_one; - - // 错一个 - auto error_one = std::make_shared(current); - error_one->logExprsError(QString(u8"Syntax[0x00001]语法匹配错误,请修正\"%1\"") - .arg(w_this->content()).arg(w_this->row()).arg(w_this->column()).arg(w_this->file())); - - auto tkins = std::make_shared( - w_this->row(), w_this->column(), w_this->position(), - w_this->content(), w_this->file(), this->_define_peers); - auto tkchain = std::make_shared(tkins, error_one->currentToken()); - error_one->setCurrent(tkchain, w_this->nextWord()); - retvals << error_one; - - // 多一个 - - - - - - rt_inst->appendParseErrors(rt_inst->currentFile(), head->position(), - QString(u8"Syntax[0x00001]语法匹配错误,无法识别\"%1\"(应该为:%4)\n\t目标语法:%5。\n") - .arg(head->content()).arg(head->row()).arg(head->column()).arg(this->_define_peers->reviseWords()) - .arg(rt_inst->currentExprRule()->present())); - return std::make_tuple(IBasicRule::MatchResult::Part, head); - } - } - virtual QString present() const override { - return QString(u8"%1").arg(this->_define_peers->reviseWords()); - } - }; - + // 组合语法实体解析 ===================================================================================== /** * @brief 语法规则或匹配 */ @@ -174,16 +107,13 @@ namespace lib_syntax { private: QList> mbrs_store; - std::tuple, std::shared_ptr> rule_select(std::shared_ptr head) const; - public: Any(const QList> mbrs); // IBasicRule interface public: virtual QList> children() const override; - virtual std::tuple> - parse(std::shared_ptr rt_inst, std::shared_ptr head) const override; + virtual QList> parse(std::shared_ptr cursor) const override; virtual QString present() const override; }; @@ -200,8 +130,7 @@ namespace lib_syntax { // IBasicRule interface public: virtual QList> children() const override; - virtual std::tuple> - parse(std::shared_ptr rt_inst, std::shared_ptr head) const override; + virtual QList> parse(std::shared_ptr cursor) const override; virtual QString present() const override; }; @@ -219,58 +148,163 @@ namespace lib_syntax { // IBasicRule interface public: virtual QList> children() const override; - virtual std::tuple> - parse(std::shared_ptr rt_inst, std::shared_ptr head) const override; + virtual QList> parse(std::shared_ptr cursor) const override; virtual QString present() const override; }; - - // 组合语法实体解析 =================================================================================================== + /** * @brief 对应语法表达式解析规则 */ - class LIBSYNTAX_EXPORT ExprRule : public lib_syntax::IBasicRule, public std::enable_shared_from_this { + class LIBSYNTAX_EXPORT ExprRule : public IBasicRule, public std::enable_shared_from_this { public: - typedef QList> TokenSeqs; ExprRule(const QString& rule_name, int expr_mark); - virtual std::shared_ptr reloadRule(std::shared_ptr rule); virtual QString name() const; virtual int typeMark() const; - - virtual std::shared_ptr newEmptyInstance() const = 0; - virtual std::shared_ptr makeCopy() const = 0; + virtual std::shared_ptr reloadRule(std::shared_ptr rule) const; // IBasicRule interface public: - virtual QList> children() const override; - virtual std::tuple> - parse(std::shared_ptr rt_inst, std::shared_ptr head) const override; + virtual QList> children() const override; virtual QString present() const override; protected: - std::shared_ptr child_store; + std::shared_ptr child_store; + virtual std::shared_ptr make_copy() const = 0; private: QString name_store; int mark_store; }; + + + /** + * @brief token匹配 + */ + template XProc = nullptr> + class TokenMatch : public IBasicRule, public std::enable_shared_from_this> { + private: + std::shared_ptr _define_peers; + + public: + TokenMatch(std::shared_ptr define) : _define_peers(define) { } + + // IBasicRule interface + public: + virtual QString present() const override { + return QString(u8"%1").arg(this->_define_peers->reviseWords()); + } + virtual QList> parse(std::shared_ptr current) const override { + auto w_this = current->currentWords(); + auto t_this = current->currentToken(); + + auto match_result = _define_peers->analysis(w_this); + if (std::get<0>(match_result)) { + auto chain = std::make_shared>(std::get<0>(match_result), t_this); + auto remains = w_this->nextWord(); + if (std::get<1>(match_result)) { + remains = std::make_shared(std::get<1>(match_result), remains); + } + + auto clone_ins = std::make_shared(current); + clone_ins->setCurrent(chain, remains); + return QList>() << clone_ins; + } + else { + QList> retvals; + // 少一个 + { + auto short_one = std::make_shared(current); + short_one->logExprsError(QString(u8"Syntax[0x00001]语法匹配错误,缺失\"%1\"") + .arg(this->_define_peers->reviseWords()) + .arg(w_this->row()).arg(w_this->column()).arg(w_this->file())); + retvals << short_one; + } + + // 错一个 + { + auto error_one = std::make_shared(current); + error_one->logExprsError(QString(u8"Syntax[0x00001]语法匹配错误,请修正\"%1\"") + .arg(w_this->content()).arg(w_this->row()).arg(w_this->column()).arg(w_this->file())); + auto tkins = std::make_shared( + w_this->row(), w_this->column(), w_this->position(), + QString(u8"名称错误_%1").arg((uint64_t)error_one.get()), w_this->file(), this->_define_peers); + auto tkchain = std::make_shared>(tkins, t_this); + error_one->setCurrent(tkchain, w_this->nextWord()); + retvals << error_one; + } + + // 多一个 + { + auto nx_word = w_this->nextWord(); + auto nx_result = this->_define_peers->analysis(nx_word); + if (std::get<0>(nx_result)) { + auto chain = std::make_shared>(std::get<0>(nx_result), t_this); + auto remains = nx_word->nextWord(); + if (std::get<1>(nx_result)) { + remains = std::make_shared(std::get<1>(nx_result), remains); + } + + auto clone_ins = std::make_shared(current); + clone_ins->setCurrent(chain, remains); + retvals << clone_ins; + } + } + + return retvals; + } + } + virtual QList> children() const override { + return QList>(); + } + }; + /** * 语法元素解析规则. */ - template - class ElementRule : public ExprRule { + template class ElementRule : public ExprRule { public: ElementRule(const QString& rule_name, int expr_mark) :ExprRule(rule_name, expr_mark) { } - virtual std::shared_ptr newEmptyInstance() const { - return std::dynamic_pointer_cast( - std::make_shared(this->shared_from_this())); - } + virtual QList> parse(std::shared_ptr cursor) const override { + if (cursor->mustStop()) + return QList>() << cursor; - virtual std::shared_ptr makeCopy() const { - return std::make_shared>(name(), typeMark()); + auto t_this = cursor->currentToken(); + auto w_this = cursor->currentWords(); + auto split_begin = std::make_shared>(shared_from_this(), t_this); + + auto ncursor = std::make_shared(cursor); + ncursor->setCurrent(split_begin, w_this); + ncursor->enterExprs(); + + auto nbranch = this->child_store->parse(ncursor); + decltype(nbranch) branch_procs; + std::for_each(nbranch.begin(), nbranch.end(), [&](std::shared_ptr curs) { + if (curs->mustStop()) { + branch_procs.append(curs); + } + else { + auto t_end = curs->currentToken(); + auto w_end = curs->currentWords(); + + auto ecursor = std::make_shared(curs); + ecursor->quitExprs(); + + auto split_end = std::make_shared>(split_begin, t_end); + ecursor->setCurrent(split_end, w_end); + branch_procs.append(ecursor); + } + }); + + return branch_procs; + } + + protected: + virtual std::shared_ptr make_copy() const { + return std::make_shared>(this->name(), this->typeMark()); } }; } // namespace lib_syntax \ No newline at end of file diff --git a/libSyntax/libtokens.cpp b/libSyntax/libtokens.cpp index a15291b..8497524 100644 --- a/libSyntax/libtokens.cpp +++ b/libSyntax/libtokens.cpp @@ -1,4 +1,5 @@ #include "libtokens.h" +#include "tokens_impl.h" using namespace lib_token; @@ -8,33 +9,29 @@ QString TokenException::message() const { return msg_store; } -lib_token::TokenChain::TokenChain(std::shared_ptr content, std::shared_ptr prev) - : _token_content(content), _token_previous(prev) { } +TokenContent::TokenContent(int r, int c, uint64_t pos, const QString& t, const QString& p, std::shared_ptr paramType) + : row_n(r), col_n(c), doc_offset(pos), text_n(t), path_p(p), type_def(paramType) { } -QString lib_token::TokenChain::file() const { - return _token_content->file(); +QString TokenContent::file() const { + return path_p; } -uint64_t lib_token::TokenChain::position() const { - return _token_content->position(); +uint64_t TokenContent::position() const { + return doc_offset; } -QString lib_token::TokenChain::content() const { - return _token_content->content(); +QString TokenContent::content() const { + return text_n; } -int lib_token::TokenChain::row() const { - return _token_content->row(); +int TokenContent::row() const { + return row_n; } -int lib_token::TokenChain::column() const { - return _token_content->column(); +int TokenContent::column() const { + return col_n; } -std::shared_ptr lib_token::TokenChain::defines() const { - return _token_content->defines(); -} - -std::shared_ptr lib_token::TokenChain::previousToken() const { - return _token_previous; +std::shared_ptr TokenContent::defines() const { + return this->type_def; } diff --git a/libSyntax/libtokens.h b/libSyntax/libtokens.h index 2764e35..dcd77ab 100644 --- a/libSyntax/libtokens.h +++ b/libSyntax/libtokens.h @@ -3,6 +3,10 @@ #include "libsyntax_global.h" #include +namespace ast_basic { + class IExprInstance; +} + namespace lib_token { /** @@ -17,6 +21,12 @@ namespace lib_token { virtual QString message() const; }; + + + + + + // token 解析机制抽象接口========================================== /** * @brief token类型定义 */ @@ -38,20 +48,17 @@ namespace lib_token { /** * @brief token解析结果 */ - class IToken : public lib_words::IWordBase { + class IToken : public lib_words::IWordBase, public std::enable_shared_from_this { public: /** * @brief token解析机制关联 * @return */ virtual std::shared_ptr defines() const = 0; - /** - * @brief 上一个Token - * @return - */ - virtual std::shared_ptr previousToken() const = 0; }; + + // 拓展基础接口========================= /** * @brief token解析机制定义 */ @@ -71,56 +78,24 @@ namespace lib_token { analysis(std::shared_ptr content) const = 0; }; + /** - * @brief 词法解析成果 - */ - class TokenContent : public IToken { - private: - int row_n, col_n, doc_offset; - QString text_n, path_p; - std::shared_ptr type_def; - + * @brief 动作Token + */ + class IActionToken : public lib_token::IToken { public: + /** - * @brief 词法解析内容 - * @param r 行 - * @param c 列 - * @param pos 位置 - * @param t 内容 - * @param p path - * @param paramType 类型定义 + * @brief 上一个Token + * @return */ - TokenContent(int r, int c, uint64_t pos, const QString& t, const QString& p, std::shared_ptr paramType); - - // WordBase interface - public: - virtual QString file() const override; - virtual uint64_t position() const override; - virtual QString content() const override; - virtual int row() const override; - virtual int column() const override; - - // Token interface - public: - virtual std::shared_ptr defines() const override; - virtual std::shared_ptr previousToken() const override; + virtual std::shared_ptr prevToken() const = 0; + /** + * @brief 落实本Token内容到指定expr,返回完善状态后的expr + * @param expr 目标表达式实例 + * @return 完善后的表达式 + */ + virtual std::shared_ptr makeSure(std::shared_ptr expr) = 0; }; - class TokenChain : public IToken { - private: - std::shared_ptr _token_previous; - std::shared_ptr _token_content; - - public: - TokenChain(std::shared_ptr content, std::shared_ptr prev); - - // 通过 IToken 继承 - QString file() const override; - uint64_t position() const override; - QString content() const override; - int row() const override; - int column() const override; - std::shared_ptr defines() const override; - std::shared_ptr previousToken() const override; - }; } \ No newline at end of file diff --git a/libSyntax/syntax_novel.cpp b/libSyntax/syntax_novel.cpp index 70b35d0..e2df938 100644 --- a/libSyntax/syntax_novel.cpp +++ b/libSyntax/syntax_novel.cpp @@ -12,23 +12,29 @@ auto leftb = std::make_shared(); // { auto rightb = std::make_shared(); // } auto refers = std::make_shared(); // @ auto declare = std::make_shared(); // # -auto split_mark = std::make_shared(); // & +auto split_mark = std::make_shared(); // & auto rank_key = std::make_shared(u8"排序", 0xAEu); // 排序 -auto story_key = std::make_shared(u8"故事", 0xAAu); // 故事 -auto numbers = std::make_shared(); // [0-9]+ -auto frag_key = std::make_shared(u8"情节", 0xABu); // 情节 +auto story_key = std::make_shared(u8"故事", 0xAAu); // 故事 +auto numbers = std::make_shared(); // [0-9]+ +auto slice_key = std::make_shared(u8"剧情", 0xAFu); // 剧情 +auto point_key = std::make_shared(u8"节点", 0xABu); // 节点 auto volume_key = std::make_shared(u8"分卷", 0xACu); // 分卷 -auto article_key = std::make_shared(u8"章节", 0xADu); // 章节 +auto article_key = std::make_shared(u8"章节", 0xADu); // 章节 auto vtext = std::make_shared(); // ^([^\\{\\}@&]+) -auto name_text = std::make_shared(); // ^([^\\{\\}@&]+) +auto name_text = std::make_shared(); // ^([^\\{\\}@&]+) // rule-parts =============================================================================== +template +void apntk(std::shared_ptr expr, std::shared_ptr t) { + expr->addToken(t); +} + // MatchRule -#define MR(E, x) std::make_shared>(x) -#define MER(E, xproc, t) std::make_shared>(t) +#define MER(E, XProc, t) std::make_shared>(t) +#define MR(E, t) MER(E, apntk, t) // Buffer #define Rules QList> // Option @@ -41,119 +47,145 @@ auto name_text = std::make_shared(); // ^ -auto decl_expr = ElementRule(u8"decl_section", (int)NovelExprs::DESC_SECTION).reloadRule( +auto decl_expr = ElementRule(u8"decl_section", (int) NovelNode::TextSection).reloadRule( MultiR(std::make_shared(Rules{ MR(TextSection, numbers), MR(TextSection, vtext), MR(TextSection, refers), MR(TextSection, split_mark) - })) + })) ); -void frags_nmset(std::shared_ptr inst, std::shared_ptr token) { +void point_nmset(std::shared_ptr inst, std::shared_ptr token) { + inst->addToken(token); inst->setName(token->content()); } -auto fragment_decl = ElementRule(u8"fragment_define", (int)NovelExprs::FRAG_DEFINES).reloadRule( +auto point_decl = ElementRule(u8"point_define", (int) NovelNode::PointDefines).reloadRule( std::make_shared(Rules{ - MR(PointDefines, leftb), MR(PointDefines, frag_key), MER(PointDefines, frags_nmset, name_text) } << + MR(PointDefines, leftb), MR(PointDefines, point_key), MER(PointDefines, point_nmset, name_text) } << OptR(decl_expr) << - MR(PointDefines, rightb) - )); + MR(PointDefines, rightb) +)); -void frags_snm_set(std::shared_ptr inst, std::shared_ptr token) { +void point_ref_story_set(std::shared_ptr inst, std::shared_ptr token) { + inst->addToken(token); inst->setStoryRefer(token->content()); } -void frags_fnm_set(std::shared_ptr inst, std::shared_ptr token) { - inst->setFragmentRefer(token->content()); +void point_ref_slice_set(std::shared_ptr inst, std::shared_ptr token) { + inst->addToken(token); + inst->setSliceRefer(token->content()); } -auto fragment_refer = ElementRule(u8"fragment_refer", (int)NovelExprs::FRAG_REFERS).reloadRule( +void point_ref_point_set(std::shared_ptr inst, std::shared_ptr token) { + inst->addToken(token); + inst->setPointRefer(token->content()); +} +auto point_refer = ElementRule(u8"point_refer", (int) NovelNode::PointRefers).reloadRule( std::make_shared(Rules{ - MR(PointRefers, leftb), MR(PointRefers, refers), MR(PointRefers, frag_key), - MER(PointRefers, frags_fnm_set, name_text), MR(PointRefers, split_mark), MER(PointRefers, frags_snm_set, name_text) } << + MR(PointRefers, leftb), MR(PointRefers, refers), MR(PointRefers, point_key), + MER(PointRefers, point_ref_story_set, name_text), + MR(PointRefers, split_mark), + MER(PointRefers, point_ref_slice_set, name_text), + MR(PointRefers, split_mark), + MER(PointRefers, point_ref_point_set, name_text) } << OptR(decl_expr) << - MR(PointRefers, rightb) - )); + MR(PointRefers, rightb) +)); + +void slice_nm_set(std::shared_ptr inst, std::shared_ptr token) { + inst->addToken(token); + inst->setName(token->content()); +} +auto slice_define = ElementRule(u8"slice_define", (int) NovelNode::FragmentSlice).reloadRule( + std::make_shared(Rules{ + MR(FragmentSlice, leftb), MR(FragmentSlice, slice_key), MER(FragmentSlice, slice_nm_set, name_text) } << + OptMulR(std::make_shared(Rules{ point_decl, point_refer, decl_expr })) << + MR(FragmentSlice, rightb) +)); void story_nmset(std::shared_ptr inst, std::shared_ptr token) { + inst->addToken(token); inst->setName(token->content()); } -auto story_define = ElementRule(u8"story_define", (int)NovelExprs::STORY_DEFINES).reloadRule( +auto story_define = ElementRule(u8"story_define", (int) NovelNode::StoryDefine).reloadRule( std::make_shared(Rules{ MR(StoryDefine, leftb), MR(StoryDefine, story_key), MER(StoryDefine, story_nmset, name_text) } << - OptMulR(std::make_shared(Rules{ fragment_decl, fragment_refer, decl_expr })) << - MR(StoryDefine, rightb) - )); + OptMulR(std::make_shared(Rules{ slice_define, decl_expr })) << + MR(StoryDefine, rightb) +)); // =================================================================== void article_nset(std::shared_ptrinst, std::shared_ptr token) { + inst->addToken(token); inst->setName(token->content()); } -auto article_decl = ElementRule(u8"article_define", (int)NovelExprs::ARTICLE_DEFINE).reloadRule( +auto article_decl = ElementRule(u8"article_define", (int) NovelNode::ArticleDefine).reloadRule( std::make_shared(Rules{ MR(ArticleDefine, leftb), MR(ArticleDefine, article_key), MER(ArticleDefine, article_nset, name_text) } << - OptMulR(std::make_shared(Rules{ fragment_refer, decl_expr })) << - MR(ArticleDefine, rightb) - )); + OptMulR(std::make_shared(Rules{ point_refer, decl_expr })) << + MR(ArticleDefine, rightb) +)); void volume_nset(std::shared_ptr inst, std::shared_ptr token) { + inst->addToken(token); inst->setName(token->content()); } -auto volume_decl = ElementRule(u8"volume_define", (int)NovelExprs::VOLUME_DEFINE).reloadRule( +auto volume_decl = ElementRule(u8"volume_define", (int) NovelNode::VolumeDefine).reloadRule( std::make_shared(Rules{ MR(VolumeDefine, leftb), MR(VolumeDefine, volume_key), MER(VolumeDefine, volume_nset, name_text) } << OptMulR(std::make_shared(Rules{ decl_expr, article_decl })) << - MR(VolumeDefine, rightb) - )); + MR(VolumeDefine, rightb) +)); void rank_set(std::shared_ptr inst, std::shared_ptr token) { + inst->addToken(token); inst->setRank(token->content().toInt()); } -auto rank_define = ElementRule(u8"rank_define", (int)NovelNode::RankDeclaration).reloadRule( +auto rank_define = ElementRule(u8"rank_define", (int) NovelNode::RankDeclaration).reloadRule( std::make_shared(Rules{ MR(RankDeclare, declare), MR(RankDeclare, rank_key), MER(RankDeclare, rank_set, numbers) } )); -auto document_define = ElementRule(u8"decls-doc", (int)NovelExprs::DOC_DEFINES).reloadRule( +auto document_define = ElementRule(u8"decls-doc", (int) NovelNode::Document).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) -{ - build_objecttree(root, children); - node_register(root, children); - return root; -} -void NovalSyntax::build_objecttree(std::shared_ptr root, QList> children) -{ - for (auto& cinst : children) { - cinst->setParent(root); - - QList> child_items; - for (auto& it : cinst->bindExpression()->children()) { - auto const_it = std::dynamic_pointer_cast(it); - child_items.append(std::const_pointer_cast(const_it)); - } - - build_objecttree(cinst, child_items); + Rules{ + std::make_shared(rank_define, 0, 1), + MultiR(std::make_shared(Rules{story_define, volume_decl})) } -} -void NovalSyntax::node_register(std::shared_ptr root, QList> children) -{ - for (auto& child : children) { - if (!child->isAnonymous()) { - auto check_result = ast_gen::GlobalElement::UniquePtr->appendToCache(child); - 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())); - } - - QList> next_child_items; - for (auto& it : child->bindExpression()->children()) { - auto const_it = std::dynamic_pointer_cast(it); - next_child_items.append(std::const_pointer_cast(const_it)); - } - - node_register(child, next_child_items); - } -} \ No newline at end of file +)); +// +//std::shared_ptr NovalSyntax::getParseTree() { return document_define; } +//std::shared_ptr NovalSyntax::tidy(std::shared_ptr root, QList> children) +//{ +// build_objecttree(root, children); +// node_register(root, children); +// return root; +//} +//void NovalSyntax::build_objecttree(std::shared_ptr root, QList> children) +//{ +// for (auto& cinst : children) { +// cinst->setParent(root); +// +// QList> child_items; +// for (auto& it : cinst->bindExpression()->children()) { +// auto const_it = std::dynamic_pointer_cast(it); +// child_items.append(std::const_pointer_cast(const_it)); +// } +// +// build_objecttree(cinst, child_items); +// } +//} +//void NovalSyntax::node_register(std::shared_ptr root, QList> children) +//{ +// for (auto& child : children) { +// if (!child->isAnonymous()) { +// auto check_result = ast_gen::GlobalElement::UniquePtr->appendToCache(child); +// if (check_result) +// throw new SyntaxException(QString(u8"SyntaxError[0x0004]系统中包含同类型重名命名节点:%1(%3,%4)") +// .arg(child->signature()).arg(child->typeMark()).arg(child->path()).arg(check_result->path())); +// } +// +// QList> next_child_items; +// for (auto& it : child->bindExpression()->children()) { +// auto const_it = std::dynamic_pointer_cast(it); +// next_child_items.append(std::const_pointer_cast(const_it)); +// } +// +// node_register(child, next_child_items); +// } +//} \ No newline at end of file diff --git a/libSyntax/syntax_novel.h b/libSyntax/syntax_novel.h index d221d85..0e956ba 100644 --- a/libSyntax/syntax_novel.h +++ b/libSyntax/syntax_novel.h @@ -7,34 +7,19 @@ #include namespace example_novel { - /** - * @brief 节点类型 - * ExprNode::typeMark() 返回值 - */ - enum NovelExprs { - DESPITE = -1, - DESC_SECTION = 0, - FRAG_REFERS = 1, - FRAG_DEFINES = 2, - STORY_DEFINES = 3, - DOC_DEFINES = 4, - VOLUME_DEFINE = 5, - ARTICLE_DEFINE = 6, - }; + //class LIBSYNTAX_EXPORT NovalSyntax { + //public: + // /** + // * @brief 获取novel语法解析树 + // * @return + // */ + // static std::shared_ptr getParseTree(); - class LIBSYNTAX_EXPORT NovalSyntax { - public: - /** - * @brief 获取novel语法解析树 - * @return - */ - static std::shared_ptr getParseTree(); + // static std::shared_ptr tidy(std::shared_ptr root, QList> docs); - static std::shared_ptr tidy(std::shared_ptr root, QList> docs); - - private: - static void build_objecttree(std::shared_ptr root, QList> docs); - static void node_register(std::shared_ptr root, QList> docs); - }; + //private: + // static void build_objecttree(std::shared_ptr root, QList> docs); + // static void node_register(std::shared_ptr root, QList> docs); + //}; } // namespace example_novel \ No newline at end of file diff --git a/libSyntax/tokens_impl.h b/libSyntax/tokens_impl.h new file mode 100644 index 0000000..2ae7dbb --- /dev/null +++ b/libSyntax/tokens_impl.h @@ -0,0 +1,185 @@ +#pragma once + +#include "libtokens.h" +#include "ast_basic.h" + +namespace lib_token { + + template + using TokenProcs = void(*)(std::shared_ptr expr, std::shared_ptr t); + + + // 基础token实现 =================================================== + /** + * @brief 词法解析成果 + */ + class TokenContent : public IToken { + private: + int row_n, col_n, doc_offset; + QString text_n, path_p; + std::shared_ptr type_def; + + public: + /** + * @brief 词法解析内容 + * @param r 行 + * @param c 列 + * @param pos 位置 + * @param t 内容 + * @param p path + * @param paramType 类型定义 + */ + TokenContent(int r, int c, uint64_t pos, const QString& t, const QString& p, std::shared_ptr paramType); + + // WordBase interface + public: + virtual QString file() const override; + virtual uint64_t position() const override; + virtual QString content() const override; + virtual int row() const override; + virtual int column() const override; + + // Token interface + public: + virtual std::shared_ptr defines() const override; + }; + + + /** + * @brief 动作Token + */ + template proc> + class ActionToken : public IActionToken { + private: + std::shared_ptr _bind_content; + std::shared_ptr _bind_previous; + + public: + ActionToken(std::shared_ptr content, std::shared_ptr prev) + : _bind_content(content), _bind_previous(prev) { } + + virtual std::shared_ptr makeSure(std::shared_ptr expr) { + auto expr_inst = std::dynamic_pointer_cast(expr); + proc(expr_inst, shared_from_this()); + return expr; + } + + // 通过 IActionToken 继承 + QString file() const override { + return _bind_content->file(); + } + uint64_t position() const override { + return _bind_content->position(); + } + QString content() const override { + return _bind_content->content(); + } + int row() const override { + return _bind_content->row(); + } + int column() const override { + return _bind_content->column(); + } + std::shared_ptr defines() const override { + return _bind_content->defines(); + } + std::shared_ptr prevToken() const override { + return this->_bind_previous; + } + }; + + /** + * @brief 表达式起始token + */ + template class ExprBeginToken : public IActionToken { + private: + std::shared_ptr _prev_token = nullptr; + std::shared_ptr _self_rule = nullptr; + + std::shared_ptr _parent_expr = nullptr; + std::shared_ptr _self_expr = nullptr; + + public: + ExprBeginToken(std::shared_ptr rule, std::shared_ptr prev) + :_prev_token(prev), _self_rule(rule) { } + + std::shared_ptr parentExpr(){ + return this->_parent_expr; + } + + // 通过 IActionToken 继承 + QString file() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprBeginToken"); + } + + uint64_t position() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprBeginToken"); + } + + QString content() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprBeginToken"); + } + + int row() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprBeginToken"); + } + + int column() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprBeginToken"); + } + + std::shared_ptr defines() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprBeginToken"); + } + + std::shared_ptr prevToken() const override { + return _prev_token; + } + + std::shared_ptr makeSure(std::shared_ptr expr) override { + this->_parent_expr = expr; + this->_self_expr = std::make_shared(_self_rule); + this->_parent_expr->addChild(this->_self_expr); + return this->_self_expr; + } + }; + + /** + * @brief 表达式终止token + */ + template class ExprEndToken : public IActionToken { + private: + std::shared_ptr _prev_token = nullptr; + std::shared_ptr> _self_start = nullptr; + + public: + ExprEndToken(std::shared_ptr> start, std::shared_ptr prev) + : _prev_token(prev), _self_start(start){ } + + // 通过 IActionToken 继承 + QString file() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprEndToken"); + } + uint64_t position() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprEndToken"); + } + QString content() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprEndToken"); + } + int row() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprEndToken"); + } + int column() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprEndToken"); + } + std::shared_ptr defines() const override { + throw new lib_token::TokenException(u8"不应该直接访问ExprEndToken"); + } + std::shared_ptr prevToken() const override { + return _prev_token; + } + std::shared_ptr makeSure(std::shared_ptr expr) override { + return this->_self_start->parentExpr(); + } + }; +} \ No newline at end of file diff --git a/libSyntax/tokens_novel.cpp b/libSyntax/tokens_novel.cpp index 5316695..d5b6362 100644 --- a/libSyntax/tokens_novel.cpp +++ b/libSyntax/tokens_novel.cpp @@ -1,33 +1,12 @@ #include "tokens_novel.h" #include +#include "tokens_impl.h" using namespace example_novel; using namespace lib_token; using namespace lib_words; -TokenContent::TokenContent(int r, int c, uint64_t pos, const QString& t, const QString& p, std::shared_ptr paramType) - : row_n(r), col_n(c), doc_offset(pos), text_n(t), path_p(p), type_def(paramType) {} - -QString TokenContent::file() const { return path_p; } - -uint64_t TokenContent::position() const { - return doc_offset; -} - -QString TokenContent::content() const { return text_n; } - -int TokenContent::row() const { return row_n; } - -int TokenContent::column() const { return col_n; } - -std::shared_ptr TokenContent::previousToken() const -{ - return nullptr; -} - -std::shared_ptr TokenContent::defines() const { return this->type_def; } - QString LeftBracket::reviseWords() const { return u8"'{'"; } int LeftBracket::typeMark() const