改进StoryDefine节点CacheLoad机制
This commit is contained in:
parent
4e99a6f120
commit
e1fe5e1104
|
@ -7,15 +7,21 @@
|
|||
#include <QDebug>
|
||||
|
||||
using namespace example_novel;
|
||||
using namespace lib_parse;
|
||||
|
||||
NovelParser::NovelParser()
|
||||
{
|
||||
this->syntax_defines = example_novel::NovalSyntax::getParseTree();
|
||||
checker_list << std::make_shared<example_novel::FragmentExistsCheck>();
|
||||
checker_list << std::make_shared<example_novel::StoryOrderCheck>();
|
||||
checker_list << std::make_shared<example_novel::FragmentGraphCheck>();
|
||||
this->syntax_defines = NovalSyntax::getParseTree();
|
||||
checker_list << std::make_shared<FragmentExistsCheck>();
|
||||
checker_list << std::make_shared<StoryOrderCheck>();
|
||||
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
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
#include <libsyntax.h>
|
||||
#include <libparse.h>
|
||||
|
||||
namespace example_novel {
|
||||
class FragmentGraphHelper;
|
||||
}
|
||||
|
||||
class NovelParser
|
||||
{
|
||||
private:
|
||||
|
@ -14,6 +18,7 @@ private:
|
|||
|
||||
public:
|
||||
NovelParser();
|
||||
QList<std::shared_ptr<const example_novel::FragmentGraphHelper>> fragmentsSorted() const;
|
||||
|
||||
virtual QString version() const;
|
||||
std::shared_ptr<const ast_gen::ElementAccess> parse(const QFileInfoList souurce_list) const;
|
||||
|
|
|
@ -16,7 +16,7 @@ void FragmentExistsCheck::exists_check(std::shared_ptr<const GlobalElement> root
|
|||
if (target->element()->typeMark() == (int)NovelNode::FragmentRefer) {
|
||||
auto refer = std::dynamic_pointer_cast<const FragmentRefers>(target->element());
|
||||
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)}")
|
||||
.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;
|
||||
}
|
||||
|
||||
QList<std::shared_ptr<const FragmentGraphHelper>> FragmentGraphCheck::fragmentsSequence() const {
|
||||
return fragments_sort_list;
|
||||
}
|
||||
|
||||
std::shared_ptr<FragmentGraphHelper> FragmentGraphCheck::getElement(const QString& signature) const
|
||||
{
|
||||
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
|
||||
{
|
||||
const_cast<FragmentGraphCheck*>(this)->fragments_sort_list.clear();
|
||||
|
||||
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>> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& inst : values)
|
||||
const_cast<FragmentGraphCheck*>(this)->fragments_sort_list.append(inst);
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
switch ((NovelNode)type_code) {
|
||||
case NovelNode::GlobalElement:{
|
||||
auto children = pnode->children();
|
||||
for(auto &cinst : children){
|
||||
values.append(valid_docs_peak(cinst));
|
||||
}
|
||||
}break;
|
||||
case NovelNode::GlobalElement: {
|
||||
auto children = pnode->children();
|
||||
for (auto& cinst : children) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
case NovelNode::Document: {
|
||||
auto storys_collection = pnode->children();
|
||||
|
||||
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()));
|
||||
bool story_exists = false;
|
||||
for (auto& syntax_elm : storys_collection) {
|
||||
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:
|
||||
break;
|
||||
|
@ -276,7 +285,7 @@ void StoryOrderCheck::validCheck(std::shared_ptr<const ElementAccess> root) cons
|
|||
const_cast<StoryOrderCheck*>(this)->sort_index = 1;
|
||||
|
||||
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_xb = std::dynamic_pointer_cast<const RankDeclare>(bdoc->children().first()->element());
|
||||
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();
|
||||
for (auto &inst : childs) {
|
||||
for (auto& inst : childs) {
|
||||
if (inst->element()->typeMark() == (int)NovelNode::StoryDefine) {
|
||||
auto cast_inst = std::dynamic_pointer_cast<const StoryDefine>(inst->element());
|
||||
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;
|
||||
for(auto &story : story_docs)
|
||||
for (auto& story : story_docs)
|
||||
ranks_number = story_node_sort(story, ranks_number);
|
||||
}
|
||||
|
|
|
@ -19,9 +19,10 @@ namespace example_novel {
|
|||
class LIBPARSE_EXPORT FragmentGraphCheck : public std::enable_shared_from_this<FragmentGraphCheck>, public lib_parse::CheckProvider {
|
||||
private:
|
||||
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(
|
||||
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:
|
||||
void setElement(std::shared_ptr<FragmentGraphHelper> inst);
|
||||
|
@ -30,6 +31,8 @@ namespace example_novel {
|
|||
QList<std::shared_ptr<FragmentGraphHelper>> getHangoutNodes();
|
||||
bool nodeDismantle(std::shared_ptr<FragmentGraphHelper> inst);
|
||||
|
||||
QList<std::shared_ptr<const FragmentGraphHelper>> fragmentsSequence() const;
|
||||
|
||||
// CheckProvider interface
|
||||
public:
|
||||
virtual void validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const override;
|
||||
|
|
|
@ -5,32 +5,32 @@ using namespace ast_basic;
|
|||
using namespace lib_token;
|
||||
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;
|
||||
}
|
||||
|
||||
QString ast_basic::ExpressionElement::filePath() const {
|
||||
if(tokens_bind.size())
|
||||
QString 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 IToken>>& list) {
|
||||
void ExpressionElement::tokensReset(const QList<std::shared_ptr<const IToken>>& 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);
|
||||
}
|
||||
|
||||
QList<std::shared_ptr<const Expression>> ast_basic::ExpressionElement::children() const {
|
||||
QList<std::shared_ptr<const Expression>> ExpressionElement::children() const {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -38,13 +38,13 @@ QList<std::shared_ptr<const IToken>> ExpressionElement::tokens() const {
|
|||
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())
|
||||
return expression_stack.last();
|
||||
|
@ -52,30 +52,30 @@ std::shared_ptr<ast_basic::Expression> ast_basic::ExpressionContext::currentInst
|
|||
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)
|
||||
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();
|
||||
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())
|
||||
return rule_stack.last();
|
||||
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)
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -91,8 +91,7 @@ int StoryDefine::sort() const { return sort_index; }
|
|||
|
||||
void StoryDefine::cacheLoad()
|
||||
{
|
||||
name_store = selfTokens()[3]->token()->content();
|
||||
sort_index = selfTokens()[2]->token()->content().toInt();
|
||||
name_store = selfTokens()[2]->token()->content();
|
||||
}
|
||||
|
||||
int StoryDefine::typeMark() const { return (int)NovelNode::StoryDefine; }
|
||||
|
|
|
@ -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 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) <<
|
||||
LinesMerge(MR(rightb))
|
||||
));
|
||||
|
@ -137,7 +137,7 @@ void NovalSyntax::node_register(std::shared_ptr<const ast_gen::SyntaxElement> ro
|
|||
if (!child->isAnonymous()) {
|
||||
auto check_result = ast_gen::GlobalElement::UniquePtr->appendToCache(child);
|
||||
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()));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue