#include "StoryChainDocumentParser.h" using namespace Parse; using namespace Lex; using namespace Syntax; using namespace Syntax::Defines; using namespace Parse::Result; // storychain 解析器================================================ NodeStoryChainParser::NodeStoryChainParser(ProjectCore *core) : XSyntaxBase("文学脉络"), pjt_ref(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 storychain = new NodeStoryChain(this->docRef(), seqs[nmidx].Text); this->refocusNode(storychain); // 收集词语 auto words0 = new Words(storychain, this->docRef(), seqs[defidx].Text, seqs[defidx].StartRow, seqs[defidx].StartCol); auto words1 = new Words(storychain, this->docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); docRef()->append(words0); docRef()->append(words1); return ParseResult::SelfManipulate; }); rule->addExpression("脉络定义基础", { Elm("{脉络定义}"), Elm("{描述文本}", true) }); rule->addExpression("脉络定义拓展", { Exp("::换行前缀"), Exp("脉络定义基础", true)}); rule = addRule("脉络成分解析", 1, [this](const QList &seqs, int cnt)->ParseResult { auto nmidx = cnt - 1; // 获取语法节点 auto storychain = this->currNode(); // 收集词语 auto word = new Words(storychain, docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].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 nmidx = cnt - 1; // 获取语法节点 auto storychain = this->currNode(); // 收集词语 auto word = new Words(storychain, docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); docRef()->append(word); return ParseResult::Completed; }); rule->addExpression("基础脉络跳出", { Elm("{右界限}", true) }); rule->addExpression("拓展脉络跳出", { Exp("::换行前缀"), Exp("基础脉络跳出", true) }); addChild(QList() << new NodeStoryPointParser(this) << new NodeStoryChainDesGroupParser(this)); } ProjectCore * NodeStoryChainParser::project() const { return pjt_ref; } // storypoint解析器================================================= NodeStoryPointParser::NodeStoryPointParser(NodeStoryChainParser *chain) : XSyntaxBase("脉络驻点"), parent_parser(chain) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); auto rule = addRule("脉络驻点定义", 0, [this](const QList &seqs, int c)->ParseResult { auto nmidx = c - 1, defidx = c - 2; // 语法节点定义 auto node = this->storyChainParser()->currNode(); auto storypoint = new NodeStoryPoint(static_cast(node), seqs[nmidx].Text); node->appendChild(storypoint); this->refocusNode(storypoint); // 词语收集 auto word0 = new Words(storypoint, node->document(), seqs[defidx].Text, seqs[defidx].StartRow, seqs[defidx].StartCol); auto word1 = new Words(storypoint, node->document(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); node->document()->append(word0); node->document()->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 nmidx = cnt - 1; auto word = new Words(this->currNode(), this->storyChainParser()->docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); this->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 nmidx = cnt - 1; auto word = new Words(this->currNode(), this->storyChainParser()->docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); this->docRef()->append(word); return ParseResult::Completed; }); rule->addExpression("基础节点跳出", { Elm("{右界限}", true) }); rule->addExpression("拓展节点跳出", { Exp("::换行前缀"), Exp("基础节点跳出", true) }); addChild(QList() << new NodeStoryChainDesGroupParser(this)); } NodeStoryChainParser * NodeStoryPointParser::storyChainParser() const { return parent_parser; } DocCore * NodeStoryPointParser::docRef() const { return this->storyChainParser()->docRef(); } NodeStoryChain::NodeStoryChain(DocCore * doc, const QString & name) : doc_store(doc), name_store(name) { } QString NodeStoryChain::srcPath() const { return doc_store->filePath(); } QString NodeStoryChain::name() const { return name_store; } DocCore * NodeStoryChain::document() const { return doc_store; } int NodeStoryChain::typeValue() const { return NODE_STORYCHAIN; } DesNode * NodeStoryChain::parent() const { return nullptr; } void NodeStoryChain::appendChild(DesNode * ins) { children_nodes.append(ins); } QList NodeStoryChain::children() const { return children_nodes; } bool NodeStoryChain::check(QList& reasons) const { return false; } QString NodeStoryChain::toString() const { auto desc_string = QString(depth(), ' ') + "#脉络 " + name() + " {"; for (auto it : children()) desc_string += "\n"+ QString(depth(), ' ') + it->toString(); desc_string +="\n"+ QString(depth(), ' ') + "}"; return desc_string; } NodeStoryPoint::NodeStoryPoint(NodeStoryChain * chain, const QString & name) : chain_store(chain), name_store(name) { } NodeStoryChain * NodeStoryPoint::storyChain() const { return chain_store; } DocCore * NodeStoryPoint::document() const { return chain_store->document(); } int NodeStoryPoint::typeValue() const { return NODE_STORYPOINT; } DesNode * NodeStoryPoint::parent() const { return chain_store; } void NodeStoryPoint::appendChild(DesNode * ins) { children_nodes.append(ins); } QList NodeStoryPoint::children() const { return children_nodes; } bool NodeStoryPoint::check(QList& reasons) const { return false; } QString NodeStoryPoint::toString() const { QString desc_string = ""; desc_string += QString(depth(), ' ') + "#节点 " + name() + " {"; for (auto it : children()) desc_string += "\n" + QString(depth(), ' ') + it->toString(); desc_string += "\n"+QString(depth(), ' ') + "}"; return desc_string; } QString NodeStoryPoint::name() const { return this->name_store; } NodeStoryDesGroup::NodeStoryDesGroup(DesNode * parent_refer) : parent_refer(parent_refer) { } DocCore * NodeStoryDesGroup::document() const { return parent_refer->document(); } int NodeStoryDesGroup::typeValue() const { return NODE_DESCRIPTION_GROUP; } DesNode * NodeStoryDesGroup::parent() const { return parent_refer; } void NodeStoryDesGroup::appendChild(DesNode * ins) { children_nodes << ins; } QList NodeStoryDesGroup::children() const { return children_nodes; } bool NodeStoryDesGroup::check(QList& reasons) const { return false; } QString NodeStoryDesGroup::toString() const { QString desc = QString(depth(), ' ') ; for (auto it : children()) desc += it->toString() + " "; return desc; } NodeStoryDesBlock::NodeStoryDesBlock(DesNode *parent_node, const QString &text) : parent_refer(parent_node), text_block(text) { } DocCore * NodeStoryDesBlock::document() const { return parent_refer->document(); } int NodeStoryDesBlock::typeValue() const { return NODE_DESCRIPTION_BLOCK; } DesNode * NodeStoryDesBlock::parent() const { return parent_refer; } void NodeStoryDesBlock::appendChild(DesNode * ins) { } QList NodeStoryDesBlock::children() const { return QList(); } bool NodeStoryDesBlock::check(QList& reasons) const { return false; } QString NodeStoryDesBlock::toString() const { return text_block; } NodeStoryChainDesGroupParser::NodeStoryChainDesGroupParser(XSyntaxBase * pparser) : XSyntaxBase("描述块"), parent_parser(pparser) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); auto rule = addRule("提取文本", 0, [this, pparser](const QList &seqs, int cnt)->ParseResult { auto curr_node = new NodeStoryDesGroup(pparser->currNode()); refocusNode(curr_node); pparser->currNode()->appendChild(curr_node); for (auto idx = 0; idx < cnt; ++idx) if (seqs[idx].Token != "{换行符}") { auto node_blk = new NodeStoryDesBlock(curr_node, seqs[idx].Text); curr_node->appendChild(node_blk); auto word = new Words(node_blk, 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) }); rule = addRule("完成提取", 1, [this](const QList &seqs, int cnt)->ParseResult { refocusNode(nullptr); return ParseResult::Completed; }); rule->addExpression("基础文本提取跳出", { Elm("{换行符}", true) }); } StoryChainDocumentParser::StoryChainDocumentParser(ProjectCore * pjt) { appendTokensDefine({ {"{脉络定义}","#脉络"}, {"{节点定义}", "#节点"}, {"{描述文本}", "[^#@\\{\\}\\n]+"}, {"{左界限}","\\{"}, {"{右界限}","\\}"}, {"{换行符}","\\n"}, {"{引用符}", "@"}, }, "{无法识别}"); auto chain_parser = new NodeStoryChainParser(pjt); appendParser(chain_parser); }