QtNovelUI/DesParser/StoryUnitDocumentParser.cpp

459 lines
18 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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<QString>& 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<QString>& 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<QString>& 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<DesNode*> NodeStoryFragmentComment::children() const
//{
// return children_nodes;
//}
//bool NodeStoryFragmentComment::check(QList<QString>& 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<LexResult> &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<LexResult> &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<LexResult> &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<SyntaxParser*>() << 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<LexResult> &seqs, int cnt)->ParseResult {
auto nmidx = cnt - 1, defidx = cnt - 2;;
auto parent_parser = nodeStoryUnitParser();
auto node = new NodeStoryFragment(static_cast<NodeStoryUnit*>(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<LexResult> &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<LexResult> &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<SyntaxParser*>() << 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<LexResult> &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<SyntaxParser*>() << 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<LexResult> &seqs, int cnt)->ParseResult {
auto pnode = parent_parser->currNode();
for(auto idx=0; idx<cnt; ++idx){
DesNode *node = docRef()->unknowns();
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<LexResult> &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<LexResult> &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<LexResult> &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<LexResult> &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<SyntaxParser*>() << new NodeStoryMixedDesGroupParser(this));
//}
NodeStoryLinePrefixParser::NodeStoryLinePrefixParser(SyntaxParser *pparent)
: Syntax::XSyntaxBase("换行符清理", MatchType::Entirely), critical_rule(nullptr)
{
critical_rule = addRule("清理换行符", 0, [this](const QList<LexResult> &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);
}