#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) : Result::NamedNode(name, doc, NODE_STORYUNIT, nullptr){} bool NodeStoryUnit::check(QList& reasons) const { auto unit_nodes = doc()->core()->queryStoryUnit(name()); if(unit_nodes.size() > 1){ for(auto &it : unit_nodes) reasons << QString("重复定义单元:%1,{src=%2 (row=%3, col=%4)}") .arg(name(), it->doc()->filePath()) .arg(it->refered().first()->row()).arg(it->refered().first()->column()); } return unit_nodes.size() == 1; } QString NodeStoryUnit::toString() const { QString rets = "#单元 " + name() + "{"; for (auto &it : children()) rets += "\n" + it->toString(); rets += "\n}"; return rets; } NodeStoryFragment::NodeStoryFragment(NodeStoryUnit * unit, const QString & name) : Result::NamedNode(name, unit->doc(), NODE_STORYFRAGMENT, unit){} bool NodeStoryFragment::check(QList& reasons) const { auto nodes = doc()->core()->queryStoryFragment(parent(), name()); if(nodes.size() > 1){ for(auto &it : nodes) reasons << QString("重复定义情节:%1,{src=%2 (row=%3, col=%4)}") .arg(name(), it->doc()->filePath()) .arg(it->refered().first()->row()).arg(it->refered().first()->column()); } return nodes.size() == 1; } QString NodeStoryFragment::toString() const { QString rets = QString(depth(), ' ') + "#情节 " + name() + "{"; for (auto cin : children()) rets += "\n" + QString(depth(), ' ') + cin->toString(); return rets + "\n"+QString(depth(), ' ') + "}"; } NodeStoryPointRefer::NodeStoryPointRefer(DesNode * parent, const QString & chain, const QString & point) : Result::DesNode(parent->doc(), NODE_POINTREFERENCE, parent), chain_name(chain), point_name(point) {} QString NodeStoryPointRefer::chainName() const { return chain_name; } QString NodeStoryPointRefer::pointName() const { return point_name; } bool NodeStoryPointRefer::check(QList& reasons) const { auto chain = doc()->core()->queryStoryChain(chainName()); if(!chain.size()){ reasons << QString("指定脉络不存在:%1{src=%2(row=%3,col=%4)}") .arg(chainName(), doc()->filePath()) .arg(refered().first()->row()).arg(refered().first()->column()); return false; } else{ auto point = doc()->core()->queryStoryPoint(chain[0], pointName()); if(!point.size()) reasons << QString("指定节点不存在:%1:%2{src=%3(row=%3,col=%4)}") .arg(chainName(), pointName(), doc()->filePath()) .arg(refered().first()->row()).arg(refered().first()->column()); return point.size(); } } 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(ParseCore * 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)); } ParseCore * NodeStoryUnitParser::project() const { return pjt_core; } StoryUnitDocumentParser::StoryUnitDocumentParser(ParseCore * 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); }