#include "StoryUnitDocumentParser.h" using namespace Parse; using namespace Parse::Result; using namespace Lex; using namespace Syntax; using namespace Syntax::Defines; NodeStoryUnit::NodeStoryUnit(DocCore * doc, const QString & name) : doc_ref(doc), name_store(name) { } QString NodeStoryUnit::name() const { return name_store; } DocCore * NodeStoryUnit::document() const { return doc_ref; } int NodeStoryUnit::typeValue() const { return NODE_STORYUNIT; } DesNode * NodeStoryUnit::parent() const { return nullptr; } void NodeStoryUnit::appendChild(DesNode * ins) { children_nodes << ins; } QList NodeStoryUnit::children() const { return children_nodes; } bool NodeStoryUnit::check(QList& reasons) const { return false; } QString NodeStoryUnit::toString() const { QString rets = "#单元 " + name_store + "{"; for (auto it : children_nodes) rets += "\n" + it->toString(); rets += "\n}"; return rets; } NodeStoryFragment::NodeStoryFragment(NodeStoryUnit * unit, const QString & name) : unit_ins(unit), name_store(name) { } DocCore * NodeStoryFragment::document() const { return unit_ins->document(); } int NodeStoryFragment::typeValue() const { return NODE_STORYFRAGMENT; } DesNode * NodeStoryFragment::parent() const { return unit_ins; } void NodeStoryFragment::appendChild(DesNode * ins) { children_nodes << ins; } QList NodeStoryFragment::children() const { return children_nodes; } bool NodeStoryFragment::check(QList& reasons) const { return false; } QString NodeStoryFragment::toString() const { QString rets = QString(depth(), ' ') + "#情节 " + name() + "{"; for (auto cin : children_nodes) rets += "\n" + QString(depth(), ' ') + cin->toString(); return rets + "\n"+QString(depth(), ' ') + "}"; } QString NodeStoryFragment::name() const { return name_store; } NodeStoryPointRefer::NodeStoryPointRefer(DesNode * parent, const QString & chain, const QString & point) : parent_ins(parent), chain_name(chain), point_name(point) {} DocCore * NodeStoryPointRefer::document() const { return parent_ins->document(); } int NodeStoryPointRefer::typeValue() const { return NODE_POINTREFERENCE; } DesNode * NodeStoryPointRefer::parent() const { return parent_ins; } void NodeStoryPointRefer::appendChild(DesNode * ins) {} QList NodeStoryPointRefer::children() const { return QList(); } bool NodeStoryPointRefer::check(QList& reasons) const { return false; } QString NodeStoryPointRefer::toString() const { return QString("{@节点 %1 %2}").arg(chain_name).arg(point_name); } NodeStoryFragmentComment::NodeStoryFragmentComment(DesNode * parent, const QString &order, const QString & name) : parent_ins(parent), name_store(name), order_name(order) { } QString NodeStoryFragmentComment::order() const { return order_name; } DocCore * NodeStoryFragmentComment::document() const { return parent_ins->document(); } int NodeStoryFragmentComment::typeValue() const { return NODE_ORDEREDCOMMENT; } DesNode * NodeStoryFragmentComment::parent() const { return parent_ins; } void NodeStoryFragmentComment::appendChild(DesNode * ins) { children_nodes << ins; } QList NodeStoryFragmentComment::children() const { return children_nodes; } bool NodeStoryFragmentComment::check(QList& reasons) const { return false; } QString NodeStoryFragmentComment::toString() const { auto xrets = QString(depth(), ' ') + "#注解 " + name() +" "+ order() +" "+ orderValue() + "{"; for (auto it : children_nodes) xrets += "\n" + QString(depth(), ' ') + it->toString(); xrets += "\n" + QString(depth(), ' ') + "}"; return xrets; } QString NodeStoryFragmentComment::name() const { return name_store; } QString NodeStoryFragmentComment::orderValue() const { return order_value; } void NodeStoryFragmentComment::resetValue(const QString &value) { this->order_value = value; } NodeStoryUnitParser::NodeStoryUnitParser(ProjectCore * core) : XSyntaxBase("故事单元"), pjt_core(core) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); auto rule = addRule("进入单元解析", 0, [this](const QList &seqs, int cnt)->ParseResult { auto nmidx = cnt - 1, defidx = cnt - 2;; auto node = new NodeStoryUnit(this->docRef(), seqs[nmidx].Text); this->refocusNode(node); auto word0 = new Words(node, docRef(), seqs[defidx].Text, seqs[defidx].StartRow, seqs[defidx].StartCol); auto word1 = new Words(node, docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); docRef()->append(word0); docRef()->append(word1); return ParseResult::SelfManipulate; }); rule->addExpression("基础单元解析", { Elm("{单元定义}"), Elm("{描述文本}", true) }); rule->addExpression("拓展单元解析", { Exp("::换行前缀"), Exp("基础单元解析", true) }); rule = addRule("单元成分解析", 1, [this](const QList &seqs, int cnt)->ParseResult { auto node = currNode(); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); docRef()->append(word); return ParseResult::EnterNext; }); rule->addExpression("基础单元成分解析", { Elm("{左界限}", true) }); rule->addExpression("拓展单元成分解析", { Exp("::换行前缀"), Exp("基础单元成分解析", true) }); rule = addRule("跳出单元成分解析", 2, [this](const QList &seqs, int cnt)->ParseResult { auto node = currNode(); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); docRef()->append(word); return ParseResult::Completed; }); rule->addExpression("基础跳出单元解析", { Elm("{右界限}", true) }); rule->addExpression("拓展跳出单元解析", { Exp("::换行前缀"), Exp("基础跳出单元解析", true) }); addChild(QList() << new NodeStoryMixedDesGroupParser(this) << new NodeStoryFragmentParser(this)); } ProjectCore * NodeStoryUnitParser::project() const { return pjt_core; } StoryUnitDocumentParser::StoryUnitDocumentParser(ProjectCore * ins) { appendTokensDefine({ {"{单元定义}", "#单元"}, {"{情节定义}", "#情节"}, {"{注解定义}", "#注解"}, {"{节点引用}", "\\{@节点"}, {"{描述文本}", "[^#@\\{\\}\\n]+"}, {"{左界限}", "\\{"}, {"{右界限}", "\\}"}, {"{换行符}", "\\n"}, }, "{无法识别}"); auto chain_parser = new NodeStoryUnitParser(ins); appendParser(chain_parser); } NodeStoryFragmentParser::NodeStoryFragmentParser(NodeStoryUnitParser * pparser) : XSyntaxBase("故事情节"), parent_parser(pparser) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); auto rule = addRule("进入情节解析", 0, [this](const QList &seqs, int cnt)->ParseResult { auto nmidx = cnt - 1, defidx = cnt - 2;; auto parent_parser = nodeStoryUnitParser(); auto node = new NodeStoryFragment(static_cast(parent_parser->currNode()), seqs[nmidx].Text); this->refocusNode(node); parent_parser->currNode()->appendChild(node); auto word0 = new Words(node, docRef(), seqs[defidx].Text, seqs[defidx].StartRow, seqs[defidx].StartCol); auto word1 = new Words(node, docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); docRef()->append(word0); docRef()->append(word1); return ParseResult::SelfManipulate; }); rule->addExpression("基础情节解析", { Elm("{情节定义}"), Elm("{描述文本}", true) }); rule->addExpression("拓展情节解析", { Exp("::换行前缀"), Exp("基础情节解析", true) }); rule = addRule("情节成分解析", 1, [this](const QList &seqs, int cnt)->ParseResult { auto node = currNode(); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); docRef()->append(word); return ParseResult::EnterNext; }); rule->addExpression("基础情节成分解析", { Elm("{左界限}", true) }); rule->addExpression("拓展情节成分解析", { Exp("::换行前缀"), Exp("基础情节成分解析", true) }); rule = addRule("跳出情节成分解析", 2, [this](const QList &seqs, int cnt)->ParseResult { auto node = currNode(); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); docRef()->append(word); return ParseResult::Completed; }); rule->addExpression("基础跳出情节解析", { Elm("{右界限}", true) }); rule->addExpression("拓展跳出情节解析", { Exp("::换行前缀"),Exp("基础跳出情节解析", true) }); addChild(QList() << new NodeStoryMixedDesGroupParser(this) << new NodeStoryFragmentCommentParser(this)); } NodeStoryUnitParser * NodeStoryFragmentParser::nodeStoryUnitParser() const { return parent_parser; } DocCore * NodeStoryFragmentParser::docRef() const { return parent_parser->docRef(); } #include "StoryChainDocumentParser.h" NodeStoryMixedDesGroupParser::NodeStoryMixedDesGroupParser(XSyntaxBase * parent) : XSyntaxBase("描述块", MatchType::Outline), parent_parser(parent), unique_tidy(new NodeStoryLinePrefixParser (this)) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); set_common_expression("::基础引用定义", { Elm("{节点引用}"),Elm("{描述文本}1"), Elm("{描述文本}2"), Elm("{右界限}", true) }); set_common_expression("::基础文本块定义", {Elm("{描述文本}"), Elm("{描述文本}", true) }); auto rule = addRule("进入描述块解析", 0, [this](const QList &seqs, int cnt)->ParseResult { auto state = seqs[0].Token == QString("{换行符}"); unique_tidy->setMatchEnable(state); auto group = new NodeStoryDesGroup(parent_parser->currNode()); parent_parser->currNode()->appendChild(group); this->refocusNode(group); return ParseResult::EnterNext; }); rule->addExpression("文本块混合定义x", { Exp("::基础引用定义", true), Exp("::基础引用定义"), Exp("::基础文本块定义", true), Exp("::基础引用定义")}); rule->addExpression("文本块混合定义y", {Exp("::基础文本块定义", true), Exp("::基础引用定义"),Exp("::基础引用定义", true), Exp("::基础文本块定义")} ); rule->addExpression("拓展文本块x", { Exp("::换行前缀"), Exp("文本块混合定义x", true)}); rule->addExpression("拓展文本块y", { Exp("::换行前缀"), Exp("文本块混合定义y", true)}); addChild(QList() << unique_tidy << new NodeStoryTextSpanParser(this) << new NodeStoryPointReferParser(this)); } void NodeStoryMixedDesGroupParser::reset() { XSyntaxBase::reset(); } NodeStoryTextSpanParser::NodeStoryTextSpanParser(XSyntaxBase *parent) : Syntax::XSyntaxBase("文本块"), parent_parser(parent) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); auto rule = addRule("解析TextSpan", 0, [this](const QList &seqs, int cnt)->ParseResult { auto pnode = parent_parser->currNode(); for(auto idx=0; idxunknowns(); if(seqs[idx].Token != "{换行符}"){ node = new NodeStoryDesBlock(pnode, seqs[idx].Text); pnode->appendChild(node); } auto word = new Words(node, docRef(), seqs[idx].Text, seqs[idx].StartRow, seqs[idx].StartCol); docRef()->append(word); } return ParseResult::Completed; }); rule->addExpression("基础文本块定义", {Elm("{描述文本}"), Elm("{描述文本}", true) }); // rule->addExpression("拓展文本块定义", {Exp("::换行前缀"), Exp("基础文本块定义", true)}); } NodeStoryPointReferParser::NodeStoryPointReferParser(XSyntaxBase *parent) : Syntax::XSyntaxBase("节点引用"), parent_parser(parent) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); auto rule = addRule("解析节点引用", 0, [this](const QList &seqs, int cnt)->ParseResult { auto pnode = parent_parser->currNode(); auto chain_unit = seqs[cnt-3]; auto point_unit = seqs[cnt-2]; auto refer = new NodeStoryPointRefer(pnode, chain_unit.Text, point_unit.Text); pnode->appendChild(refer); auto word3 = new Words(refer, docRef(), seqs[cnt-1].Text, seqs[cnt-1].StartRow, seqs[cnt-1].StartCol); auto word2 = new Words(refer, docRef(), point_unit.Text, point_unit.StartRow, point_unit.StartCol); auto word1 = new Words(refer, docRef(), chain_unit.Text, chain_unit.StartRow, chain_unit.StartCol); auto word0 = new Words(refer, docRef(), seqs[cnt-4].Text, seqs[cnt-4].StartRow, seqs[cnt-4].StartCol); docRef()->append(word3); docRef()->append(word2); docRef()->append(word1); docRef()->append(word0); return ParseResult::Completed; }); rule->addExpression("基础引用定义", { Elm("{节点引用}"),Elm("{描述文本}1"), Elm("{描述文本}2"), Elm("{右界限}", true) }); // rule->addExpression("拓展引用定义", {Exp("::换行前缀"), Exp("基础引用定义",true)}); } /** * 故事情节有序注释,单独解析 * #注解 注解名 序列名 值 { * 注解段落 * 注解段落 * } */ NodeStoryFragmentCommentParser::NodeStoryFragmentCommentParser(Syntax::SyntaxParser *pparser) : Syntax::XSyntaxBase("有序注解", MatchType::Entirely), pparser(pparser) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); auto rule = this->addRule("进入注解", 0, [this](const QList &seqs, int cnt)->ParseResult{ auto nmidx = cnt - 3; auto oridx = cnt - 2; auto vidx = cnt - 1; auto pnode = this->pparser->currNode(); auto comment = new NodeStoryFragmentComment(pnode, seqs[oridx].Text, seqs[nmidx].Text); comment->resetValue(seqs[vidx].Text); pnode->appendChild(comment); refocusNode(comment); auto word0 = new Words(comment, docRef(), seqs[cnt-4].Text, seqs[cnt-4].StartRow, seqs[cnt-4].StartCol); auto word1 = new Words(comment, docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); auto word2 = new Words(comment, docRef(), seqs[oridx].Text, seqs[oridx].StartRow, seqs[oridx].StartCol); auto word3 = new Words(comment, docRef(), seqs[vidx].Text, seqs[vidx].StartRow, seqs[vidx].StartCol); docRef()->append(word0); docRef()->append(word1); docRef()->append(word2); docRef()->append(word3); return ParseResult::SelfManipulate; }); rule->addExpression("基础注解定义", {Elm("{注解定义}"), Elm{"{描述文本}1"}, Elm{"{描述文本}2"}, Elm{"{描述文本}3", true}}); rule->addExpression("拓展注解定义", {Exp("::换行前缀"), Exp("基础注解定义", true)}); rule = addRule("进入成分解析", 1, [this](const QList &seqs, int cnt)->ParseResult { auto node = currNode(); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); docRef()->append(word); return ParseResult::EnterNext; }); rule->addExpression("成分解析", { Elm("{左界限}", true) }); rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("成分解析", true) }); rule = addRule("跳出成分解析", 2, [this](const QList &seqs, int cnt)->ParseResult { auto node = currNode(); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); docRef()->append(word); return ParseResult::Completed; }); rule->addExpression("基础跳出成分解析", { Elm("{右界限}", true) }); rule->addExpression("拓展跳出成分解析", { Exp("::换行前缀"),Exp("基础跳出成分解析", true) }); addChild(QList() << new NodeStoryMixedDesGroupParser(this)); } NodeStoryLinePrefixParser::NodeStoryLinePrefixParser(SyntaxParser *pparent) : Syntax::XSyntaxBase("换行符清理", MatchType::Entirely), critical_rule(nullptr) { critical_rule = addRule("清理换行符", 0, [this](const QList &seqs, int cnt)->ParseResult { this->setMatchEnable(false); return ParseResult::Completed; }); critical_rule->addExpression("清理换行符x", {Elm{"{换行符}"},Elm{"{换行符}", true}}); } void NodeStoryLinePrefixParser::setMatchEnable(bool v) { critical_rule->setEnable(v); }