354 lines
8.2 KiB
C++
354 lines
8.2 KiB
C++
#pragma once
|
||
|
||
#include "ast_basic.h"
|
||
#include "libsyntax.h"
|
||
#include <QtCore/QHash>
|
||
#include <QtCore/QString>
|
||
|
||
namespace ast_gen {
|
||
class TokenAccess;
|
||
|
||
/**
|
||
* @brief 解析上下文
|
||
*/
|
||
class SyntaxElement {
|
||
public:
|
||
virtual ~SyntaxElement() = default;
|
||
/**
|
||
* 绑定表达式实体.
|
||
*
|
||
* \return 表达式实例
|
||
*/
|
||
virtual std::shared_ptr<const ast_basic::IExprInstance> 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<const SyntaxElement> parent() const = 0;
|
||
/**
|
||
* @brief 重置父指针.
|
||
*
|
||
* \param inst
|
||
*/
|
||
virtual void setParent(std::shared_ptr<const SyntaxElement> inst) = 0;
|
||
|
||
/**
|
||
* @brief 定义元素自身的Token集合
|
||
* @return
|
||
*/
|
||
virtual QList<std::shared_ptr<const TokenAccess>> selfTokens() const = 0;
|
||
};
|
||
|
||
/**
|
||
* @brief 语法元素整理访问接口
|
||
*/
|
||
class LIBSYNTAX_EXPORT ElementAccess {
|
||
private:
|
||
std::shared_ptr<const SyntaxElement> peers;
|
||
|
||
public:
|
||
ElementAccess(std::shared_ptr<const SyntaxElement> point);
|
||
|
||
std::shared_ptr<const SyntaxElement> element() const;
|
||
QList<std::shared_ptr<const ElementAccess>> children() const;
|
||
|
||
/**
|
||
* @brief 获取该元素下所有Token定义
|
||
* @return
|
||
*/
|
||
virtual QList<std::shared_ptr<const TokenAccess>> tokens() const;
|
||
};
|
||
|
||
/**
|
||
* @brief Token元素访问接口
|
||
*/
|
||
class LIBSYNTAX_EXPORT TokenAccess {
|
||
private:
|
||
std::shared_ptr<const ast_gen::SyntaxElement> element_bind;
|
||
std::shared_ptr<const lib_token::IToken> token_store;
|
||
|
||
public:
|
||
TokenAccess(std::shared_ptr<const ast_gen::SyntaxElement> elm_inst, std::shared_ptr<const lib_token::IToken> token_inst);
|
||
virtual std::shared_ptr<const ast_gen::SyntaxElement> bind() const;
|
||
virtual std::shared_ptr<const lib_token::IToken> token() const;
|
||
};
|
||
|
||
}
|
||
|
||
namespace example_novel {
|
||
enum class NovelNode {
|
||
GlobalElement = 0,
|
||
TextSection = 1,
|
||
PointRefers = 2,
|
||
PointDefines = 3,
|
||
StoryDefine = 4,
|
||
Document = 5,
|
||
ArticleDefine = 6,
|
||
VolumeDefine = 7,
|
||
RankDeclaration = 8,
|
||
FragmentSlice = 9,
|
||
};
|
||
|
||
/*
|
||
GlobalElement
|
||
\-Document
|
||
|-RankDeclaration
|
||
|-StoryDefine
|
||
| |-TextSection
|
||
| \-FragmentSlice
|
||
| |-TextSection
|
||
| |-PointDefines
|
||
| | \-TextSection
|
||
| \-PointRefers
|
||
| \-TextSection
|
||
\-VolumeDefine
|
||
|-TextSection
|
||
\-ArticleDefine
|
||
|-TextSection
|
||
\-PointRefers
|
||
\-TextSection
|
||
*/
|
||
|
||
template<NovelNode type, bool named>
|
||
class AbstractImpl : public ast_basic::ExprInstance, public ast_gen::SyntaxElement {
|
||
private:
|
||
std::weak_ptr<const SyntaxElement> parent_store;
|
||
|
||
public:
|
||
AbstractImpl(std::shared_ptr<const lib_syntax::ExprRule> rule_bind)
|
||
: ExprInstance(rule_bind) {
|
||
parent_store.reset();
|
||
}
|
||
|
||
// 通过 SyntaxElement 继承
|
||
virtual int typeMark() const override {
|
||
return (int) type;
|
||
}
|
||
virtual bool isAnonymous() const override {
|
||
return !named;
|
||
}
|
||
virtual std::shared_ptr<const IExprInstance> bindExpression() const override {
|
||
return shared_from_this();
|
||
}
|
||
QString path() const override {
|
||
return ExprInstance::filePath();
|
||
}
|
||
virtual std::weak_ptr<const ast_gen::SyntaxElement> parent() const override {
|
||
return this->parent_store;
|
||
}
|
||
virtual void setParent(std::shared_ptr<const ast_gen::SyntaxElement> inst) override {
|
||
this->parent_store = inst;
|
||
}
|
||
virtual QList<std::shared_ptr<const ast_gen::TokenAccess>> selfTokens() const override {
|
||
auto tokensx = ExprInstance::tokens();
|
||
QList<std::shared_ptr<const ast_gen::TokenAccess>> values;
|
||
for (auto xit : tokensx) {
|
||
values.append(std::make_shared<ast_gen::TokenAccess>(std::dynamic_pointer_cast<const ast_gen::SyntaxElement>(shared_from_this()), xit));
|
||
}
|
||
|
||
return values;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* @brief 文字段落
|
||
*/
|
||
class LIBSYNTAX_EXPORT TextSection : public AbstractImpl<NovelNode::TextSection, false> {
|
||
public:
|
||
TextSection(std::shared_ptr<const lib_syntax::ExprRule> rule_bind);
|
||
|
||
/**
|
||
* @brief 段落内容
|
||
*/
|
||
QString content() const;
|
||
|
||
// 通过 AbstractImpl 继承
|
||
virtual QString signature() const override;
|
||
};
|
||
|
||
/**
|
||
* @brief 故事情节
|
||
*/
|
||
class LIBSYNTAX_EXPORT FragmentSlice : public AbstractImpl<NovelNode::FragmentSlice, true> {
|
||
private:
|
||
QString _slice_name;
|
||
|
||
public:
|
||
FragmentSlice(std::shared_ptr<const lib_syntax::ExprRule> rule);
|
||
|
||
QString name() const;
|
||
void setName(const QString& nm);
|
||
|
||
// 通过 AbstractImpl 继承
|
||
QString signature() const override;
|
||
};
|
||
|
||
/**
|
||
* @brief 节点引用定义
|
||
*/
|
||
class LIBSYNTAX_EXPORT PointRefers : public AbstractImpl<NovelNode::PointRefers, false> {
|
||
private:
|
||
QString story_refs, slice_ref, point_ref;
|
||
|
||
public:
|
||
PointRefers(std::shared_ptr<const lib_syntax::ExprRule> rule_bind);
|
||
|
||
QString storyRefer() const;
|
||
void setStoryRefer(const QString& refer);
|
||
|
||
QString sliceRefer() const;
|
||
void setSliceRefer(const QString& refer);
|
||
|
||
QString pointRefer() const;
|
||
void setPointRefer(const QString& refer);
|
||
|
||
QString referSignature() const;
|
||
|
||
// 通过 AbstractImpl 继承
|
||
virtual QString signature() const override;
|
||
};
|
||
|
||
/**
|
||
* @brief 节点定义
|
||
*/
|
||
class LIBSYNTAX_EXPORT PointDefines : public AbstractImpl<NovelNode::PointDefines, true> {
|
||
private:
|
||
QString name_store;
|
||
|
||
public:
|
||
PointDefines(std::shared_ptr<const lib_syntax::ExprRule> rule_bind);
|
||
|
||
QString name() const;
|
||
void setName(const QString& nm);
|
||
|
||
// 通过 AbstractImpl 继承
|
||
virtual QString signature() const override;
|
||
};
|
||
|
||
/**
|
||
* @brief 章节定义
|
||
*/
|
||
class LIBSYNTAX_EXPORT ArticleDefine : public AbstractImpl<NovelNode::ArticleDefine, true> {
|
||
public:
|
||
ArticleDefine(std::shared_ptr<const lib_syntax::ExprRule> rule_bind);
|
||
|
||
QString name() const;
|
||
void setName(const QString& nm);
|
||
|
||
// 通过 AbstractImpl 继承
|
||
virtual QString signature() const override;
|
||
|
||
private:
|
||
QString name_store;
|
||
};
|
||
|
||
/**
|
||
* @brief 卷宗定义
|
||
*/
|
||
class LIBSYNTAX_EXPORT VolumeDefine : public AbstractImpl<NovelNode::VolumeDefine, true> {
|
||
public:
|
||
VolumeDefine(std::shared_ptr<const lib_syntax::ExprRule> rule_bind);
|
||
|
||
QString name() const;
|
||
void setName(const QString& nm);
|
||
|
||
// 通过 AbstractImpl 继承
|
||
virtual QString signature() const override;
|
||
|
||
private:
|
||
QString name_store;
|
||
};
|
||
|
||
/**
|
||
* @brief 故事定义
|
||
*/
|
||
class LIBSYNTAX_EXPORT StoryDefine : public AbstractImpl<NovelNode::StoryDefine, true> {
|
||
public:
|
||
StoryDefine(std::shared_ptr<const lib_syntax::ExprRule> rule_bind);
|
||
|
||
QString name() const;
|
||
void setName(const QString& nm);
|
||
|
||
void setSort(int value);
|
||
int sort() const;
|
||
|
||
// 通过 AbstractImpl 继承
|
||
virtual QString signature() const override;
|
||
|
||
private:
|
||
QString name_store;
|
||
int sort_index;
|
||
};
|
||
|
||
/**
|
||
* @brief 排序声明
|
||
*/
|
||
class LIBSYNTAX_EXPORT RankDeclare : public AbstractImpl<NovelNode::RankDeclaration, false> {
|
||
private:
|
||
int page_rank = 0;
|
||
public:
|
||
RankDeclare(std::shared_ptr<const lib_syntax::ExprRule> rule);
|
||
|
||
int rankNumber() const;
|
||
void setRank(int nums);
|
||
|
||
// 通过 AbstractImpl 继承
|
||
QString signature() const override;
|
||
};
|
||
|
||
/**
|
||
* @brief 文档定义
|
||
*/
|
||
class LIBSYNTAX_EXPORT Document : public AbstractImpl<NovelNode::Document, false> {
|
||
public:
|
||
Document(std::shared_ptr<const lib_syntax::ExprRule> rule_bind);
|
||
|
||
// 通过 AbstractImpl 继承
|
||
virtual QString signature() const override;
|
||
};
|
||
|
||
/**
|
||
* @brief 全局根元素
|
||
*/
|
||
class LIBSYNTAX_EXPORT NGlobalElement : public ast_basic::ExprProgram, public ast_gen::SyntaxElement {
|
||
public:
|
||
NGlobalElement(const QString &root);
|
||
|
||
// 通过 SyntaxElement 继承
|
||
std::shared_ptr<const ast_basic::IExprInstance> bindExpression() const override;
|
||
int typeMark() const override;
|
||
bool isAnonymous() const override;
|
||
QString path() const override;
|
||
QString signature() const override;
|
||
std::weak_ptr<const SyntaxElement> parent() const override;
|
||
void setParent(std::shared_ptr<const SyntaxElement> inst) override;
|
||
QList<std::shared_ptr<const ast_gen::TokenAccess>> selfTokens() const override;
|
||
};
|
||
}
|