QtNovelUI/DesParser/StoryChainDocumentParser.cpp

387 lines
10 KiB
C++

#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<LexResult> &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<LexResult> &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<LexResult> &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<SyntaxParser*>() << 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<LexResult> &seqs, int c)->ParseResult {
auto nmidx = c - 1, defidx = c - 2;
// 语法节点定义
auto node = this->storyChainParser()->currNode();
auto storypoint = new NodeStoryPoint(static_cast<NodeStoryChain*>(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<LexResult> &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<LexResult> &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<SyntaxParser*>() << 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<DesNode*> NodeStoryChain::children() const
{
return children_nodes;
}
bool NodeStoryChain::check(QList<QString>& 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<DesNode*> NodeStoryPoint::children() const
{
return children_nodes;
}
bool NodeStoryPoint::check(QList<QString>& 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<DesNode*> NodeStoryDesGroup::children() const
{
return children_nodes;
}
bool NodeStoryDesGroup::check(QList<QString>& 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<DesNode*> NodeStoryDesBlock::children() const
{
return QList<DesNode*>();
}
bool NodeStoryDesBlock::check(QList<QString>& 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<LexResult> &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<LexResult> &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);
}