diff --git a/libSyntax/ast_access.cpp b/libSyntax/ast_access.cpp deleted file mode 100644 index e607483..0000000 --- a/libSyntax/ast_access.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#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 deleted file mode 100644 index 496c1d0..0000000 --- a/libSyntax/ast_access.h +++ /dev/null @@ -1,136 +0,0 @@ -#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_gen.cpp b/libSyntax/ast_gen.cpp index b7a2a46..1fa6a85 100644 --- a/libSyntax/ast_gen.cpp +++ b/libSyntax/ast_gen.cpp @@ -1,5 +1,4 @@ #include "ast_gen.h" -#include "ast_access.h" using namespace ast_gen; using namespace ast_basic; @@ -27,10 +26,17 @@ QList> SyntaxParser::parse(std::shared_ptr ast_gen::SyntaxParser::getAst( std::shared_ptr cursor, std::shared_ptr root) { + QList> token_seqs; std::shared_ptr action_token = cursor->currentToken(); - while (action_token->prevToken()) { + while (action_token) { + token_seqs.prepend(action_token); action_token = action_token->prevToken(); } - return std::const_pointer_cast(action_token)->makeSure(root); + auto expr_inst = root; + for (auto ins_t : token_seqs) { + expr_inst = std::const_pointer_cast(ins_t)->makeSure(expr_inst); + } + + return expr_inst; } diff --git a/libSyntax/ast_gen.h b/libSyntax/ast_gen.h index df59712..b98a0eb 100644 --- a/libSyntax/ast_gen.h +++ b/libSyntax/ast_gen.h @@ -9,7 +9,7 @@ namespace ast_gen { /** * @brief 语法解析器 */ - class SyntaxParser { + class LIBSYNTAX_EXPORT SyntaxParser { private: std::shared_ptr _rule_bind = nullptr; diff --git a/libSyntax/ast_novel.cpp b/libSyntax/ast_novel.cpp index c63d044..ad3fa37 100644 --- a/libSyntax/ast_novel.cpp +++ b/libSyntax/ast_novel.cpp @@ -1,5 +1,5 @@ #include "ast_novel.h" - +#include using namespace example_novel; using namespace lib_syntax; @@ -199,3 +199,101 @@ QList> NGlobalElement::selfTokens() const { } NGlobalElement::NGlobalElement(const QString& root): ExprProgram(root) { } + + + +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_novel.h b/libSyntax/ast_novel.h index 523404f..4194582 100644 --- a/libSyntax/ast_novel.h +++ b/libSyntax/ast_novel.h @@ -1,8 +1,141 @@ #pragma once -#include "ast_access.h" #include "ast_basic.h" #include "libsyntax.h" +#include +#include + +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; + }; + + /** + * @brief Token元素访问接口 + */ + 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; + }; +} namespace example_novel { enum class NovelNode { @@ -236,6 +369,9 @@ namespace example_novel { virtual QString signature() const override; }; + /** + * @brief 全局根元素 + */ class LIBSYNTAX_EXPORT NGlobalElement : public ast_basic::ExprProgram, public ast_gen::SyntaxElement { public: NGlobalElement(const QString &root); diff --git a/libSyntax/libSyntax.vcxproj b/libSyntax/libSyntax.vcxproj index 4482acc..c4ef402 100644 --- a/libSyntax/libSyntax.vcxproj +++ b/libSyntax/libSyntax.vcxproj @@ -108,11 +108,9 @@ - - diff --git a/libSyntax/libSyntax.vcxproj.filters b/libSyntax/libSyntax.vcxproj.filters index e74e440..21e292a 100644 --- a/libSyntax/libSyntax.vcxproj.filters +++ b/libSyntax/libSyntax.vcxproj.filters @@ -53,9 +53,6 @@ Header Files - - Header Files - @@ -76,8 +73,5 @@ Source Files - - Source Files - \ No newline at end of file diff --git a/libSyntax/syntax_novel.cpp b/libSyntax/syntax_novel.cpp index e2df938..289a940 100644 --- a/libSyntax/syntax_novel.cpp +++ b/libSyntax/syntax_novel.cpp @@ -148,8 +148,8 @@ auto document_define = ElementRule(u8"decls-doc", (int) NovelNode::Doc MultiR(std::make_shared(Rules{story_define, volume_decl})) } )); -// -//std::shared_ptr NovalSyntax::getParseTree() { return document_define; } + +std::shared_ptr NovalSyntax::getSyntaxTree() { return document_define; } //std::shared_ptr NovalSyntax::tidy(std::shared_ptr root, QList> children) //{ // build_objecttree(root, children); diff --git a/libSyntax/syntax_novel.h b/libSyntax/syntax_novel.h index 0e956ba..ed6086b 100644 --- a/libSyntax/syntax_novel.h +++ b/libSyntax/syntax_novel.h @@ -7,19 +7,19 @@ #include namespace example_novel { - //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 getSyntaxTree(); // 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); - //}; + }; } // namespace example_novel \ No newline at end of file