改进StoryDefine节点CacheLoad机制

This commit is contained in:
codeboss 2024-06-20 22:13:06 +08:00
parent 4e99a6f120
commit e1fe5e1104
7 changed files with 77 additions and 55 deletions

View File

@ -7,15 +7,21 @@
#include <QDebug> #include <QDebug>
using namespace example_novel; using namespace example_novel;
using namespace lib_parse;
NovelParser::NovelParser() NovelParser::NovelParser()
{ {
this->syntax_defines = example_novel::NovalSyntax::getParseTree(); this->syntax_defines = NovalSyntax::getParseTree();
checker_list << std::make_shared<example_novel::FragmentExistsCheck>(); checker_list << std::make_shared<FragmentExistsCheck>();
checker_list << std::make_shared<example_novel::StoryOrderCheck>(); checker_list << std::make_shared<StoryOrderCheck>();
checker_list << std::make_shared<example_novel::FragmentGraphCheck>(); checker_list << std::make_shared<FragmentGraphCheck>();
analyzer_ref = std::make_shared<lib_parse::Analyzer>(checker_list); analyzer_ref = std::make_shared<Analyzer>(checker_list);
}
QList<std::shared_ptr<const FragmentGraphHelper>> NovelParser::fragmentsSorted() const
{
return std::dynamic_pointer_cast<const FragmentGraphCheck>(checker_list[1])->fragmentsSequence();
} }
QString NovelParser::version() const QString NovelParser::version() const

View File

@ -5,6 +5,10 @@
#include <libsyntax.h> #include <libsyntax.h>
#include <libparse.h> #include <libparse.h>
namespace example_novel {
class FragmentGraphHelper;
}
class NovelParser class NovelParser
{ {
private: private:
@ -14,6 +18,7 @@ private:
public: public:
NovelParser(); NovelParser();
QList<std::shared_ptr<const example_novel::FragmentGraphHelper>> fragmentsSorted() const;
virtual QString version() const; virtual QString version() const;
std::shared_ptr<const ast_gen::ElementAccess> parse(const QFileInfoList souurce_list) const; std::shared_ptr<const ast_gen::ElementAccess> parse(const QFileInfoList souurce_list) const;

View File

@ -16,7 +16,7 @@ void FragmentExistsCheck::exists_check(std::shared_ptr<const GlobalElement> root
if (target->element()->typeMark() == (int)NovelNode::FragmentRefer) { if (target->element()->typeMark() == (int)NovelNode::FragmentRefer) {
auto refer = std::dynamic_pointer_cast<const FragmentRefers>(target->element()); auto refer = std::dynamic_pointer_cast<const FragmentRefers>(target->element());
auto signature = refer->storyRefer() + u8"&" + refer->fragmentRefer(); auto signature = refer->storyRefer() + u8"&" + refer->fragmentRefer();
if(!root->getNamedNodeBy((int)NovelNode::FragmentDefine, signature)) if (!root->getNamedNodeBy((int)NovelNode::FragmentDefine, signature))
throw new SyntaxException(QString(u8"CheckError[0x0005]系统中不包含指定签名的节点:%1<type%2>{%3:(%4)}") throw new SyntaxException(QString(u8"CheckError[0x0005]系统中不包含指定签名的节点:%1<type%2>{%3:(%4)}")
.arg(signature).arg((int)NovelNode::FragmentDefine).arg(refer->signature()).arg(refer->filePath())); .arg(signature).arg((int)NovelNode::FragmentDefine).arg(refer->signature()).arg(refer->filePath()));
} }
@ -58,6 +58,10 @@ void FragmentGraphCheck::setElement(std::shared_ptr<FragmentGraphHelper> inst)
elements_store[inst->nodePeer()->signature()] = inst; elements_store[inst->nodePeer()->signature()] = inst;
} }
QList<std::shared_ptr<const FragmentGraphHelper>> FragmentGraphCheck::fragmentsSequence() const {
return fragments_sort_list;
}
std::shared_ptr<FragmentGraphHelper> FragmentGraphCheck::getElement(const QString& signature) const std::shared_ptr<FragmentGraphHelper> FragmentGraphCheck::getElement(const QString& signature) const
{ {
return elements_store[signature]; return elements_store[signature];
@ -92,6 +96,8 @@ bool FragmentGraphCheck::nodeDismantle(std::shared_ptr<FragmentGraphHelper> inst
void FragmentGraphCheck::validCheck(std::shared_ptr<const ElementAccess> root) const void FragmentGraphCheck::validCheck(std::shared_ptr<const ElementAccess> root) const
{ {
const_cast<FragmentGraphCheck*>(this)->fragments_sort_list.clear();
std::function<QList<std::shared_ptr<const ElementAccess>>(std::shared_ptr<const ElementAccess>)> story_peak std::function<QList<std::shared_ptr<const ElementAccess>>(std::shared_ptr<const ElementAccess>)> story_peak
= [&](std::shared_ptr<const ElementAccess> root)->QList<std::shared_ptr<const ElementAccess>> { = [&](std::shared_ptr<const ElementAccess> root)->QList<std::shared_ptr<const ElementAccess>> {
QList<std::shared_ptr<const ElementAccess>> return_temp; QList<std::shared_ptr<const ElementAccess>> return_temp;
@ -200,6 +206,9 @@ void FragmentGraphCheck::validCheck(std::shared_ptr<const ElementAccess> root) c
throw new CheckException(error_msg); throw new CheckException(error_msg);
} }
} }
for (auto& inst : values)
const_cast<FragmentGraphCheck*>(this)->fragments_sort_list.append(inst);
} }
QString FragmentGraphCheck::name() const { QString FragmentGraphCheck::name() const {
@ -232,32 +241,32 @@ QList<std::shared_ptr<const ElementAccess>> StoryOrderCheck::valid_docs_peak(std
auto type_code = pnode->element()->typeMark(); auto type_code = pnode->element()->typeMark();
switch ((NovelNode)type_code) { switch ((NovelNode)type_code) {
case NovelNode::GlobalElement:{ case NovelNode::GlobalElement: {
auto children = pnode->children(); auto children = pnode->children();
for(auto &cinst : children){ for (auto& cinst : children) {
values.append(valid_docs_peak(cinst)); values.append(valid_docs_peak(cinst));
}
}break;
case NovelNode::Document: {
auto storys_collection = pnode->children();
bool story_exists = false;
for (auto& syntax_elm : storys_collection) {
if (syntax_elm->element()->typeMark() == (int)NovelNode::StoryDefine) {
story_exists = true;
break;
} }
}break; }
case NovelNode::Document: { if (story_exists) {
auto storys_collection = pnode->children(); auto first_elm = storys_collection.at(0);
values.append(pnode);
bool story_exists = false; if (first_elm->element()->typeMark() != (int)NovelNode::RankDeclaration)
for (auto& syntax_elm : storys_collection) { throw new CheckException(QString(u8"CheckError[0x0007]具有故事节点的文档必须在第一行指定排序(%1").arg(pnode->element()->path()));
if (syntax_elm->element()->typeMark() == (int)NovelNode::StoryDefine) { }
story_exists = true; }break;
break;
}
}
if (story_exists) {
auto first_elm = storys_collection.at(0);
values.append(pnode);
if(first_elm->element()->typeMark() != (int)NovelNode::RankDeclaration)
throw new CheckException(QString(u8"CheckError[0x0007]具有故事节点的文档必须在第一行指定排序(%1").arg(pnode->element()->path()));
}
}break;
default: default:
break; break;
@ -276,7 +285,7 @@ void StoryOrderCheck::validCheck(std::shared_ptr<const ElementAccess> root) cons
const_cast<StoryOrderCheck*>(this)->sort_index = 1; const_cast<StoryOrderCheck*>(this)->sort_index = 1;
auto story_docs = valid_docs_peak(root); auto story_docs = valid_docs_peak(root);
std::sort(story_docs.begin(), story_docs.end(), [](std::shared_ptr<const ElementAccess> adoc, std::shared_ptr<const ElementAccess> bdoc){ std::sort(story_docs.begin(), story_docs.end(), [](std::shared_ptr<const ElementAccess> adoc, std::shared_ptr<const ElementAccess> bdoc) {
auto elm_xa = std::dynamic_pointer_cast<const RankDeclare>(adoc->children().first()->element()); auto elm_xa = std::dynamic_pointer_cast<const RankDeclare>(adoc->children().first()->element());
auto elm_xb = std::dynamic_pointer_cast<const RankDeclare>(bdoc->children().first()->element()); auto elm_xb = std::dynamic_pointer_cast<const RankDeclare>(bdoc->children().first()->element());
return elm_xa->rankNumber() < elm_xb->rankNumber(); return elm_xa->rankNumber() < elm_xb->rankNumber();
@ -292,9 +301,9 @@ void StoryOrderCheck::validCheck(std::shared_ptr<const ElementAccess> root) cons
} }
// 故事节点排序 // 故事节点排序
auto story_node_sort = [](std::shared_ptr<const ElementAccess> doc_node, int start_index) -> int{ auto story_node_sort = [](std::shared_ptr<const ElementAccess> doc_node, int start_index) -> int {
auto childs = doc_node->children(); auto childs = doc_node->children();
for (auto &inst : childs) { for (auto& inst : childs) {
if (inst->element()->typeMark() == (int)NovelNode::StoryDefine) { if (inst->element()->typeMark() == (int)NovelNode::StoryDefine) {
auto cast_inst = std::dynamic_pointer_cast<const StoryDefine>(inst->element()); auto cast_inst = std::dynamic_pointer_cast<const StoryDefine>(inst->element());
std::const_pointer_cast<StoryDefine>(cast_inst)->setSort(start_index++); std::const_pointer_cast<StoryDefine>(cast_inst)->setSort(start_index++);
@ -304,6 +313,6 @@ void StoryOrderCheck::validCheck(std::shared_ptr<const ElementAccess> root) cons
}; };
int ranks_number = 1; int ranks_number = 1;
for(auto &story : story_docs) for (auto& story : story_docs)
ranks_number = story_node_sort(story, ranks_number); ranks_number = story_node_sort(story, ranks_number);
} }

View File

@ -19,9 +19,10 @@ namespace example_novel {
class LIBPARSE_EXPORT FragmentGraphCheck : public std::enable_shared_from_this<FragmentGraphCheck>, public lib_parse::CheckProvider { class LIBPARSE_EXPORT FragmentGraphCheck : public std::enable_shared_from_this<FragmentGraphCheck>, public lib_parse::CheckProvider {
private: private:
QHash<QString, std::shared_ptr<FragmentGraphHelper>> elements_store; QHash<QString, std::shared_ptr<FragmentGraphHelper>> elements_store;
QList<std::shared_ptr<const FragmentGraphHelper>> fragments_sort_list;
QList<std::shared_ptr<FragmentGraphHelper>> refers_cycle_check( QList<std::shared_ptr<FragmentGraphHelper>> refers_cycle_check(
std::shared_ptr<FragmentGraphHelper> item, QList<std::shared_ptr<FragmentGraphHelper>> prevs = QList<std::shared_ptr<FragmentGraphHelper>>()) const; std::shared_ptr<FragmentGraphHelper> item, QList<std::shared_ptr<FragmentGraphHelper>> prevs = QList<std::shared_ptr<FragmentGraphHelper>>()) const;
public: public:
void setElement(std::shared_ptr<FragmentGraphHelper> inst); void setElement(std::shared_ptr<FragmentGraphHelper> inst);
@ -30,6 +31,8 @@ namespace example_novel {
QList<std::shared_ptr<FragmentGraphHelper>> getHangoutNodes(); QList<std::shared_ptr<FragmentGraphHelper>> getHangoutNodes();
bool nodeDismantle(std::shared_ptr<FragmentGraphHelper> inst); bool nodeDismantle(std::shared_ptr<FragmentGraphHelper> inst);
QList<std::shared_ptr<const FragmentGraphHelper>> fragmentsSequence() const;
// CheckProvider interface // CheckProvider interface
public: public:
virtual void validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const override; virtual void validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const override;

View File

@ -5,32 +5,32 @@ using namespace ast_basic;
using namespace lib_token; using namespace lib_token;
using namespace lib_syntax; using namespace lib_syntax;
ExpressionElement::ExpressionElement(std::shared_ptr<const lib_syntax::ExpressionRule> bind) : _expr_rule(bind) {} ExpressionElement::ExpressionElement(std::shared_ptr<const ExpressionRule> bind) : _expr_rule(bind) {}
std::shared_ptr<const lib_syntax::ExpressionRule> ast_basic::ExpressionElement::definedRule() const { std::shared_ptr<const ExpressionRule> ExpressionElement::definedRule() const {
return _expr_rule; return _expr_rule;
} }
QString ast_basic::ExpressionElement::filePath() const { QString ExpressionElement::filePath() const {
if(tokens_bind.size()) if(!tokens_bind.size())
throw new SyntaxException(u8"InternalError[0x0002]Ò»¸ö¿ÕµÄ·Ç·¨ÎÞЧ½Úµã"); throw new SyntaxException(u8"InternalError[0x0002]Ò»¸ö¿ÕµÄ·Ç·¨ÎÞЧ½Úµã");
return tokens_bind.first()->file(); return tokens_bind.first()->file();
} }
void ast_basic::ExpressionElement::tokensReset(const QList<std::shared_ptr<const IToken>>& list) { void ExpressionElement::tokensReset(const QList<std::shared_ptr<const IToken>>& list) {
this->tokens_bind = list; this->tokens_bind = list;
} }
void ast_basic::ExpressionElement::addToken(std::shared_ptr<const IToken> token_inst) { void ExpressionElement::addToken(std::shared_ptr<const IToken> token_inst) {
this->tokens_bind.append(token_inst); this->tokens_bind.append(token_inst);
} }
QList<std::shared_ptr<const Expression>> ast_basic::ExpressionElement::children() const { QList<std::shared_ptr<const Expression>> ExpressionElement::children() const {
return this->children_store; return this->children_store;
} }
void ast_basic::ExpressionElement::addChild(std::shared_ptr<const Expression> inst) { void ExpressionElement::addChild(std::shared_ptr<const Expression> inst) {
this->children_store.append(inst); this->children_store.append(inst);
} }
@ -38,13 +38,13 @@ QList<std::shared_ptr<const IToken>> ExpressionElement::tokens() const {
return this->tokens_bind; return this->tokens_bind;
} }
ast_basic::ExpressionContext::ExpressionContext() {} ExpressionContext::ExpressionContext() {}
void ast_basic::ExpressionContext::setCurrentFile(const QString& path) { this->current_file_path = path; } void ExpressionContext::setCurrentFile(const QString& path) { this->current_file_path = path; }
QString ast_basic::ExpressionContext::currentFile() const { return this->current_file_path; } QString ExpressionContext::currentFile() const { return this->current_file_path; }
std::shared_ptr<ast_basic::Expression> ast_basic::ExpressionContext::currentInst() const std::shared_ptr<Expression> ExpressionContext::currentInst() const
{ {
if(expression_stack.size()) if(expression_stack.size())
return expression_stack.last(); return expression_stack.last();
@ -52,30 +52,30 @@ std::shared_ptr<ast_basic::Expression> ast_basic::ExpressionContext::currentInst
return nullptr; return nullptr;
} }
void ast_basic::ExpressionContext::pushInst(std::shared_ptr<ast_basic::Expression> current_inst) void ExpressionContext::pushInst(std::shared_ptr<Expression> current_inst)
{ {
if(!expression_stack.size() || expression_stack.last() != current_inst) if(!expression_stack.size() || expression_stack.last() != current_inst)
expression_stack.append(current_inst); expression_stack.append(current_inst);
} }
std::shared_ptr<ast_basic::Expression> ast_basic::ExpressionContext::popInst() std::shared_ptr<Expression> ExpressionContext::popInst()
{ {
auto lastx = expression_stack.takeLast(); auto lastx = expression_stack.takeLast();
return lastx; return lastx;
} }
std::shared_ptr<const lib_syntax::BaseRule> ast_basic::ExpressionContext::currentExpressionRule() const { std::shared_ptr<const BaseRule> ExpressionContext::currentExpressionRule() const {
if(rule_stack.size()) if(rule_stack.size())
return rule_stack.last(); return rule_stack.last();
return nullptr; return nullptr;
} }
void ast_basic::ExpressionContext::pushExpressionRule(std::shared_ptr<const lib_syntax::BaseRule> inst) { void ExpressionContext::pushExpressionRule(std::shared_ptr<const BaseRule> inst) {
if(!rule_stack.size() || rule_stack.last() != inst) if(!rule_stack.size() || rule_stack.last() != inst)
rule_stack.append(inst); rule_stack.append(inst);
} }
std::shared_ptr<const lib_syntax::BaseRule> ast_basic::ExpressionContext::popExpressionRule() std::shared_ptr<const BaseRule> ExpressionContext::popExpressionRule()
{ {
return rule_stack.takeLast(); return rule_stack.takeLast();
} }

View File

@ -91,8 +91,7 @@ int StoryDefine::sort() const { return sort_index; }
void StoryDefine::cacheLoad() void StoryDefine::cacheLoad()
{ {
name_store = selfTokens()[3]->token()->content(); name_store = selfTokens()[2]->token()->content();
sort_index = selfTokens()[2]->token()->content().toInt();
} }
int StoryDefine::typeMark() const { return (int)NovelNode::StoryDefine; } int StoryDefine::typeMark() const { return (int)NovelNode::StoryDefine; }

View File

@ -81,7 +81,7 @@ auto fragment_refer = ElementRule<FragmentRefers>(u8"fragment_refer", (int)Novel
auto fragment_comp = std::make_shared<const Any>(Rules{ fragment_decl, fragment_refer, decl_expr }); 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>( 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) }) << LinesMerge(Rules{ MR(leftb), MR(story_key), MR(name_text) }) <<
OptMulR(fragment_comp) << OptMulR(fragment_comp) <<
LinesMerge(MR(rightb)) LinesMerge(MR(rightb))
)); ));
@ -137,7 +137,7 @@ void NovalSyntax::node_register(std::shared_ptr<const ast_gen::SyntaxElement> ro
if (!child->isAnonymous()) { if (!child->isAnonymous()) {
auto check_result = ast_gen::GlobalElement::UniquePtr->appendToCache(child); auto check_result = ast_gen::GlobalElement::UniquePtr->appendToCache(child);
if(check_result) if(check_result)
throw new lib_syntax::SyntaxException(QString(u8"Parse[0x0004]系统中包含同类型重名命名节点:%1<type%2>(%3,%4)") throw new lib_syntax::SyntaxException(QString(u8"SyntaxError[0x0004]系统中包含同类型重名命名节点:%1<type%2>(%3,%4)")
.arg(child->signature()).arg(child->typeMark()).arg(child->path()).arg(check_result->path())); .arg(child->signature()).arg(child->typeMark()).arg(child->path()).arg(check_result->path()));
} }