#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 = std::make_shared(u8"故事", u8"story-mark"); // 故事 auto numbers = std::make_shared(); // [0-9]+ auto frags = std::make_shared(u8"情节", u8"fragment-mark"); // 情节 auto volume = std::make_shared(u8"分卷", u8"volume-mark"); // 分卷 auto article = std::make_shared(u8"章节", u8"article-mark"); // 章节 auto split = std::make_shared(); // & auto vtext = std::make_shared(); // ^([^\\{\\}\\n@&]+) auto ntext = std::make_shared(); // ^([^:\\{\\}\\n@&][^\\{\\}\\n@&]*) auto newl = std::make_shared(); // rule-parts =============================================================================== // MatchRule #define MR(x) std::make_shared(x) // Buffer #define Buff 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) // 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(Buff << MR(numbers) << MR(vtext) << MR(ntext) << MR(split)); auto decl_expr = ExprRule(u8"decl_section", (int)NovelExprs::DESC_SECTION) .reloadRule(remove_nl, std::make_shared(Buff << MultiR(decl_comp) << OptMulT(newl))); auto fragment_decl = ExprRule(u8"fragment_define", (int)NovelExprs::FRAG_DEFINES) .reloadRule(remove_nl, std::make_shared(Buff << MR(leftb) << OptMulT(newl) << MR(frags) << OptMulT(newl) << MR(ntext) << OptMulT(newl) << OptMulR(decl_expr) << MR(rightb) << OptMulT(newl))); auto fragment_refer = ExprRule(u8"fragment_refer", (int)NovelExprs::FRAG_REFERS) .reloadRule(remove_nl, std::make_shared(Buff << MR(leftb) << OptMulT(newl) << MR(refers) << OptMulT(newl) << MR(frags) << OptMulT(newl) << MR(ntext) << OptMulT(newl) << MR(split) << OptMulT(newl) << MR(ntext) << OptMulT(newl) << OptMulR(decl_expr) << MR(rightb) << OptMulT(newl))); auto fragment_comp = std::make_shared(Buff << fragment_decl << fragment_refer << decl_expr); auto story_define = ExprRule(u8"story_define", (int)NovelExprs::STORY_DEFINES) .reloadRule(remove_nl, std::make_shared(Buff << OptMulT(newl) << MR(leftb) << OptMulT(newl) << MR(story) << OptMulT(newl) << MR(numbers) << OptMulT(newl) << MR(ntext) << OptMulT(newl) << OptMulR(fragment_comp) << MR(rightb) << OptMulT(newl))); // =================================================================== auto article_decl = ExprRule(u8"article_define", (int)NovelExprs::ARTICLE_DEFINE) .reloadRule(remove_nl, std::make_shared( Buff << MR(leftb) << OptMulT(newl) << MR(article) << OptMulT(newl) << MR(ntext) << OptMulT(newl) << OptMulR(std::make_shared(Buff << fragment_refer << decl_expr)) << MR(rightb) << OptMulT(newl))); auto volume_decl = ExprRule(u8"volume_define", (int)NovelExprs::VOLUME_DEFINE) .reloadRule(remove_nl, std::make_shared(Buff << OptMulT(newl) << MR(leftb) << OptMulT(newl) << MR(volume) << OptMulT(newl) << MR(ntext) << OptMulT(newl) << OptMulR(std::make_shared(Buff << decl_expr << article_decl)) << MR(rightb) << OptMulT(newl))); auto document_define = ExprRule(u8"decls-doc", (int)NovelExprs::DOC_DEFINES) .reloadRule(remove_nl, std::make_shared(std::make_shared(Buff << story_define << volume_decl), 1, INT_MAX)); std::shared_ptr NovalSyntax::getParseTree() { return document_define; } std::shared_ptr NovalSyntax::getLexReader() { auto inst = std::make_shared(QList>() << leftb << rightb << refers << split << story << frags << volume << article << numbers << ntext << vtext << newl); return inst; }