#include "syntax_novel.h" #include using namespace lib_syntax; using namespace example_novel; using namespace lib_token; using namespace ast_basic; // token-avaliable ========================================================================== auto leftb = std::make_shared(); // { auto rightb = std::make_shared(); // } auto refers = std::make_shared(); // @ auto story_key = std::make_shared(u8"故事", u8"story-mark"); // 故事 auto numbers = std::make_shared(); // [0-9]+ auto frag_key = std::make_shared(u8"情节", u8"fragment-mark"); // 情节 auto volume_key = std::make_shared(u8"分卷", u8"volume-mark"); // 分卷 auto article_key = std::make_shared(u8"章节", u8"article-mark"); // 章节 auto split_mark = std::make_shared(); // & auto vtext = std::make_shared(); // ^([^\\{\\}\\n@&]+) auto name_text = std::make_shared(); // ^([^:\\{\\}\\n@&][^\\{\\}\\n@&]*) auto newl = std::make_shared(); // rule-parts =============================================================================== // MatchRule #define MR(x) std::make_shared(x) // Buffer #define Rules QList> // Option #define OptMulT(token) std::make_shared(MR(token), 0, INT_MAX) #define OptMulR(rule) std::make_shared(rule, 0, INT_MAX) // multi+ #define MultiR(rule) std::make_shared(rule, 1, INT_MAX) QList> LinesMerge(const QList>& mbrs) { QList> values_ret; for (auto& item : mbrs) { values_ret << item << OptMulT(newl); } return values_ret; } QList> LinesMerge(std::shared_ptr item) { return QList>() << 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 decl_comp = std::make_shared(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(LinesMerge(MultiR(decl_comp)) )); auto fragment_decl = ExprRule(u8"fragment_define", (int)NovelExprs::FRAG_DEFINES).reloadRule(remove_nl, std::make_shared( LinesMerge(Rules{MR(leftb), MR(frag_key), 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( 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(Rules{fragment_decl, fragment_refer, decl_expr}); auto story_define = ExprRule(u8"story_define", (int)NovelExprs::STORY_DEFINES).reloadRule(remove_nl, std::make_shared( 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( LinesMerge(Rules{MR(leftb), MR(article_key), MR(name_text)}) << OptMulR(std::make_shared(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( LinesMerge(Rules{MR(leftb), MR(volume_key), MR(name_text)}) << OptMulR(std::make_shared(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( Rules{ OptMulT(newl), MultiR(std::make_shared(Rules{story_define, volume_decl})) } )); std::shared_ptr NovalSyntax::getParseTree() { return document_define; } std::shared_ptr NovalSyntax::getLexReader() { auto inst = std::make_shared(QList>() << leftb << rightb << refers << split_mark << story_key << frag_key << volume_key << article_key << numbers << name_text << vtext << newl); return inst; }