移除冗余层次,语法规则解析直出语法结构

This commit is contained in:
codeboss 2024-06-18 11:54:36 +08:00
parent fc1e13b74d
commit c8fedda85b
12 changed files with 609 additions and 798 deletions

View File

@ -23,37 +23,29 @@ QString NovelParser::version() const
}
std::shared_ptr<const ast_gen::ElementAccess> NovelParser::parse(const QFileInfoList source_list) const {
QList<std::shared_ptr<const ast_basic::TokenNode>> forst_root;
QList<std::shared_ptr<const ast_basic::Expression>> forst_root;
auto lex_reader = NovalSyntax::getLexReader();
auto context = std::make_shared<ast_gen::GlobalElement>(u8"С˵");
auto time_stamp = QTime::currentTime();
for (auto& file : source_list) {
auto tokens = lex_reader->extractFrom(file.canonicalFilePath());
auto exprs_result = std::make_shared<lib_syntax::ExprsChecker>(this->syntax_defines)->parseFrom(tokens);
auto exprs_result = this->syntax_defines->parse(context, tokens);
forst_root.append(exprs_result);
}
auto current_stamp = QTime::currentTime();
qDebug() << QString(u8"词法解析+语法解析消耗时间:%1 ms。").arg(time_stamp.msecsTo(current_stamp));
std::function<QList<std::shared_ptr<const ast_basic::ExprNode>>(QList<std::shared_ptr<const ast_basic::TokenNode>> input)> summary =
[&](QList<std::shared_ptr<const ast_basic::TokenNode>> input) -> QList<std::shared_ptr<const ast_basic::ExprNode>> {
QList<std::shared_ptr<const ast_basic::ExprNode>> temp;
if (input.size()) {
auto item = std::dynamic_pointer_cast<const ast_basic::ExprNode>(input.first());
temp << item;
temp.append(summary(input.mid(1)));
}
return temp;
};
time_stamp = QTime::currentTime();
auto tree_visit = std::make_shared<example_novel::NovelExprsVisitor>();
auto vinst = std::make_shared<ast_gen::ExprTreeParser>(tree_visit);
auto resultx = vinst->parse("test", summary(forst_root));
auto novel_accesstree = vinst->tidy(resultx);
QList<std::shared_ptr<ast_gen::SyntaxElement>> docs_node;
for (auto &it : forst_root) {
auto xitem = std::dynamic_pointer_cast<const ast_gen::SyntaxElement>(it);
docs_node.append(std::const_pointer_cast<ast_gen::SyntaxElement>(xitem));
context->addChild(docs_node.last());
}
auto x_root = NovalSyntax::tidy(context, docs_node);
auto novel_accesstree = std::make_shared<ast_gen::ElementAccess>(x_root);
current_stamp = QTime::currentTime();
qDebug() << QString(u8"程序结构重建消耗时间:%1 ms。").arg(time_stamp.msecsTo(current_stamp));

View File

@ -8,7 +8,7 @@
class NovelParser
{
private:
std::shared_ptr<const lib_syntax::ExprRule> syntax_defines;
std::shared_ptr<const lib_syntax::ExpressionRule> syntax_defines;
QList<std::shared_ptr<const lib_parse::CheckProvider>> checker_list;
std::shared_ptr<const lib_parse::Analyzer> analyzer_ref;

View File

@ -4,65 +4,71 @@ using namespace ast_basic;
using namespace lib_token;
using namespace lib_syntax;
TokenNodeImpl::TokenNodeImpl(std::shared_ptr<const Token> word) : word_store(word) {}
ExpressionElement::ExpressionElement(std::shared_ptr<const lib_syntax::ExpressionRule> bind) : _expr_rule(bind) {}
QString TokenNodeImpl::filePath() const
std::shared_ptr<const lib_syntax::ExpressionRule> ast_basic::ExpressionElement::definedRule() const {
return _expr_rule;
}
QString ast_basic::ExpressionElement::filePath() const {
if(tokens_bind.size())
throw new SyntaxException(u8"InternalError[0x0002]Ò»¸ö¿ÕµÄ·Ç·¨ÎÞЧ½Úµã");
return tokens_bind.first()->file();
}
void ast_basic::ExpressionElement::tokensReset(const QList<std::shared_ptr<const lib_token::Token>>& list) {
this->tokens_bind = list;
}
void ast_basic::ExpressionElement::addToken(std::shared_ptr<const lib_token::Token> token_inst) {
this->tokens_bind.append(token_inst);
}
QList<std::shared_ptr<const Expression>> ast_basic::ExpressionElement::children() const {
return this->children_store;
}
void ast_basic::ExpressionElement::addChild(std::shared_ptr<const Expression> inst) {
this->children_store.append(inst);
}
QList<std::shared_ptr<const Token>> ExpressionElement::tokens() const {
return this->tokens_bind;
}
std::shared_ptr<ast_basic::Expression> ast_basic::ExpressionContext::currentInst() const
{
return word_store->file();
if(expression_stack.size())
return expression_stack.last();
return nullptr;
}
bool TokenNodeImpl::isLeaf() const { return true; }
QList<std::shared_ptr<const Token>> TokenNodeImpl::tokens() const { return QList<std::shared_ptr<const lib_token::Token>>() << word_store; }
std::shared_ptr<const TokenNode> TokenNodeImpl::filledWith(const QList<std::shared_ptr<const TokenNode>>& tokens) const {
Q_UNUSED(tokens);
throw new lib_syntax::SyntaxException(u8"InternalError[0x0001]不能对TokenNode调用filledWith");
}
ExprNodeImpl::ExprNodeImpl(std::shared_ptr<const lib_syntax::ExprRule> bind) : _expr_rule(bind) {}
QString ExprNodeImpl::filePath() const
void ast_basic::ExpressionContext::pushInst(std::shared_ptr<ast_basic::Expression> current_inst)
{
auto toks = tokens();
if (toks.size())
return toks.first()->file();
auto exprs = exprNodes();
if (exprs.size())
return exprs.first()->filePath();
throw new SyntaxException(u8"InternalError[0x0002]一个空的非法无效节点");
if(!expression_stack.size() || expression_stack.last() != current_inst)
expression_stack.append(current_inst);
}
bool ExprNodeImpl::isLeaf() const { return false; }
std::shared_ptr<const ExprRule> ExprNodeImpl::defined() const { return this->_expr_rule; }
QList<std::shared_ptr<const ExprNode>> ExprNodeImpl::exprNodes() const {
QList<std::shared_ptr<const ExprNode>> listret;
for (auto& it : children_store)
if (!it->isLeaf())
listret.append(std::dynamic_pointer_cast<const ExprNode>(it));
return listret;
}
QList<std::shared_ptr<const TokenNode> > ExprNodeImpl::childTokensMid(int index, int length) const
std::shared_ptr<ast_basic::Expression> ast_basic::ExpressionContext::popInst()
{
if (index >= 0 && length > 0 && index + length <= children_store.size())
return children_store.mid(index, length);
return QList<std::shared_ptr<const TokenNode>>();
auto lastx = expression_stack.takeLast();
return lastx;
}
QList<std::shared_ptr<const Token>> ExprNodeImpl::tokens() const {
QList<std::shared_ptr<const lib_token::Token>> retlist;
for (auto& it : children_store)
retlist.append(it->tokens());
return retlist;
std::shared_ptr<const lib_syntax::BaseRule> ast_basic::ExpressionContext::currentExpressionRule() const {
if(rule_stack.size())
return rule_stack.last();
return nullptr;
}
std::shared_ptr<const TokenNode> ExprNodeImpl::filledWith(const QList<std::shared_ptr<const TokenNode>>& child_nodes) const {
auto vinst = std::make_shared<ExprNodeImpl>(this->_expr_rule);
vinst->children_store.append(child_nodes);
return vinst;
void ast_basic::ExpressionContext::pushExpressionRule(std::shared_ptr<const lib_syntax::BaseRule> inst) {
if(!rule_stack.size() || rule_stack.last() != inst)
rule_stack.append(inst);
}
std::shared_ptr<const lib_syntax::BaseRule> ast_basic::ExpressionContext::popExpressionRule()
{
return rule_stack.takeLast();
}

View File

@ -7,105 +7,102 @@
namespace ast_basic {
// 抽象语法树 ================================================================================================
/**
* @brief //
*/
class TokenNode {
public:
/**
* @brief
* @return
*/
virtual QString filePath() const = 0;
/**
* @brief
* @return
*/
virtual bool isLeaf() const = 0;
/**
* @brief Token集合
* @return
*/
virtual QList<std::shared_ptr<const lib_token::Token>> tokens() const = 0;
/**
* @brief
* @param tokens
* @return
*/
virtual std::shared_ptr<const TokenNode> filledWith(const QList<std::shared_ptr<const TokenNode>>& child_nodes) const = 0;
};
/**
* @brief /
*/
class ExprNode : public TokenNode {
class Expression {
public:
virtual ~Expression() = default;
/**
* @brief
* @brief
* @return
*/
virtual std::shared_ptr<const lib_syntax::ExprRule> defined() const = 0;
/**
* @brief
* @return
*/
virtual QList<std::shared_ptr<const ExprNode>> exprNodes() const = 0;
virtual std::shared_ptr<const lib_syntax::ExpressionRule> definedRule() const = 0;
//=====================================================
/**
* @brief TokenNode
* @param index 0
* @param length
* .
*
* \return
*/
virtual QString filePath() const = 0;
/**
* token序列.
*
* \return token序列
*/
virtual QList<std::shared_ptr<const lib_token::Token>> tokens() const = 0;
virtual void tokensReset(const QList<std::shared_ptr<const lib_token::Token>> &list) = 0;
/**
* token实例.
*
* \param token_inst
*/
virtual void addToken(std::shared_ptr<const lib_token::Token> token_inst) = 0;
//=====================================================
/**
* @brief
* @return
*/
virtual QList<std::shared_ptr<const TokenNode>> childTokensMid(int index, int length = 1) const = 0;
virtual QList<std::shared_ptr<const Expression>> children() const = 0;
/**
* @brief .
*
* \param inst
*/
virtual void addChild(std::shared_ptr<const Expression> inst) = 0;
};
// 基础语法树构成 ==========================================================================================
/**
* @brief
*/
class LIBSYNTAX_EXPORT TokenNodeImpl : public ast_basic::TokenNode {
private:
std::shared_ptr<const lib_token::Token> word_store;
public:
TokenNodeImpl(std::shared_ptr<const lib_token::Token> word);
// TokenNode interface
public:
virtual QString filePath() const override;
virtual bool isLeaf() const override;
virtual QList<std::shared_ptr<const lib_token::Token>> tokens() const override;
virtual std::shared_ptr<const TokenNode> filledWith(const QList<std::shared_ptr<const TokenNode> >& tokens) const override;
};
/**
* @brief
*/
class LIBSYNTAX_EXPORT ExprNodeImpl : public ast_basic::ExprNode {
class LIBSYNTAX_EXPORT ExpressionElement : public ast_basic::Expression,
public std::enable_shared_from_this<ExpressionElement> {
private:
std::shared_ptr<const lib_syntax::ExprRule> _expr_rule;
QList<std::shared_ptr<const TokenNode>> children_store;
std::shared_ptr<const lib_syntax::ExpressionRule> _expr_rule;
QList<std::shared_ptr<const Expression>> children_store;
QList<std::shared_ptr<const lib_token::Token>> tokens_bind;
public:
ExprNodeImpl(std::shared_ptr<const lib_syntax::ExprRule> bind);
ExpressionElement(std::shared_ptr<const lib_syntax::ExpressionRule> bind);
// TokenNode interface
public:
virtual QString filePath() const override;
virtual bool isLeaf() const override;
virtual QList<std::shared_ptr<const lib_token::Token>> tokens() const override;
virtual std::shared_ptr<const TokenNode> filledWith(const QList<std::shared_ptr<const TokenNode> >& child_nodes) const override;
// 通过 Expression 继承
std::shared_ptr<const lib_syntax::ExpressionRule> definedRule() const override;
QString filePath() const override;
QList<std::shared_ptr<const lib_token::Token>> tokens() const override;
void tokensReset(const QList<std::shared_ptr<const lib_token::Token>>& list) override;
void addToken(std::shared_ptr<const lib_token::Token> token_inst) override;
QList<std::shared_ptr<const Expression>> children() const override;
void addChild(std::shared_ptr<const Expression> inst) override;
};
class LIBSYNTAX_EXPORT ExpressionContext : public lib_syntax::ParseContext, public std::enable_shared_from_this<ExpressionContext> {
private:
QList<std::shared_ptr<const lib_syntax::BaseRule>> rule_stack;
QList<std::shared_ptr<Expression>> expression_stack;
// ExprNode interface
public:
virtual std::shared_ptr<const lib_syntax::ExprRule> defined() const override;
virtual QList<std::shared_ptr<const ExprNode>> exprNodes() const override;
virtual QList<std::shared_ptr<const TokenNode> > childTokensMid(int index, int length) const override;
ExpressionContext(){}
// 通过 ParseContext 继承
std::shared_ptr<ast_basic::Expression> currentInst() const override;
void pushInst(std::shared_ptr<ast_basic::Expression> current_inst) override;
std::shared_ptr<ast_basic::Expression> popInst() override;
std::shared_ptr<const lib_syntax::BaseRule> currentExpressionRule() const override;
void pushExpressionRule(std::shared_ptr<const lib_syntax::BaseRule> inst) override;
std::shared_ptr<const lib_syntax::BaseRule> popExpressionRule() override;
};
}

View File

@ -2,105 +2,27 @@
using namespace ast_gen;
ExprTreeParser::ExprTreeParser(std::shared_ptr<const ExprVisitor> vistor) : visitor_store(vistor) {}
GlobalElement* GlobalElement::UniquePtr = nullptr;
typedef std::shared_ptr<const SyntaxElement> E;
typedef QList<std::shared_ptr<const SyntaxElement>> Es;
typedef std::shared_ptr<const ast_basic::ExprNode> Expr;
QList<std::shared_ptr<const SyntaxElement>> ExprTreeParser::parse(const QString& name,
const QList<std::shared_ptr<const ast_basic::ExprNode>>& forest) const {
std::function<Es(Expr, E)> visit_loop = [&](Expr n, E p) -> Es {
QList<std::shared_ptr<const SyntaxElement>> temp_list;
auto node = this->visitor_store->visit(n, p);
if (node)
temp_list.append(node);
for (auto& it : n->exprNodes()) {
temp_list.append(visit_loop(it, node));
}
return temp_list;
};
QList<std::shared_ptr<const SyntaxElement>> temp_list;
auto root = std::make_shared<GlobalElement>(name);
temp_list << root;
for (auto& tree : forest) {
temp_list.append(visit_loop(tree, root));
}
return temp_list;
GlobalElement::GlobalElement(const QString& name) :names_store(name) {
UniquePtr = this;
}
std::shared_ptr<const ElementAccess> ExprTreeParser::tidy(const QList<std::shared_ptr<const SyntaxElement>>& nodes) const {
auto temp = nodes.first();
while (temp->parent()) {
temp = temp->parent();
}
auto core_cache = std::static_pointer_cast<GlobalElement>(std::const_pointer_cast<SyntaxElement>(temp));
core_cache->clearCache();
for (auto& it : nodes) {
if (!it->isAnonymous()) {
core_cache->appendToCache(it);
}
}
auto root = std::make_shared<ElementAccess>(temp);
for (auto& node : nodes)
tidy_branch(root, node);
return root;
}
void ExprTreeParser::tidy_branch(std::shared_ptr<ElementAccess> root, std::shared_ptr<const SyntaxElement> node) const {
QList<std::shared_ptr<const SyntaxElement>> link;
while (node) {
link.prepend(node);
node = node->parent();
}
std::function<void(std::shared_ptr<ElementAccess> pnode, QList<std::shared_ptr<const SyntaxElement>>)> merge =
[&](std::shared_ptr<ElementAccess> pnode, QList<std::shared_ptr<const SyntaxElement>> remains) {
if (!remains.size())
return;
auto current = remains.first();
for (auto& c_a : pnode->children()) {
if (c_a->element() == current) {
merge(std::const_pointer_cast<ElementAccess>(c_a), remains.mid(1));
return;
}
}
auto new_branch = std::make_shared<ElementAccess>(current);
pnode->appendChild(new_branch);
if (remains.size() > 1)
merge(new_branch, remains.mid(1));
};
merge(root, link.mid(1));
}
GlobalElement::GlobalElement(const QString& name) :names_store(name) {}
void GlobalElement::clearCache() { node_cache.clear(); }
void GlobalElement::appendToCache(std::shared_ptr<const SyntaxElement> named_node) {
auto mixed_key = QString(u8"%1<%2>").arg(named_node->signature()).arg(named_node->typeMark());
if (node_cache.contains(mixed_key))
throw new lib_syntax::SyntaxException(
QString(u8"Parse[0x0004]系统中包含同类型重名命名节点:%1<type%2>").arg(named_node->signature()).arg(named_node->typeMark()));
node_cache[mixed_key] = named_node;
auto mixed_key = QString(u8"%1<%2>").arg(named_node->signature()).arg(named_node->typeMark());
if (node_cache.contains(mixed_key))
throw new lib_syntax::SyntaxException(
QString(u8"Parse[0x0004]系统中包含同类型重名命名节点:%1<type%2>").arg(named_node->signature()).arg(named_node->typeMark()));
node_cache[mixed_key] = named_node;
}
std::shared_ptr<const SyntaxElement> GlobalElement::getNamedNodeBy(int type, const QString& signature) const {
auto mixed_key = QString(u8"%1<%2>").arg(signature).arg(type);
if (!node_cache.contains(mixed_key))
throw new lib_syntax::SyntaxException(QString(u8"Parse[0x0005]系统中不包含指定签名的节点:%1<type%2>").arg(signature).arg(type));
return node_cache[mixed_key];
auto mixed_key = QString(u8"%1<%2>").arg(signature).arg(type);
if (!node_cache.contains(mixed_key))
throw new lib_syntax::SyntaxException(QString(u8"Parse[0x0005]系统中不包含指定签名的节点:%1<type%2>").arg(signature).arg(type));
return node_cache[mixed_key];
}
int GlobalElement::typeMark() const { return 0; }
@ -113,28 +35,42 @@ QString GlobalElement::path() const { return u8""; }
std::shared_ptr<const SyntaxElement> GlobalElement::parent() const { return nullptr; }
void ast_gen::GlobalElement::setParent(std::shared_ptr<const SyntaxElement> inst) {}
QList<std::shared_ptr<const TokenAccess>> GlobalElement::selfTokens() const { return QList<std::shared_ptr<const TokenAccess>>(); }
std::shared_ptr<const ast_basic::Expression> ast_gen::GlobalElement::bindExpression() const
{
return bind_exprs;
}
void GlobalElement::addChild(std::shared_ptr<ast_gen::SyntaxElement> citem) {
auto convx = std::dynamic_pointer_cast<ast_basic::Expression>(citem);
bind_exprs->addChild(convx);
}
ElementAccess::ElementAccess(std::shared_ptr<const SyntaxElement> point) { peers = point; }
std::shared_ptr<const SyntaxElement> ElementAccess::element() const { return peers; }
QList<std::shared_ptr<const ElementAccess>> ElementAccess::children() const { return children_store; }
QList<std::shared_ptr<const ElementAccess>> ElementAccess::children() const {
auto expression_inst = element()->bindExpression();
auto children = expression_inst->children();
void ElementAccess::appendChild(std::shared_ptr<const ElementAccess> inst) { children_store.append(inst); }
QList<std::shared_ptr<const ElementAccess>> retvalues;
for (auto item : children) {
auto elem_inst = std::dynamic_pointer_cast<const SyntaxElement>(item);
retvalues.append(std::make_shared<ElementAccess>(elem_inst));
}
return retvalues;
}
QList<std::shared_ptr<const TokenAccess>> ElementAccess::tokens() const {
QList<std::shared_ptr<const TokenAccess>> tokens_retv;
tokens_retv.append(element()->selfTokens());
for (auto& it : children()) {
tokens_retv.append(it->tokens());
}
return tokens_retv;
return element()->selfTokens();
}
TokenAccess::TokenAccess(std::shared_ptr<const SyntaxElement> elm_inst, std::shared_ptr<const lib_token::Token> token_inst)
: element_bind(elm_inst), token_store(token_inst) {}
: element_bind(elm_inst), token_store(token_inst) {}
std::shared_ptr<const SyntaxElement> TokenAccess::bind() const { return element_bind; }

View File

@ -15,6 +15,14 @@ namespace ast_gen
*/
class SyntaxElement {
public:
virtual ~SyntaxElement() = default;
/**
* .
*
* \return
*/
virtual std::shared_ptr<const ast_basic::Expression> bindExpression() const = 0;
/**
* @brief
* @return
@ -42,9 +50,10 @@ namespace ast_gen
/**
* @brief
* @return
* @return parentnullptr
*/
virtual std::shared_ptr<const SyntaxElement> parent() const = 0;
virtual void setParent(std::shared_ptr<const SyntaxElement> inst) = 0;
/**
* @brief Token集合
@ -59,7 +68,6 @@ namespace ast_gen
class LIBSYNTAX_EXPORT ElementAccess {
private:
std::shared_ptr<const SyntaxElement> peers;
QList<std::shared_ptr<const ElementAccess>> children_store;
public:
ElementAccess(std::shared_ptr<const SyntaxElement> point);
@ -67,8 +75,6 @@ namespace ast_gen
std::shared_ptr<const SyntaxElement> element() const;
QList<std::shared_ptr<const ElementAccess>> children() const;
void appendChild(std::shared_ptr<const ElementAccess> inst);
/**
* @brief Token定义
@ -91,13 +97,15 @@ namespace ast_gen
/**
* @brief
*/
class LIBSYNTAX_EXPORT GlobalElement : public SyntaxElement {
class LIBSYNTAX_EXPORT GlobalElement : public SyntaxElement, public ast_basic::ExpressionContext {
private:
QList<std::shared_ptr<const SyntaxElement>> children_store;
QString names_store;
QHash<QString, std::shared_ptr<const SyntaxElement>> node_cache;
std::shared_ptr<ast_basic::Expression> bind_exprs = std::make_shared<ast_basic::ExpressionElement>(nullptr);
public:
static GlobalElement* UniquePtr;
GlobalElement(const QString& name);
virtual void clearCache();
@ -110,6 +118,8 @@ namespace ast_gen
*/
virtual std::shared_ptr<const ast_gen::SyntaxElement> getNamedNodeBy(int type, const QString& signature) const;
virtual void addChild(std::shared_ptr<ast_gen::SyntaxElement> citem);
// ParseElement interface
public:
virtual int typeMark() const override;
@ -117,47 +127,10 @@ namespace ast_gen
virtual QString signature() const override;
virtual QString path() const override;
virtual std::shared_ptr<const SyntaxElement> parent() const override;
virtual void setParent(std::shared_ptr<const SyntaxElement> inst) override;
virtual QList<std::shared_ptr<const TokenAccess>> selfTokens() const override;
};
/**
* @brief 访
*/
class ExprVisitor {
public:
/**
* @brief
* @param expr
* @param pnode
* @return
*/
virtual std::shared_ptr<const SyntaxElement> visit(std::shared_ptr<const ast_basic::ExprNode> expr, std::shared_ptr<const SyntaxElement> pnode) const = 0;
};
/**
* @brief
*/
class LIBSYNTAX_EXPORT ExprTreeParser {
private:
std::shared_ptr<const ExprVisitor> visitor_store;
void tidy_branch(std::shared_ptr<ElementAccess> root, std::shared_ptr<const SyntaxElement> node) const;
public:
ExprTreeParser(std::shared_ptr<const ExprVisitor> vistor);
/**
* @brief
* @param name
* @param forest
* @return
*/
QList<std::shared_ptr<const SyntaxElement>> parse(const QString& name, const QList<std::shared_ptr<const ast_basic::ExprNode>>& forest) const;
/**
* @brief 访
* @param nodes
* @return
*/
std::shared_ptr<const ElementAccess> tidy(const QList<std::shared_ptr<const SyntaxElement>>& nodes) const;
// 通过 SyntaxElement 继承
std::shared_ptr<const ast_basic::Expression> bindExpression() const override;
};
}

View File

@ -3,245 +3,151 @@
using namespace example_novel;
TextSection::TextSection(const QString& text, const QString path, std::shared_ptr<const SyntaxElement> parent)
: content_store(text), file_path(path), pnode_store(parent) {}
TextSection::TextSection(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
: AbstractImpl(rule_bind) {}
QString example_novel::TextSection::content() const
{
return this->content_store;
QString text;
for (auto& t : selfTokens()) {
text += t->token()->content() + " ";
}
return text;
}
int TextSection::typeMark() const { return (int)NovelNode::TextSection; }
bool example_novel::TextSection::isAnonymous() const
{
return true;
return true;
}
QString TextSection::path() const { return file_path; }
QString TextSection::signature() const { return u8"::section"; }
std::shared_ptr<const ast_gen::SyntaxElement> TextSection::parent() const { return pnode_store; }
FragmentRefers::FragmentRefers(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
: AbstractImpl(rule_bind) {}
QList<std::shared_ptr<const ast_gen::TokenAccess> > TextSection::selfTokens() const {
return TokenSL::selfTokens();
}
QString FragmentRefers::storyRefer() const { return selfTokens()[5]->token()->content(); }
FragmentRefers::FragmentRefers(const QString& story, const QString& fragment, const QString& path, std::shared_ptr<const SyntaxElement> parent)
: story_ref(story), fragm_ref(fragment), path_store(path), pnode_store(parent) {}
QString FragmentRefers::storyRefer() const { return story_ref; }
QString FragmentRefers::fragmentRefer() const { return fragm_ref; }
QString FragmentRefers::fragmentRefer() const { return selfTokens()[3]->token()->content(); }
QString FragmentRefers::referSignature() const {
return story_ref + u8"&" + fragm_ref;
return storyRefer() + u8"&" + fragmentRefer();
}
int FragmentRefers::typeMark() const { return (int)NovelNode::FragmentRefer; }
bool example_novel::FragmentRefers::isAnonymous() const
{
return true;
return true;
}
QString FragmentRefers::path() const { return path_store; }
QString FragmentRefers::signature() const {
QString signature = u8"@" + storyRefer() + u8"&" + fragmentRefer();
return parent()->signature() + signature;
QString signature = u8"@" + storyRefer() + u8"&" + fragmentRefer();
return parent()->signature() + signature;
}
std::shared_ptr<const ast_gen::SyntaxElement> FragmentRefers::parent() const { return pnode_store; }
FragmentDefine::FragmentDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
: AbstractImpl(rule_bind) {}
QList<std::shared_ptr<const ast_gen::TokenAccess> > FragmentRefers::selfTokens() const {
return TokenSL::selfTokens();
}
FragmentDefine::FragmentDefine(const QString& name, const QString& path, std::shared_ptr<const SyntaxElement> parent)
: name_store(name), path_store(path), pnode_store(parent) {}
QString FragmentDefine::name() const { return name_store; }
QString FragmentDefine::name() const { return selfTokens()[2]->token()->content(); }
int FragmentDefine::typeMark() const { return (int)NovelNode::FragmentDefine; }
bool example_novel::FragmentDefine::isAnonymous() const
{
return false;
return false;
}
QString FragmentDefine::path() const { return path_store; }
QString FragmentDefine::signature() const { return parent()->signature() + u8"&" + name(); }
std::shared_ptr<const ast_gen::SyntaxElement> FragmentDefine::parent() const { return pnode_store; }
StoryDefine::StoryDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
: AbstractImpl(rule_bind) {}
QList<std::shared_ptr<const ast_gen::TokenAccess> > FragmentDefine::selfTokens() const {
return TokenSL::selfTokens();
}
QString StoryDefine::name() const { return selfTokens()[3]->token()->content(); }
StoryDefine::StoryDefine(const QString name, int sort, const QString path, std::shared_ptr<const SyntaxElement> parent)
: name_store(name), sort_index(sort), path_store(path), pnode_store(parent) {}
QString StoryDefine::name() const { return name_store; }
int StoryDefine::sort() const { return sort_index; }
int StoryDefine::sort() const { return selfTokens()[2]->token()->content().toInt(); }
int StoryDefine::typeMark() const { return (int)NovelNode::StoryDefine; }
bool example_novel::StoryDefine::isAnonymous() const
{
return false;
return false;
}
QString StoryDefine::path() const { return path_store; }
QString StoryDefine::signature() const { return name_store; }
std::shared_ptr<const ast_gen::SyntaxElement> StoryDefine::parent() const { return pnode_store; }
QList<std::shared_ptr<const ast_gen::TokenAccess> > StoryDefine::selfTokens() const {
return TokenSL::selfTokens();
}
QString StoryDefine::signature() const { return name(); }
#include "syntax_novel.h"
std::shared_ptr<const ast_gen::SyntaxElement> NovelExprsVisitor::visit(std::shared_ptr<const ast_basic::ExprNode> expr, std::shared_ptr<const ast_gen::SyntaxElement> pnode) const
{
auto tidy_tokens = [&](std::shared_ptr<const ast_basic::ExprNode> expr) {
auto vtokens = expr->tokens();
for (auto& cld : expr->exprNodes()) {
auto remove_tokens = cld->tokens();
for (auto& rit : remove_tokens)
vtokens.removeAll(rit);
}
return vtokens;
};
switch (expr->defined()->typeMark()) {
case example_novel::NovelExprs::DOC_DEFINES:
return std::make_shared<Document>(expr->filePath(), pnode);
case example_novel::NovelExprs::STORY_DEFINES: {
auto name = expr->tokens().at(3)->content();
auto sort = expr->tokens().at(2)->content().toInt();
auto rinst = std::make_shared<StoryDefine>(name, sort, expr->filePath(), pnode);
rinst->appendDefinedTokens(rinst, tidy_tokens(expr));
return rinst;
}
case example_novel::NovelExprs::FRAG_DEFINES: {
auto name = expr->tokens().at(2)->content();
auto inst = std::make_shared<FragmentDefine>(name, expr->filePath(), pnode);
inst->appendDefinedTokens(inst, tidy_tokens(expr));
return inst;
}
case example_novel::NovelExprs::FRAG_REFERS: {
auto fragm_ref = expr->tokens().at(3)->content();
auto story_ref = expr->tokens().at(5)->content();
auto inst = std::make_shared<FragmentRefers>(story_ref, fragm_ref, expr->filePath(), pnode);
inst->appendDefinedTokens(inst, tidy_tokens(expr));
return inst;
}
case example_novel::NovelExprs::DESC_SECTION:
{
QString content = u8"";
for (auto& t : expr->tokens())
content += t->content();
auto inst = std::make_shared<TextSection>(content, expr->filePath(), pnode);
inst->appendDefinedTokens(inst, tidy_tokens(expr));
return inst;
}
case example_novel::NovelExprs::ARTICLE_DEFINE:
{
auto name = expr->tokens().at(2)->content();
auto inst = std::make_shared<ArticleDefine>(name, expr->filePath(), pnode);
inst->appendDefinedTokens(inst, tidy_tokens(expr));
return inst;
}
case example_novel::NovelExprs::VOLUME_DEFINE:
{
auto name = expr->tokens().at(2)->content();
auto inst = std::make_shared<VolumeDefine>(name, expr->filePath(), pnode);
inst->appendDefinedTokens(inst, tidy_tokens(expr));
return inst;
}
default:
throw new lib_syntax::SyntaxException(u8"InternalError[0x0003]ÀàÐÍÆ¥Åä´íÎó");
}
}
Document::Document(const QString& path, std::shared_ptr<const SyntaxElement> pnode)
: path_store(path), pnode_store(pnode) {}
Document::Document(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
: AbstractImpl(rule_bind) {}
int Document::typeMark() const { return (int)NovelNode::Document; }
bool example_novel::Document::isAnonymous() const
{
return true;
return true;
}
QString Document::path() const { return path_store; }
QString Document::signature() const { return QString(u8"::document<%1>").arg(path()); }
std::shared_ptr<const ast_gen::SyntaxElement> Document::parent() const { return pnode_store; }
example_novel::AbstractImpl::AbstractImpl(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
: ExpressionElement(rule_bind) {}
QList<std::shared_ptr<const ast_gen::TokenAccess> > Document::selfTokens() const
QList<std::shared_ptr<const ast_gen::TokenAccess> > AbstractImpl::selfTokens() const {
auto tokensx = ast_basic::ExpressionElement::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;
}
std::shared_ptr<const ast_gen::SyntaxElement> example_novel::AbstractImpl::parent() const
{
return QList<std::shared_ptr<const ast_gen::TokenAccess>>();
return this->parent_store;
}
void TokenSL::appendDefinedTokens(std::shared_ptr<const ast_gen::SyntaxElement> elm, QList<std::shared_ptr<const lib_token::Token>> tokens) {
QList<std::shared_ptr<const ast_gen::TokenAccess>> access;
for (auto& t : tokens)
this->tokens_store << std::make_shared<ast_gen::TokenAccess>(elm, t);
void example_novel::AbstractImpl::setParent(std::shared_ptr<const ast_gen::SyntaxElement> inst)
{
this->parent_store = inst;
}
QList<std::shared_ptr<const ast_gen::TokenAccess> > TokenSL::selfTokens() const {
return tokens_store;
// ͨ¹ý SyntaxElement ¼Ì³Ð
std::shared_ptr<const ast_basic::Expression> example_novel::AbstractImpl::bindExpression() const {
return shared_from_this();
}
VolumeDefine::VolumeDefine(const QString& name, const QString& path, std::shared_ptr<const SyntaxElement> parent)
: name_store(name), path_store(path), pnode_store(parent) {}
QString example_novel::AbstractImpl::path() const
{
return ast_basic::ExpressionElement::filePath();
}
QString VolumeDefine::name() const { return name_store; }
VolumeDefine::VolumeDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
: AbstractImpl(rule_bind) {}
QString VolumeDefine::name() const { return selfTokens()[2]->token()->content(); }
int VolumeDefine::typeMark() const { return (int)NovelNode::VolumeDefine; }
bool example_novel::VolumeDefine::isAnonymous() const
{
return false;
return false;
}
QString VolumeDefine::path() const { return path_store; }
QString VolumeDefine::signature() const { return name(); }
std::shared_ptr<const ast_gen::SyntaxElement> VolumeDefine::parent() const { return pnode_store; }
ArticleDefine::ArticleDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
: AbstractImpl(rule_bind) {}
QList<std::shared_ptr<const ast_gen::TokenAccess> > VolumeDefine::selfTokens() const {
return TokenSL::selfTokens();
}
ArticleDefine::ArticleDefine(const QString& name, const QString& path, std::shared_ptr<const SyntaxElement> parent)
: name_store(name), path_store(path), pnode_store(parent) {}
QString ArticleDefine::name() const { return name_store; }
QString ArticleDefine::name() const { return selfTokens()[2]->token()->content(); }
int ArticleDefine::typeMark() const { return (int)NovelNode::ArticleDefine; }
bool example_novel::ArticleDefine::isAnonymous() const
{
return false;
return false;
}
QString ArticleDefine::path() const { return path_store; }
QString ArticleDefine::signature() const { return parent()->signature() + u8"&" + name(); }
std::shared_ptr<const ast_gen::SyntaxElement> ArticleDefine::parent() const { return pnode_store; }
QList<std::shared_ptr<const ast_gen::TokenAccess> > ArticleDefine::selfTokens() const {
return TokenSL::selfTokens();
}

View File

@ -14,24 +14,26 @@ namespace example_novel
VolumeDefine = 7,
};
class LIBSYNTAX_EXPORT TokenSL {
class LIBSYNTAX_EXPORT AbstractImpl :
public ast_basic::ExpressionElement, public ast_gen::SyntaxElement {
private:
QList<std::shared_ptr<const ast_gen::TokenAccess>> tokens_store;
std::shared_ptr<const SyntaxElement> parent_store = nullptr;
public:
virtual void appendDefinedTokens(std::shared_ptr<const ast_gen::SyntaxElement> elm, QList<std::shared_ptr<const lib_token::Token> > tokens);
virtual QList<std::shared_ptr<const ast_gen::TokenAccess>> selfTokens() const;
explicit AbstractImpl(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind);
// ͨ¹ý SyntaxElement ¼Ì³Ð
virtual std::shared_ptr<const ast_basic::Expression> bindExpression() const override;
QString path() const override;
virtual std::shared_ptr<const ast_gen::SyntaxElement> parent() const override;
virtual void setParent(std::shared_ptr<const ast_gen::SyntaxElement> inst) override;
virtual QList<std::shared_ptr<const ast_gen::TokenAccess>> selfTokens() const override;
};
class LIBSYNTAX_EXPORT TextSection : public ast_gen::SyntaxElement, public TokenSL {
private:
QString content_store;
QString file_path;
std::shared_ptr<const SyntaxElement> pnode_store;
class LIBSYNTAX_EXPORT TextSection : public AbstractImpl {
public:
TextSection(const QString& text, const QString path, std::shared_ptr<const SyntaxElement> parent);
TextSection(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind);
QString content() const;
@ -39,21 +41,12 @@ namespace example_novel
public:
virtual int typeMark() const override;
virtual bool isAnonymous() const override;
virtual QString path() const override;
virtual QString signature() const override;
virtual std::shared_ptr<const ast_gen::SyntaxElement> parent() const override;
virtual QList<std::shared_ptr<const ast_gen::TokenAccess> > selfTokens() const override;
};
class LIBSYNTAX_EXPORT FragmentRefers : public ast_gen::SyntaxElement, public TokenSL {
private:
QString story_ref;
QString fragm_ref;
QString path_store;
std::shared_ptr<const SyntaxElement> pnode_store;
class LIBSYNTAX_EXPORT FragmentRefers : public AbstractImpl {
public:
FragmentRefers(const QString& story, const QString& fragment, const QString& path, std::shared_ptr<const SyntaxElement> parent);
FragmentRefers(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind);
QString storyRefer() const;
QString fragmentRefer() const;
@ -63,20 +56,12 @@ namespace example_novel
public:
virtual int typeMark() const override;
virtual bool isAnonymous() const override;
virtual QString path() const override;
virtual QString signature() const override;
virtual std::shared_ptr<const ast_gen::SyntaxElement> parent() const override;
virtual QList<std::shared_ptr<const ast_gen::TokenAccess> > selfTokens() const override;
};
class LIBSYNTAX_EXPORT FragmentDefine : public ast_gen::SyntaxElement, public TokenSL {
private:
QString name_store;
QString path_store;
std::shared_ptr<const SyntaxElement> pnode_store;
class LIBSYNTAX_EXPORT FragmentDefine : public AbstractImpl {
public:
FragmentDefine(const QString& name, const QString& path, std::shared_ptr<const SyntaxElement> parent);
FragmentDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind);
QString name() const;
@ -84,20 +69,12 @@ namespace example_novel
public:
virtual int typeMark() const override;
virtual bool isAnonymous() const override;
virtual QString path() const override;
virtual QString signature() const override;
virtual std::shared_ptr<const ast_gen::SyntaxElement> parent() const override;
virtual QList<std::shared_ptr<const ast_gen::TokenAccess> > selfTokens() const override;
};
class LIBSYNTAX_EXPORT ArticleDefine : public ast_gen::SyntaxElement, public TokenSL {
private:
QString name_store;
QString path_store;
std::shared_ptr<const SyntaxElement> pnode_store;
class LIBSYNTAX_EXPORT ArticleDefine : public AbstractImpl{
public:
ArticleDefine(const QString& name, const QString& path, std::shared_ptr<const SyntaxElement> parent);
ArticleDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind);
QString name() const;
@ -105,20 +82,12 @@ namespace example_novel
public:
virtual int typeMark() const override;
virtual bool isAnonymous() const override;
virtual QString path() const override;
virtual QString signature() const override;
virtual std::shared_ptr<const ast_gen::SyntaxElement> parent() const override;
virtual QList<std::shared_ptr<const ast_gen::TokenAccess> > selfTokens() const override;
};
class LIBSYNTAX_EXPORT VolumeDefine : public ast_gen::SyntaxElement, public TokenSL {
private:
QString name_store;
QString path_store;
std::shared_ptr<const SyntaxElement> pnode_store;
class LIBSYNTAX_EXPORT VolumeDefine : public AbstractImpl {
public:
VolumeDefine(const QString& name, const QString& path, std::shared_ptr<const SyntaxElement> parent);
VolumeDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind);
QString name() const;
@ -126,58 +95,31 @@ namespace example_novel
public:
virtual int typeMark() const override;
virtual bool isAnonymous() const override;
virtual QString path() const override;
virtual QString signature() const override;
virtual std::shared_ptr<const ast_gen::SyntaxElement> parent() const override;
virtual QList<std::shared_ptr<const ast_gen::TokenAccess> > selfTokens() const override;
};
class LIBSYNTAX_EXPORT StoryDefine : public ast_gen::SyntaxElement, public TokenSL {
private:
QString name_store;
int sort_index;
QString path_store;
std::shared_ptr<const SyntaxElement> pnode_store;
class LIBSYNTAX_EXPORT StoryDefine : public AbstractImpl {
public:
StoryDefine(const QString name, int sort, const QString path, std::shared_ptr<const SyntaxElement> parent);
StoryDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind);
QString name() const;
int sort() const;
// SyntaxElement interface
public:
virtual int typeMark() const override;
virtual bool isAnonymous() const override;
virtual QString signature() const override;
};
class LIBSYNTAX_EXPORT Document : public AbstractImpl {
public:
Document(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind);
// SyntaxElement interface
public:
virtual int typeMark() const override;
virtual bool isAnonymous() const override;
virtual QString path() const override;
virtual QString signature() const override;
virtual std::shared_ptr<const ast_gen::SyntaxElement> parent() const override;
virtual QList<std::shared_ptr<const ast_gen::TokenAccess> > selfTokens() const override;
};
class LIBSYNTAX_EXPORT Document : public ast_gen::SyntaxElement {
private:
QString path_store;
std::shared_ptr<const ast_gen::SyntaxElement> pnode_store;
public:
Document(const QString& path, std::shared_ptr<const ast_gen::SyntaxElement> pnode);
// SyntaxElement interface
public:
virtual int typeMark() const override;
virtual bool isAnonymous() const override;
virtual QString path() const override;
virtual QString signature() const override;
virtual std::shared_ptr<const ast_gen::SyntaxElement> parent() const override;
virtual QList<std::shared_ptr<const ast_gen::TokenAccess>> selfTokens() const override;
};
class LIBSYNTAX_EXPORT NovelExprsVisitor : public ast_gen::ExprVisitor {
// ExprVisitor interface
public:
virtual std::shared_ptr<const ast_gen::SyntaxElement> visit(std::shared_ptr<const ast_basic::ExprNode> expr, std::shared_ptr<const ast_gen::SyntaxElement> pnode) const override;
};
}

View File

@ -19,20 +19,21 @@ std::tuple<BaseRule::MatchResult, uint> TokenMatch::match(const QList<std::share
return std::make_tuple(MatchResult::Fail, 0);
}
QList<std::shared_ptr<const TokenNode>> TokenMatch::parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
std::shared_ptr<const Expression> TokenMatch::parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
if (stream.size()) {
auto current = stream.first();
if (current->define()->name() == define_peer->name())
return QList<std::shared_ptr<const ast_basic::TokenNode>>() << std::make_shared<const TokenNodeImpl>(stream.first());
if (current->define()->name() == define_peer->name()){
rt_inst->currentInst()->addToken(current);
return nullptr;
}
throw new SyntaxException(
QString(u8"Syntax[0x00001]语法匹配错误不能识别token%1<%2,%3>").arg(current->content()).arg(current->row()).arg(current->column()));
throw new SyntaxException(QString(u8"Syntax[0x00001]语法匹配错误不能识别token%1<%2,%3>")
.arg(current->content()).arg(current->row()).arg(current->column()));
}
throw new SyntaxException(u8"Syntax[0x0000]tokenÁ÷ÌáǰÖÕÖ¹");
}
QString TokenMatch::token_present() const
{
QString TokenMatch::token_present() const {
return QString(u8"<%1>").arg(this->define_peer->name());
}
@ -70,15 +71,17 @@ std::tuple<BaseRule::MatchResult, uint> Rept::match(const QList<std::shared_ptr<
return std::make_tuple(MatchResult::Success, token_offset);
}
QList<std::shared_ptr<const TokenNode>> Rept::parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
QList<std::shared_ptr<const TokenNode>> list_retvs;
std::shared_ptr<const Expression> Rept::parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto token_offset = 0;
// min-match
for (auto idx = 0; idx < min_match; ++idx) {
auto result = rule_peer->match(stream.mid(token_offset));
list_retvs.append(rule_peer->parse(stream.mid(token_offset)));
auto result_gen = rule_peer->parse(rt_inst, stream.mid(token_offset));
if(result_gen)
rt_inst->currentInst()->addChild(result_gen);
token_offset += std::get<1>(result);
}
@ -89,16 +92,19 @@ QList<std::shared_ptr<const TokenNode>> Rept::parse(const QList<std::shared_ptr<
switch (std::get<0>(result)) {
case MatchResult::Fail:
case MatchResult::Part:
return list_retvs;
return nullptr;
default:
break;
}
list_retvs.append(rule_peer->parse(stream.mid(token_offset)));
auto result_gen = rule_peer->parse(rt_inst, stream.mid(token_offset));
if (result_gen)
rt_inst->currentInst()->addChild(result_gen);
token_offset += std::get<1>(result);
}
return list_retvs;
return nullptr;
}
QString Rept::token_present() const
@ -130,18 +136,18 @@ std::tuple<BaseRule::MatchResult, uint> Seqs::match(const QList<std::shared_ptr<
return std::make_tuple(MatchResult::Success, token_offset);
}
QList<std::shared_ptr<const TokenNode>> Seqs::parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
QList<std::shared_ptr<const TokenNode>> list_retv;
std::shared_ptr<const Expression> Seqs::parse(std::shared_ptr<ParseContext> rt_inst,const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto token_offset = 0;
for (auto& r : mbrs_store) {
list_retv.append(r->parse(stream.mid(token_offset)));
auto rst_gene = r->parse(rt_inst, stream.mid(token_offset));
if(rst_gene)
rt_inst->currentInst()->addChild(rst_gene);
auto result = r->match(stream.mid(token_offset));
token_offset += std::get<1>(result);
}
return list_retv;
return nullptr;
}
QString Seqs::token_present() const
@ -190,9 +196,9 @@ std::tuple<BaseRule::MatchResult, uint> Any::match(const QList<std::shared_ptr<c
return std::make_tuple(std::get<0>(item), std::get<1>(item));
}
QList<std::shared_ptr<const TokenNode>> Any::parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
std::shared_ptr<const Expression> Any::parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto temp = rule_select(stream);
return std::get<2>(temp)->parse(stream);
return std::get<2>(temp)->parse(rt_inst, stream);
}
QString Any::token_present() const
@ -204,48 +210,49 @@ QString Any::token_present() const
return u8"(" + members_content.mid(0, members_content.size() - 1) + u8")";
}
ExprRule::ExprRule(const QString& rule_name, int expr_mark) : name_store(rule_name) {
this->filter_proc = [](const TokenSeqs& seqs) { return seqs; };
this->mark_store = expr_mark;
}
std::shared_ptr<const ExprRule> ExprRule::reloadRule(std::function<TokenSeqs(const TokenSeqs&)> filter, std::shared_ptr<const BaseRule> rule) {
auto ninst = std::make_shared<ExprRule>(this->name(), this->typeMark());
ninst->child_store = rule;
ninst->filter_proc = filter;
return ninst;
}
QString ExprRule::name() const { return name_store; }
int ExprRule::typeMark() const { return this->mark_store; }
QList<std::shared_ptr<const BaseRule>> ExprRule::children() const { return QList<std::shared_ptr<const BaseRule>>() << this->child_store; }
std::tuple<BaseRule::MatchResult, uint> ExprRule::match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
return child_store->match(stream);
}
QList<std::shared_ptr<const TokenNode>> ExprRule::parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto primary_tokens = child_store->parse(stream);
auto remains_tokens = this->filter_proc(primary_tokens);
return QList<std::shared_ptr<const TokenNode>>() << ExprNodeImpl(shared_from_this()).filledWith(remains_tokens);
}
QString ExprRule::token_present() const
{
return QString(u8"(%1)").arg(child_store->token_present());
}
SyntaxException::SyntaxException(const QString& message) { this->msg_store = message; }
QString SyntaxException::message() const { return msg_store; }
ExprsChecker::ExprsChecker(std::shared_ptr<const ExprRule> parse_tree) : syntax_tree_root(parse_tree) {}
QList<std::shared_ptr<const TokenNode>> ExprsChecker::parseFrom(const QList<std::shared_ptr<const lib_token::Token>>& all_tokens) {
if (!all_tokens.size())
return QList<std::shared_ptr<const TokenNode>>();
return this->syntax_tree_root->parse(all_tokens);
lib_syntax::ExpressionRule::ExpressionRule(const QString& rule_name, int expr_mark) : name_store(rule_name) {
this->filter_proc = [](const TokenSeqs& seqs) { return seqs; };
this->mark_store = expr_mark;
}
std::shared_ptr<const ExpressionRule> lib_syntax::ExpressionRule::reloadRule(std::function<TokenSeqs(const TokenSeqs&)> filter, std::shared_ptr<const BaseRule> rule) {
auto ninst = makeCopy();
ninst->child_store = rule;
ninst->filter_proc = filter;
return ninst;
}
QString lib_syntax::ExpressionRule::name() const { return name_store; }
int lib_syntax::ExpressionRule::typeMark() const { return this->mark_store; }
QList<std::shared_ptr<const lib_syntax::BaseRule>> lib_syntax::ExpressionRule::children() const {
return QList<std::shared_ptr<const BaseRule>>() << this->child_store;
}
std::tuple<BaseRule::MatchResult, uint> lib_syntax::ExpressionRule::match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
return child_store->match(stream);
}
std::shared_ptr<const ast_basic::Expression> lib_syntax::ExpressionRule::parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
std::shared_ptr<ast_basic::Expression> elm_ast = this->newEmptyInstance();
rt_inst->pushExpressionRule(this->shared_from_this());
rt_inst->pushInst(elm_ast);
child_store->parse(rt_inst, stream);
auto tokens_decl = this->filter_proc(elm_ast->tokens());
elm_ast->tokensReset(tokens_decl);
rt_inst->popExpressionRule();
return rt_inst->popInst();
}
QString lib_syntax::ExpressionRule::token_present() const {
return QString(u8"(%1)").arg(child_store->token_present());
}

View File

@ -5,182 +5,215 @@
#include <memory>
#include <tuple>
#include <functional>
namespace ast_basic {
class TokenNode;
class ExprNode;
class Expression;
class ExpressionElement;
}
namespace lib_syntax {
/**
* @brief
*/
class SyntaxException {
private:
QString msg_store;
/**
* @brief
*/
class SyntaxException {
private:
QString msg_store;
public:
SyntaxException(const QString& message);
virtual ~SyntaxException() = default;
public:
SyntaxException(const QString& message);
virtual ~SyntaxException() = default;
virtual QString message() const;
};
virtual QString message() const;
};
// 基础语法解析接口 ===================================================================================================
/**
* @brief
*/
class BaseRule {
public:
/**
* @brief
* @return
*/
virtual QList<std::shared_ptr<const BaseRule>> children() const = 0;
/**
* @brief
*/
enum class MatchResult {
Success, // 符合匹配条件
Part, // 部分匹配
Fail // 从第一个词起完全不匹配
};
class BaseRule;
// 基础语法解析接口 ===================================================================================================
/**
* @brief
*/
class ParseContext {
public:
virtual ~ParseContext() = default;
/**
* @brief token流匹配
* @return token集合
*/
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const = 0;
/**
* \brief .
*
* \return
*/
virtual std::shared_ptr<ast_basic::Expression> currentInst() const = 0;
virtual void pushInst(std::shared_ptr<ast_basic::Expression> current_inst) = 0;
virtual std::shared_ptr<ast_basic::Expression> popInst() = 0;
/**
* @brief
* @param stream
* @return
*/
virtual QList<std::shared_ptr<const ast_basic::TokenNode>> parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const = 0;
virtual std::shared_ptr<const BaseRule> currentExpressionRule() const = 0;
virtual void pushExpressionRule(std::shared_ptr<const BaseRule> inst) = 0;
virtual std::shared_ptr<const BaseRule> popExpressionRule() = 0;
};
/**
*
*
* \return
*/
virtual QString token_present() const = 0;
};
/**
* @brief
*/
class BaseRule {
public:
virtual ~BaseRule() = default;
/**
* @brief
* @return
*/
virtual QList<std::shared_ptr<const BaseRule>> children() const = 0;
/**
* @brief token匹配
*/
class LIBSYNTAX_EXPORT TokenMatch : public BaseRule {
private:
std::shared_ptr<const lib_token::TokenDefine> define_peer;
/**
* @brief
*/
enum class MatchResult {
Success, // 符合匹配条件
Part, // 部分匹配
Fail // 从第一个词起完全不匹配
};
public:
TokenMatch(std::shared_ptr<const lib_token::TokenDefine> define);
/**
* @brief token流匹配
* @return token集合
*/
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const = 0;
// BaseRule interface
public:
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QList<std::shared_ptr<const ast_basic::TokenNode>> parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QString token_present() const override;
};
/**
* @brief
* @param stream
* @return
*/
virtual std::shared_ptr<const ast_basic::Expression> parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const = 0;
/**
* @brief
*/
class LIBSYNTAX_EXPORT Any : public BaseRule {
private:
QList<std::shared_ptr<const BaseRule>> mbrs_store;
/**
*
*
* \return
*/
virtual QString token_present() const = 0;
};
std::tuple<MatchResult, uint, std::shared_ptr<const BaseRule>> rule_select(const QList<std::shared_ptr<const lib_token::Token>>& stream) const;
public:
Any(const QList<std::shared_ptr<const BaseRule>> mbrs);
/**
* @brief token匹配
*/
class LIBSYNTAX_EXPORT TokenMatch : public BaseRule, public std::enable_shared_from_this<TokenMatch> {
private:
std::shared_ptr<const lib_token::TokenDefine> define_peer;
// BaseRule interface
public:
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QList<std::shared_ptr<const ast_basic::TokenNode>> parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QString token_present() const override;
};
public:
TokenMatch(std::shared_ptr<const lib_token::TokenDefine> define);
/**
* @brief
*/
class LIBSYNTAX_EXPORT Seqs : public BaseRule {
private:
QList<std::shared_ptr<const BaseRule>> mbrs_store;
// BaseRule interface
public:
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual std::shared_ptr<const ast_basic::Expression> parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QString token_present() const override;
};
public:
Seqs(const QList<std::shared_ptr<const BaseRule>> mbrs);
/**
* @brief
*/
class LIBSYNTAX_EXPORT Any : public BaseRule, public std::enable_shared_from_this<Any> {
private:
QList<std::shared_ptr<const BaseRule>> mbrs_store;
// BaseRule interface
public:
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QList<std::shared_ptr<const ast_basic::TokenNode>> parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QString token_present() const override;
};
std::tuple<MatchResult, uint, std::shared_ptr<const BaseRule>> rule_select(const QList<std::shared_ptr<const lib_token::Token>>& stream) const;
/**
* @brief
*/
class LIBSYNTAX_EXPORT Rept : public BaseRule {
private:
std::shared_ptr<const BaseRule> rule_peer;
int min_match, max_match;
public:
Any(const QList<std::shared_ptr<const BaseRule>> mbrs);
public:
Rept(std::shared_ptr<const BaseRule> rule, int min, int max);
// BaseRule interface
public:
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual std::shared_ptr<const ast_basic::Expression> parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QString token_present() const override;
};
// BaseRule interface
public:
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QList<std::shared_ptr<const ast_basic::TokenNode>> parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QString token_present() const override;
};
/**
* @brief
*/
class LIBSYNTAX_EXPORT Seqs : public BaseRule, public std::enable_shared_from_this<Seqs> {
private:
QList<std::shared_ptr<const BaseRule>> mbrs_store;
// 组合语法实体解析 ===================================================================================================
/**
* @brief
*/
class LIBSYNTAX_EXPORT ExprRule : public lib_syntax::BaseRule, public std::enable_shared_from_this<ExprRule> {
private:
std::shared_ptr<const lib_syntax::BaseRule> child_store;
QString name_store;
int mark_store;
std::function<QList<std::shared_ptr<const ast_basic::TokenNode>>(const QList<std::shared_ptr<const ast_basic::TokenNode>>& primary)> filter_proc;
public:
Seqs(const QList<std::shared_ptr<const BaseRule>> mbrs);
public:
typedef QList<std::shared_ptr<const ast_basic::TokenNode>> TokenSeqs;
ExprRule(const QString& rule_name, int expr_mark);
// BaseRule interface
public:
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual std::shared_ptr<const ast_basic::Expression> parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QString token_present() const override;
};
virtual std::shared_ptr<const ExprRule> reloadRule(std::function<TokenSeqs(const TokenSeqs&)> filter, std::shared_ptr<const BaseRule> rule);
virtual QString name() const;
virtual int typeMark() const;
/**
* @brief
*/
class LIBSYNTAX_EXPORT Rept : public BaseRule, public std::enable_shared_from_this<Rept> {
private:
std::shared_ptr<const BaseRule> rule_peer;
int min_match, max_match;
// BaseRule interface
public:
virtual QList<std::shared_ptr<const lib_syntax::BaseRule>> children() const override;
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QList<std::shared_ptr<const ast_basic::TokenNode>> parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QString token_present() const override;
};
public:
Rept(std::shared_ptr<const BaseRule> rule, int min, int max);
/**
* @brief
*/
class LIBSYNTAX_EXPORT ExprsChecker {
public:
ExprsChecker(std::shared_ptr<const ExprRule> parse_tree);
// BaseRule interface
public:
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual std::shared_ptr<const ast_basic::Expression> parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QString token_present() const override;
};
QList<std::shared_ptr<const ast_basic::TokenNode>> parseFrom(const QList<std::shared_ptr<const lib_token::Token>>& all_tokens);
// 组合语法实体解析 ===================================================================================================
/**
* @brief
*/
class LIBSYNTAX_EXPORT ExpressionRule : public lib_syntax::BaseRule, public std::enable_shared_from_this<ExpressionRule> {
public:
typedef QList<std::shared_ptr<const lib_token::Token>> TokenSeqs;
ExpressionRule(const QString& rule_name, int expr_mark);
private:
std::shared_ptr<const ExprRule> syntax_tree_root;
};
virtual std::shared_ptr<const ExpressionRule> reloadRule(std::function<TokenSeqs(const TokenSeqs&)> filter, std::shared_ptr<const BaseRule> rule);
virtual QString name() const;
virtual int typeMark() const;
virtual std::shared_ptr<ast_basic::Expression> newEmptyInstance() const = 0;
virtual std::shared_ptr<ExpressionRule> makeCopy() const = 0;
// BaseRule interface
public:
virtual QList<std::shared_ptr<const lib_syntax::BaseRule>> children() const override;
virtual std::tuple<MatchResult, uint> match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual std::shared_ptr<const ast_basic::Expression> parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const override;
virtual QString token_present() const override;
private:
std::function<TokenSeqs(const TokenSeqs&)> filter_proc;
std::shared_ptr<const lib_syntax::BaseRule> child_store;
QString name_store;
int mark_store;
};
/**
* .
*/
template<class ExprType>
class ElementRule : public ExpressionRule {
public:
ElementRule(const QString& rule_name, int expr_mark)
:ExpressionRule(rule_name, expr_mark){}
virtual std::shared_ptr<ast_basic::Expression> newEmptyInstance() const {
return std::dynamic_pointer_cast<ast_basic::Expression>(
std::make_shared<ExprType>(this->shared_from_this()));
}
virtual std::shared_ptr<ExpressionRule> makeCopy() const {
return std::make_shared<ElementRule<ExprType>>(name(), typeMark());
}
};
} // namespace lib_syntax

View File

@ -1,5 +1,6 @@
#include "syntax_novel.h"
#include <tokens_novel.h>
#include "ast_novel.h"
using namespace lib_syntax;
using namespace example_novel;
@ -38,78 +39,93 @@ auto newl = std::make_shared<NewLine>();
QList<std::shared_ptr<const BaseRule>> LinesMerge(const QList<std::shared_ptr<const BaseRule>>& mbrs) {
QList<std::shared_ptr<const BaseRule>> values_ret;
for (auto& item : mbrs) {
values_ret << item << OptMulT(newl);
}
return values_ret;
QList<std::shared_ptr<const BaseRule>> values_ret;
for (auto& item : mbrs) {
values_ret << item << OptMulT(newl);
}
return values_ret;
}
QList<std::shared_ptr<const BaseRule>> LinesMerge(std::shared_ptr<const BaseRule> item) {
return QList<std::shared_ptr<const BaseRule>>() << item << OptMulT(newl);
return QList<std::shared_ptr<const BaseRule>>() << item << OptMulT(newl);
}
// remove-return
auto remove_nl = [](const ExprRule::TokenSeqs& p)->ExprRule::TokenSeqs {
ExprRule::TokenSeqs result;
for (auto& n : p) {
if (n->isLeaf()) {
auto target_token = n->tokens().first();
if (target_token->define()->name() == newl->name())
continue;
}
result.append(n);
}
return result;
auto remove_nl = [](const ExpressionRule::TokenSeqs& p)->ExpressionRule::TokenSeqs {
ExpressionRule::TokenSeqs result;
for (auto& n : p) {
if (n->define()->name() == newl->name())
continue;
result.append(n);
}
return result;
};
auto decl_comp = std::make_shared<const Any>(Rules{MR(numbers), MR(vtext), MR(name_text), MR(split_mark)});
auto decl_expr = ExprRule(u8"decl_section", (int)NovelExprs::DESC_SECTION).reloadRule(remove_nl,
std::make_shared<const Seqs>(LinesMerge(MultiR(decl_comp))
auto decl_comp = std::make_shared<const Any>(Rules{ MR(numbers), MR(vtext), MR(name_text), MR(split_mark) });
auto decl_expr = ElementRule<TextSection>(u8"decl_section", (int)NovelExprs::DESC_SECTION).reloadRule(remove_nl,
std::make_shared<const Seqs>(LinesMerge(MultiR(decl_comp))
));
auto fragment_decl = ElementRule<FragmentDefine>(u8"fragment_define", (int)NovelExprs::FRAG_DEFINES).reloadRule(remove_nl, std::make_shared<const Seqs>(
LinesMerge(Rules{ MR(leftb), MR(frag_key), MR(name_text) }) <<
OptMulR(decl_expr) <<
LinesMerge(MR(rightb))
));
auto fragment_decl = ExprRule(u8"fragment_define", (int)NovelExprs::FRAG_DEFINES).reloadRule(remove_nl, std::make_shared<const Seqs>(
LinesMerge(Rules{MR(leftb), MR(frag_key), MR(name_text)}) <<
OptMulR(decl_expr) <<
LinesMerge(MR(rightb))
auto fragment_refer = ElementRule<FragmentRefers>(u8"fragment_refer", (int)NovelExprs::FRAG_REFERS).reloadRule(remove_nl, std::make_shared<const Seqs>(
LinesMerge(Rules{ MR(leftb), MR(refers), MR(frag_key), MR(name_text), MR(split_mark), MR(name_text) }) <<
OptMulR(decl_expr) <<
LinesMerge(MR(rightb))
));
auto fragment_refer = ExprRule(u8"fragment_refer", (int)NovelExprs::FRAG_REFERS).reloadRule(remove_nl, std::make_shared<const Seqs>(
LinesMerge(Rules{MR(leftb), MR(refers), MR(frag_key), MR(name_text), MR(split_mark), MR(name_text)}) <<
OptMulR(decl_expr) <<
LinesMerge(MR(rightb))
));
auto fragment_comp = std::make_shared<const Any>(Rules{fragment_decl, fragment_refer, decl_expr});
auto story_define = ExprRule(u8"story_define", (int)NovelExprs::STORY_DEFINES).reloadRule(remove_nl, std::make_shared<const Seqs>(
LinesMerge(Rules{MR(leftb), MR(story_key), MR(numbers), MR(name_text)}) <<
OptMulR(fragment_comp) <<
LinesMerge(MR(rightb))
auto fragment_comp = std::make_shared<const Any>(Rules{ fragment_decl, fragment_refer, decl_expr });
auto story_define = ElementRule<StoryDefine>(u8"story_define", (int)NovelExprs::STORY_DEFINES).reloadRule(remove_nl, std::make_shared<const Seqs>(
LinesMerge(Rules{ MR(leftb), MR(story_key), MR(numbers), MR(name_text) }) <<
OptMulR(fragment_comp) <<
LinesMerge(MR(rightb))
));
// ===================================================================
auto article_decl = ExprRule(u8"article_define", (int)NovelExprs::ARTICLE_DEFINE).reloadRule(remove_nl, std::make_shared<const Seqs>(
LinesMerge(Rules{MR(leftb), MR(article_key), MR(name_text)}) <<
OptMulR(std::make_shared<const Any>(Rules{ fragment_refer, decl_expr })) <<
LinesMerge(MR(rightb))
auto article_decl = ElementRule<ArticleDefine>(u8"article_define", (int)NovelExprs::ARTICLE_DEFINE).reloadRule(remove_nl, std::make_shared<const Seqs>(
LinesMerge(Rules{ MR(leftb), MR(article_key), MR(name_text) }) <<
OptMulR(std::make_shared<const Any>(Rules{ fragment_refer, decl_expr })) <<
LinesMerge(MR(rightb))
));
auto volume_decl = ExprRule(u8"volume_define", (int)NovelExprs::VOLUME_DEFINE).reloadRule(remove_nl, std::make_shared<const Seqs>(
LinesMerge(Rules{MR(leftb), MR(volume_key), MR(name_text)}) <<
OptMulR(std::make_shared<const Any>(Rules{ decl_expr, article_decl })) <<
LinesMerge(MR(rightb))
auto volume_decl = ElementRule<VolumeDefine>(u8"volume_define", (int)NovelExprs::VOLUME_DEFINE).reloadRule(remove_nl, std::make_shared<const Seqs>(
LinesMerge(Rules{ MR(leftb), MR(volume_key), MR(name_text) }) <<
OptMulR(std::make_shared<const Any>(Rules{ decl_expr, article_decl })) <<
LinesMerge(MR(rightb))
));
auto document_define = ExprRule(u8"decls-doc", (int)NovelExprs::DOC_DEFINES).reloadRule(remove_nl, std::make_shared<const Seqs>(
Rules{
OptMulT(newl),
MultiR(std::make_shared<const Any>(Rules{story_define, volume_decl}))
}
auto document_define = ElementRule<Document>(u8"decls-doc", (int)NovelExprs::DOC_DEFINES).reloadRule(remove_nl, std::make_shared<const Seqs>(
Rules{
OptMulT(newl),
MultiR(std::make_shared<const Any>(Rules{story_define, volume_decl}))
}
));
std::shared_ptr<const ExprRule> NovalSyntax::getParseTree() { return document_define; }
std::shared_ptr<const ExpressionRule> NovalSyntax::getParseTree() { return document_define; }
std::shared_ptr<const ast_gen::SyntaxElement> example_novel::NovalSyntax::tidy(std::shared_ptr<const ast_gen::SyntaxElement> root, QList<std::shared_ptr<ast_gen::SyntaxElement>> children)
{
for (auto& cinst : children) {
cinst->setParent(root);
if (!cinst->isAnonymous())
ast_gen::GlobalElement::UniquePtr->appendToCache(cinst);
QList<std::shared_ptr<ast_gen::SyntaxElement>> child_items;
for (auto& it : cinst->bindExpression()->children()) {
auto const_it = std::dynamic_pointer_cast<const ast_gen::SyntaxElement>(it);
child_items.append(std::const_pointer_cast<ast_gen::SyntaxElement>(const_it));
}
tidy(cinst, child_items);
}
return root;
}
std::shared_ptr<const TokenReader> NovalSyntax::getLexReader()
{
auto inst = std::make_shared<lib_token::TokenReader>(QList<std::shared_ptr<const lib_token::TokenDefine>>()
<< leftb << rightb << refers << split_mark << story_key << frag_key << volume_key << article_key << numbers << name_text << vtext << newl);
return inst;
auto inst = std::make_shared<lib_token::TokenReader>(QList<std::shared_ptr<const lib_token::TokenDefine>>()
<< leftb << rightb << refers << split_mark << story_key << frag_key << volume_key << article_key << numbers << name_text << vtext << newl);
return inst;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "ast_basic.h"
#include "ast_gen.h"
#include "libsyntax.h"
#include <libtoken.h>
#include <tokens_novel.h>
@ -35,7 +36,9 @@ namespace example_novel {
* @brief novel语法解析树
* @return
*/
static std::shared_ptr<const lib_syntax::ExprRule> getParseTree();
static std::shared_ptr<const lib_syntax::ExpressionRule> getParseTree();
static std::shared_ptr<const ast_gen::SyntaxElement> tidy(std::shared_ptr<const ast_gen::SyntaxElement> root, QList<std::shared_ptr<ast_gen::SyntaxElement>> docs);
};
} // namespace example_novel