同步当前状态

This commit is contained in:
玉宇清音 2022-11-17 16:27:48 +08:00
parent 0aa8fc8764
commit c1435484d3
14 changed files with 0 additions and 2841 deletions

View File

@ -1,28 +0,0 @@
#pragma once
#define NODE_UNKNOWNHOST 0 // 未知
#define NODE_STORYCHAIN 1 // 故事脉络
#define NODE_STORYPOINT 2 // 故事节点
#define NODE_DESCRIPTION_GROUP 3 // 描述集(段落)
#define NODE_DESCRIPTION_BLOCK 4 // 描述块(普通)
#define NODE_STORYUNIT 5 // 故事单元
#define NODE_STORYFRAGMENT 6 // 故事情节
#define NODE_POINTREFERENCE 7 // 节点引用
#define NODE_ORDEREDCOMMENT 8 // 情节序列注释
#define NODE_STORYBOARD 9 // 故事大纲
#define NODE_FRAGMENTREFERENCE 10 // 情节引用
#define NODE_STORYDEPICTION 11 // 卷宗叙述节点
#define DOC_STORYBOARD 0xa0001 // 故事板
#define DOC_STORYUNIT 0xa0002 // 故事单元
#define DOC_STORYCHAIN 0xa0003 // 故事脉络
#define DOC_VOLUMEOUTLINE 0xa0004 // 卷宗大纲

View File

@ -1,134 +0,0 @@
#include "LexFoundation.h"
#include <tuple>
using namespace Lex;
LexFoundation::LexFoundation(QList<LexDef> seqence, const QString UnknownToken)
: unknown_token(UnknownToken), lexical_seq(seqence)
{
empty_seq << '\t' << '\b' << ' ' << '\r' << EOF;
}
typedef int lexunit_index;
typedef int match_start;
QList<LexResult> LexFoundation::push(int row, int col, const QChar w)
{
QList<LexResult> result;
QString remains = "";
if (!empty_seq.contains(w)) {
code_acc << XChar(w, row, col);
if (w != '\n')
return result;
}
else {
if (!code_acc.size())
return result;
}
for (auto c : code_acc)
remains += c.value();
auto mid_result = lexical_parse(remains);
for (auto &r : mid_result) {
auto char_start = code_acc[r.index_at_segment];
r.StartRow = char_start.row();
r.StartCol = char_start.col();
auto char_end = code_acc[r.index_at_segment + r.Text.length() - 1];
r.EndRow = char_end.row();
r.EndCol = char_end.col();
}
code_acc.clear();
return mid_result;
}
QList<LexResult> LexFoundation::lexical_parse(const QString & segment)
{
// 获取匹配词法分析
QList<LexResult> result;
QList<std::tuple<match_start, lexunit_index>> match_results;
int lex_index = -1;
for (auto lex : lexical_seq) {
lex_index++;
QRegExp exp(lex.RegExpression);
auto match_index = exp.indexIn(segment);
if (match_index != -1)
match_results.append(std::make_tuple(match_index, lex_index));
}
// 没有匹配结果,返回未定义
if (!match_results.size())
{
LexResult rst;
rst.index_at_segment = 0;
rst.Token = this->unknown_token;
rst.Text = segment;
result << rst;
return result;
}
// 获取“匹配索引”,“词法优先级”获取最佳匹配结果,最小
std::tuple<match_start, lexunit_index> min_elm = std::make_tuple(INT32_MAX, INT32_MAX);
for (auto item : match_results) {
if (std::get<0>(item) < std::get<0>(min_elm))
min_elm = item;
else if (std::get<0>(item) == std::get<0>(min_elm) &&
std::get<1>(item) < std::get<1>(min_elm))
min_elm = item;
}
// 发现无效匹配局部,标记前部为未知
if (std::get<0>(min_elm) != 0) {
LexResult rst;
rst.index_at_segment = 0;
rst.Token = this->unknown_token;
rst.Text = segment.mid(0, std::get<0>(min_elm));
result << rst;
}
// 重新匹配,获取完全匹配信息
auto lex_unit = lexical_seq[std::get<1>(min_elm)];
QRegExp exp(lex_unit.RegExpression);
auto match_start = exp.indexIn(segment);
auto match_len = exp.matchedLength();
// 获取匹配词法分析结果
LexResult rst;
rst.Token = lex_unit.TokenType;
rst.Text = segment.mid(match_start, match_len);
rst.index_at_segment = match_start;
result << rst;
// 迭代匹配剩余字符串
auto last = segment.mid(match_start + match_len);
if(last.length()){
auto xrst = lexical_parse(last);
for (auto &t : xrst)
t.index_at_segment += match_start;
result.append(xrst);
}
// 返回结果
return result;
}
XChar::XChar(QChar c, int row, int col)
: value_store(c), row_index(row), col_index(col) {}
QChar XChar::value() const
{
return value_store;
}
int XChar::row() const
{
return row_index;
}
int XChar::col() const
{
return col_index;
}

View File

@ -1,76 +0,0 @@
#pragma once
#include <QString>
#include <QList>
namespace Lex {
class LexFoundation;
/**
* .
*/
struct LexDef
{
QString TokenType; // Token字符
QString RegExpression; // 词法解析表达式
};
/**
* .
*/
struct LexResult
{
QString Token; // Token字符
QString Text; // 内容
int StartRow, StartCol, EndRow, EndCol; // 波及范围
friend class LexFoundation;
private:
int index_at_segment;
};
/**
* .
*/
class XChar
{
public:
explicit XChar(QChar c, int row, int col);
QChar value() const;
int row() const;
int col() const;
private:
QChar value_store;
int row_index, col_index;
};
/**
* .
*/
class LexFoundation
{
public:
explicit LexFoundation(QList<LexDef> seqence, const QString UnknownToken);
virtual ~LexFoundation() = default;
/**
* .
*
* \param row
* \param col
* \param w
* \return
*/
QList<LexResult> push(int row, int col, const QChar w);
private:
QString unknown_token;
QList<QChar> empty_seq;
QList<XChar> code_acc;
QList<LexDef> lexical_seq;
QList<LexResult> lexical_parse(const QString &segment);
};
}

View File

@ -1,32 +0,0 @@
#pragma once
#include <QString>
#include <QList>
#include "SyntaxBase.h"
namespace Syntax
{
/**
* .
*/
class ParseFrame
{
public:
explicit ParseFrame();
virtual ~ParseFrame() = default;
QList<Parse::Result::DesNode*> analysis(Parse::Result::DocCore *doc, const QString &path);
protected:
void appendTokensDefine(QList<Lex::LexDef> seqs, const QString &unknown_token);
void appendParser(Syntax::SyntaxParser* u);
private:
QString unknown_token;
QList<Lex::LexDef> token_seqs;
QList<SyntaxParser*> cascade_parsers;
ParseResult ParseFrame::inner_parse(QList<Lex::LexResult> &lex_seqence,
QList<Syntax::SyntaxParser*> parsers,
QList<Parse::Result::DesNode*> &nodes_out);
};
}

View File

@ -1,288 +0,0 @@
#include "StoryChainDocumentParser.h"
using namespace Parse;
using namespace Lex;
using namespace Syntax;
using namespace Syntax::Defines;
using namespace Parse::Result;
// storychain 解析器================================================
NodeStoryChainParser::NodeStoryChainParser(ParseCore *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 NodeStoryPureTextDesGroupParser(this));
}
ParseCore * 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->doc(), seqs[defidx].Text, seqs[defidx].StartRow, seqs[defidx].StartCol);
auto word1 = new Words(storypoint, node->doc(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol);
node->doc()->append(word0);
node->doc()->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 NodeStoryPureTextDesGroupParser(this));
}
NodeStoryChainParser * NodeStoryPointParser::storyChainParser() const
{
return parent_parser;
}
DocCore * NodeStoryPointParser::docRef() const
{
return this->storyChainParser()->docRef();
}
NodeStoryChain::NodeStoryChain(DocCore * doc, const QString & name)
: Result::NamedNode(name, doc, NODE_STORYCHAIN){}
QString NodeStoryChain::srcPath() const
{
return doc()->filePath();
}
bool NodeStoryChain::check(QList<QString>& reasons) const
{
auto nodes = doc()->core()->queryStoryChain(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 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)
: Result::NamedNode(name, chain->doc(), NODE_STORYPOINT, chain){}
NodeStoryChain * NodeStoryPoint::storyChain() const
{
return static_cast<NodeStoryChain*>(parent());
}
bool NodeStoryPoint::check(QList<QString>& reasons) const
{
auto chain = parent();
auto nodes = chain->doc()->core()->queryStoryPoint(chain, 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 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;
}
NodeStoryDesGroup::NodeStoryDesGroup(DesNode * parent_refer)
: Result::DesNode(parent_refer->doc(), NODE_DESCRIPTION_GROUP, parent_refer){}
bool NodeStoryDesGroup::check(QList<QString>&) const
{
return true;
}
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)
: Result::DesNode(parent_node->doc(), NODE_DESCRIPTION_BLOCK, parent_node),
text_block(text){}
bool NodeStoryDesBlock::check(QList<QString>&) const
{
return true;
}
QString NodeStoryDesBlock::toString() const
{
return text_block;
}
NodeStoryPureTextDesGroupParser::NodeStoryPureTextDesGroupParser(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(ParseCore * pjt)
{
appendTokensDefine({
{"{脉络定义}","#脉络"},
{"{节点定义}", "#节点"},
{"{描述文本}", "[^#@\\{\\}\\n]+"},
{"{左界限}","\\{"},
{"{右界限}","\\}"},
{"{换行符}","\\n"},
{"{引用符}", "@"},
}, "{无法识别}");
auto chain_parser = new NodeStoryChainParser(pjt);
appendParser(chain_parser);
}

View File

@ -1,144 +0,0 @@
#pragma once
/**
* StoryChain文件定义.
*/
#include <QString>
#include <QList>
#include "ParseFrame.h"
#include "XSyntaxBase.h"
#include "ComnDef.h"
namespace Parse
{
class NodeStoryPoint;
/**
* .
*/
class NodeStoryChain : public Result::NamedNode
{
public:
/**
* .
*
* \param src_path
*/
explicit NodeStoryChain(Result::DocCore *doc, const QString &name);
virtual ~NodeStoryChain() = default;
/**
* .
*
* \return
*/
virtual QString srcPath() const;
// 通过 NamedNode 继承
virtual bool check(QList<QString>& reasons) const override;
virtual QString toString() const override;
};
/**
* .
*/
class NodeStoryChainParser : public Syntax::XSyntaxBase
{
public:
NodeStoryChainParser(Result::ParseCore *core);
virtual ~NodeStoryChainParser() = default;
Result::ParseCore* project() const;
private:
Result::ParseCore *pjt_ref;
};
/**
* .
*/
class NodeStoryPoint : public Result::NamedNode
{
public:
explicit NodeStoryPoint(NodeStoryChain *chain, const QString &name);
virtual ~NodeStoryPoint() = default;
/**
*
*
* \return
*/
virtual NodeStoryChain* storyChain() const;
// 通过 NamedNode 继承
virtual bool check(QList<QString>& reasons) const override;
virtual QString toString() const override;
};
/**
* .
*/
class NodeStoryPointParser : public Syntax::XSyntaxBase
{
public:
explicit NodeStoryPointParser(NodeStoryChainParser *chain);
virtual ~NodeStoryPointParser() = default;
NodeStoryChainParser* storyChainParser() const;
virtual Result::DocCore* docRef() const override;
private:
NodeStoryChainParser *const parent_parser;
};
/**
* .
*/
class NodeStoryDesGroup : public Result::DesNode
{
public:
NodeStoryDesGroup(DesNode *parent_refer);
virtual ~NodeStoryDesGroup() = default;
// 通过 DesNode 继承
virtual bool check(QList<QString>&) const override;
virtual QString toString() const override;
};
class NodeStoryPureTextDesGroupParser : public Syntax::XSyntaxBase
{
public:
explicit NodeStoryPureTextDesGroupParser(XSyntaxBase *pparser);
virtual ~NodeStoryPureTextDesGroupParser() = default;
private:
XSyntaxBase *const parent_parser;
};
/**
* .
*/
class NodeStoryDesBlock : public Result::DesNode
{
public:
explicit NodeStoryDesBlock(DesNode *parent_node, const QString &text);
virtual ~NodeStoryDesBlock() = default;
// 通过 DesNode 继承
virtual bool check(QList<QString>&) const override;
virtual QString toString() const override;
private:
QString text_block;
};
class StoryChainDocumentParser : public Syntax::ParseFrame
{
public:
StoryChainDocumentParser(Result::ParseCore *pjt);
virtual ~StoryChainDocumentParser() = default;
};
}

View File

@ -1,458 +0,0 @@
#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);
}

View File

@ -1,183 +0,0 @@
#pragma once
#include "XSyntaxBase.h"
#include "ParseFrame.h"
#include "SyntaxBase.h"
namespace Parse {
/**
* .
*/
class NodeStoryUnit : public Result::NamedNode
{
public:
explicit NodeStoryUnit(Result::DocCore *doc, const QString &name);
virtual ~NodeStoryUnit() = default;
// 通过 DesNode 继承
virtual bool check(QList<QString>& reasons) const override;
virtual QString toString() const override;
};
/** 故事单元解析器 */
class NodeStoryUnitParser : public Syntax::XSyntaxBase
{
public:
NodeStoryUnitParser(Result::ParseCore *core);
Result::ParseCore* project() const;
private:
Result::ParseCore *const pjt_core;
};
/**
* .
*/
class NodeStoryFragment : public Result::NamedNode
{
public:
explicit NodeStoryFragment(NodeStoryUnit* unit, const QString &name);
virtual ~NodeStoryFragment() = default;
// 通过 NamedNode 继承
virtual bool check(QList<QString>& reasons) const override;
virtual QString toString() const override;
};
/**
* .
*/
class NodeStoryFragmentParser : public Syntax::XSyntaxBase
{
public:
NodeStoryFragmentParser(NodeStoryUnitParser *pparser);
NodeStoryUnitParser * nodeStoryUnitParser() const;
Result::DocCore * docRef() const;
private:
NodeStoryUnitParser *const parent_parser;
};
/**
* .
*/
class NodeStoryPointRefer : public Result::DesNode
{
public:
explicit NodeStoryPointRefer(DesNode *parent, const QString &chain, const QString &point);
virtual ~NodeStoryPointRefer() = default;
QString chainName() const;
QString pointName() const;
// 通过 DesNode 继承
virtual bool check(QList<QString>& reasons) const override;
virtual QString toString() const override;
private:
QString chain_name;
QString point_name;
};
/**
* @brief
*/
class NodeStoryLinePrefixParser : public Syntax::XSyntaxBase
{
public:
NodeStoryLinePrefixParser(SyntaxParser* pparent);
void setMatchEnable(bool v);
private:
Syntax::ParseRule *critical_rule;
};
class NodeStoryMixedDesGroupParser : public Syntax::XSyntaxBase
{
public:
NodeStoryMixedDesGroupParser(Syntax::XSyntaxBase * parent);
virtual void reset() override;
private:
Syntax::XSyntaxBase *const parent_parser;
NodeStoryLinePrefixParser *const unique_tidy;
};
class NodeStoryTextSpanParser : public Syntax::XSyntaxBase
{
public:
NodeStoryTextSpanParser(Syntax::XSyntaxBase *parent);
private:
Syntax::XSyntaxBase *const parent_parser;
};
class NodeStoryPointReferParser : public Syntax::XSyntaxBase
{
public:
NodeStoryPointReferParser(Syntax::XSyntaxBase *parent);
private:
Syntax::XSyntaxBase *const parent_parser;
};
// /**
// * 故事情节有序注释,单独解析
// * #注解 注解名 序列名 值 {
// * 注解段落
// * 注解段落
// * }
// */
// class NodeStoryFragmentComment : public Result::NamedNode
// {
// public:
// NodeStoryFragmentComment(DesNode *parent, const QString &order, const QString &name);
// virtual ~NodeStoryFragmentComment() = default;
// QString order() const;
// // 通过 NamedNode 继承
// inline virtual int depth() const override
// {
// return parent_ins->depth() + 1;
// }
// virtual Result::DocCore * document() const override;
// virtual int typeValue() const override;
// virtual DesNode * parent() const override;
// virtual void appendChild(DesNode * ins) override;
// virtual QList<DesNode*> children() const override;
// virtual bool check(QList<QString>& reasons) const override;
// virtual QString toString() const override;
// virtual QString name() const override;
// QString orderValue() const;
// void resetValue(const QString &value);
// private:
// DesNode *const parent_ins;
// QString name_store;
// QString order_name;
// QString order_value;
// QList<DesNode*> children_nodes;
// };
// class NodeStoryFragmentCommentParser : public Syntax::XSyntaxBase
// {
// public:
// NodeStoryFragmentCommentParser(Syntax::SyntaxParser* pparser);
// private:
// Syntax::SyntaxParser *const pparser;
// };
class StoryUnitDocumentParser : public Syntax::ParseFrame
{
public:
StoryUnitDocumentParser(Result::ParseCore *ins);
};
}

View File

@ -1,320 +0,0 @@
#include "SyntaxBase.h"
#include <QFileInfo>
using namespace Parse;
using namespace Lex;
using namespace Syntax;
using namespace Parse::Result;
namespace Parse {
class Unknown : public DesNode
{
public:
explicit Unknown(DocCore *ins) : DesNode(ins, NODE_UNKNOWNHOST, nullptr){}
// 通过 DesNode 继承
virtual bool check(QList<QString>&) const override
{
return true;
}
virtual QString toString() const override
{
return QString();
}
};
}
NamedNode::NamedNode(const QString &name, DocCore *core, int type, DesNode *pnode)
: Result::DesNode(core, type, pnode), name_store(name){}
QString NamedNode::name() const
{
return name_store;
}
DesNode::DesNode(DocCore *core, int type_value, DesNode *pnode)
: doc_store(core), type_value(type_value), parent_node(pnode)
{
}
DesNode::~DesNode()
{
for(auto &i : children())
delete i;
children_nodes.clear();
}
int DesNode::depth() const
{
if(parent_node==nullptr)
return 0;
return parent_node->depth() + 1;
}
DocCore *DesNode::doc() const
{
return this->doc_store;
}
int DesNode::typeValue() const
{
return type_value;
}
DesNode *DesNode::parent() const
{
return parent_node;
}
void DesNode::appendChild(DesNode *ins)
{
children_nodes << ins;
}
QList<DesNode *> DesNode::children() const
{
return children_nodes;
}
void DesNode::registerWords(Words *ins)
{
words_collection << ins;
}
QList<Words *> DesNode::refered() const
{
return words_collection;
}
ParseCore::ParseCore(const QString &name)
: name_store(name)
{
}
void ParseCore::registerNode(DocCore *doc, DesNode *node)
{
if(!nodes_map.contains(doc))
nodes_map[doc] = new QList<DesNode*>();
nodes_map[doc]->append(node);
}
void ParseCore::clearNodes(DocCore *ins)
{
if(!nodes_map.contains(ins))
return;
auto c = nodes_map[ins];
for(auto i : *c)
delete i;
c->clear();
}
QList<DocCore *> ParseCore::allDocuments() const
{
return nodes_map.keys();
}
QList<DesNode *> ParseCore::queryRootNodes(DocCore *doc) const
{
if(!nodes_map.contains(doc))
return QList<DesNode*>();
return *nodes_map[doc];
}
DocCore *ParseCore::queryDocument(const QFileInfo &file_src) const
{
for(auto &d : nodes_map.keys()){
auto anchor_file = d->filePath();
if(anchor_file == file_src.absoluteFilePath())
return d;
}
return nullptr;
}
void ParseCore::deleteDocument(DocCore *ins)
{
ins->clear();
nodes_map.remove(ins);
delete ins;
}
QList<Result::DesNode*> ParseCore::queryStoryChain(const QString &name) const
{
QList<Result::DesNode*> retlist;
auto keys = nodes_map.keys();
for(auto &k : keys)
if(k->docType() == DocType::STORYCHAIN)
for(auto &n : *nodes_map[k]){
if(n->typeValue()==NODE_STORYCHAIN &&
static_cast<NamedNode*>(n)->name() == name)
retlist << n;
}
return retlist;
}
QList<Result::DesNode*> ParseCore::queryStoryPoint(DesNode *chain, const QString &name) const
{
QList<Result::DesNode*> retlist;
for(auto &n : chain->children())
if(n->typeValue() == NODE_STORYPOINT &&
static_cast<NamedNode*>(n)->name() == name)
retlist << n;
return retlist;
}
QList<Result::DesNode*> ParseCore::queryStoryUnit(const QString &name) const
{
QList<Result::DesNode*> retlist;
auto keys = nodes_map.keys();
for(auto &k : keys)
if(k->docType() == DocType::STORYUNIT)
for(auto &n : *nodes_map[k]){
if(n->typeValue()==NODE_STORYUNIT &&
static_cast<NamedNode*>(n)->name() == name)
retlist << n;
}
return retlist;
}
QList<Result::DesNode*> ParseCore::queryStoryFragment(DesNode *unit, const QString &name) const
{
QList<Result::DesNode*> retlist;
for(auto &n : unit->children())
if(n->typeValue() == NODE_STORYFRAGMENT &&
static_cast<NamedNode*>(n)->name() == name)
retlist << n;
return retlist;
}
QList<Result::DesNode*> ParseCore::queryStoryBoard(const QString &name) const
{
QList<Result::DesNode*> retlist;
auto keys = nodes_map.keys();
for(auto &k : keys)
if(k->docType() == DocType::STORYBOARD)
for(auto &n : *nodes_map[k]){
if(n->typeValue() == NODE_STORYBOARD &&
static_cast<NamedNode*>(n)->name() == name)
retlist << n;
}
return retlist;
}
QList<DesNode *> ParseCore::queryStoryDepiction(const QString &name) const
{
QList<Result::DesNode*> retlist;
for(auto &it : nodes_map.keys()) {
if(it->docType() == DocType::STORYOUTLINES)
for(auto &n : *nodes_map[it])
if(n->typeValue() == NODE_STORYDEPICTION &&
static_cast<NamedNode*>(n)->name() == name)
retlist << n;
}
return retlist;
}
Words::Words(Result::DesNode *host, DocCore *doc, const QString & value, int row, int col)
: value_store(value), row_store(row), col_store(col), desnode_store(host), docpresent_store(doc)
{
host->registerWords(this);
}
int Words::row() const
{
return row_store;
}
int Words::column() const
{
return col_store;
}
int Words::length() const
{
return value_store.length();
}
DesNode * Words::host() const
{
return desnode_store;
}
DocCore * Words::doc() const
{
return docpresent_store;
}
QString Words::toString() const
{
return value_store;
}
DocCore::DocCore(ParseCore * core, DocType type, const QFileInfo & path)
: unknown_host(new Unknown(this)), core_store(core),
file_path_store(path.absoluteFilePath()), type_store(type)
{
}
DesNode * DocCore::unknowns() const
{
return unknown_host;
}
ParseCore * DocCore::core() const
{
return core_store;
}
DocType DocCore::docType() const
{
return type_store;
}
QString DocCore::filePath() const
{
return file_path_store;
}
QString DocCore::fileName() const
{
return QFileInfo(file_path_store).fileName();
}
void DocCore::clear()
{
for(auto &it : words_store)
delete it;
words_store.clear();
core()->clearNodes(this);
}
int DocCore::append(Words * ins)
{
words_store << ins;
return 0;
}
Words * DocCore::getWords(int row, int col) const
{
for (auto it : words_store)
if (it->row() == row && it->column() <= col && it->column() + it->length() >= col)
return it;
return nullptr;
}

View File

@ -1,399 +0,0 @@
#pragma once
#include <QString>
#include <functional>
#include <QList>
#include <QHash>
#include <QFileInfo>
#include "LexFoundation.h"
#include "ComnDef.h"
namespace Parse
{
namespace Result {
class ParseCore;
class DesNode;
class NamedNode;
class DocCore;
}
namespace Result
{
/**
* .
*/
class Words
{
public:
explicit Words(Result::DesNode* host, Result::DocCore *doc, const QString &value, int row, int col);
virtual ~Words() = default;
/**
* .
*
* \return
*/
virtual int row() const;
/**
* .
*
* \return
*/
virtual int column() const;
/**
* .
*
* \return
*/
virtual int length() const;
/**
* nullptr.
*
* \return
*/
virtual Result::DesNode* host() const;
/**
* .
*
* \return
*/
virtual Result::DocCore* doc() const;
/**
* .
*
* \return
*/
virtual QString toString() const;
private:
QString value_store;
int row_store, col_store;
Result::DesNode *desnode_store;
Result::DocCore *docpresent_store;
};
/**
* .
*/
class DesNode
{
public:
DesNode(DocCore *core, int type_value, DesNode *pnode = nullptr);
virtual ~DesNode();
/**
* 0
*
* \return
*/
int depth() const;
/**
* .
*
* \return
*/
DocCore* doc() const;
/**
* .
*
* \return
*/
int typeValue() const;
/**
* .
*
* \return
*/
DesNode* parent() const;
/**
*
*
* \param ins
*/
void appendChild(DesNode *ins);
/**
*
*
* \return
*/
QList<DesNode*> children() const;
/**
* @brief
* @param ins
*/
void registerWords(Words *ins);
/**
* @brief
* @return
*/
QList<Words*> refered() const;
/**
* .
*
* \return true
*/
virtual bool check(QList<QString> &reasons) const = 0;
/**
* .
*
* \return
*/
virtual QString toString() const = 0;
private:
DocCore *const doc_store;
int type_value;
DesNode *const parent_node;
QList<DesNode*> children_nodes;
QList<Words*> words_collection;
};
/**
* .
*/
class NamedNode : public Result::DesNode
{
public:
NamedNode(const QString &name, DocCore *core, int type, DesNode *pnode = nullptr);
virtual ~NamedNode() = default;
/**
* .
*
* \return
*/
QString name() const;
private:
QString name_store;
};
enum class DocType
{
STORYBOARD = DOC_STORYBOARD,
STORYUNIT = DOC_STORYUNIT,
STORYCHAIN = DOC_STORYCHAIN,
STORYOUTLINES = DOC_VOLUMEOUTLINE
};
/**
* .
*/
class DocCore
{
public:
explicit DocCore(ParseCore* core, DocType type, const QFileInfo &path);
virtual ~DocCore() = default;
/**
* .
*
* \return
*/
Result::DesNode* unknowns() const;
/**
* .
*
* \return
*/
ParseCore* core() const;
/**
* @brief
* @return
*/
DocType docType() const;
/**
* .
*
* \return
*/
QString filePath() const;
/**
* .
*
* \return
*/
QString fileName() const;
/**
* .
*/
void clear();
/**
* .
*
* \param ins
* \return 0 -
*/
int append(Words *ins);
/**
* .
*
* \param row
* \param col
* \return
*/
Words* getWords(int row, int col) const;
private:
Result::DesNode *const unknown_host;
ParseCore *const core_store;
QString file_path_store;
DocType type_store;
QList<Words*> words_store;
};
/**
* .
*/
class ParseCore
{
private:
QString name_store;
QHash<DocCore*, QList<DesNode*>*> nodes_map;
public:
explicit ParseCore(const QString &name);
virtual ~ParseCore() = default;
virtual void registerNode(DocCore *doc, DesNode *node);
virtual void clearNodes(DocCore *ins);
virtual QList<DocCore *> allDocuments() const;
virtual QList<DesNode*> queryRootNodes(DocCore *doc) const;
/**
* nullptr.
*
* \param file_path
* \return
*/
virtual Result::DocCore* queryDocument(const QFileInfo &file_src) const;
virtual void deleteDocument(Result::DocCore *ins);
virtual QList<Result::DesNode*> queryStoryChain(const QString & name) const;
virtual QList<Result::DesNode*> queryStoryPoint(Result::DesNode* chain, const QString &name) const;
virtual QList<Result::DesNode*> queryStoryUnit(const QString &name) const;
virtual QList<Result::DesNode*> queryStoryFragment(Result::DesNode *unit, const QString &name) const;
virtual QList<Result::DesNode*> queryStoryBoard(const QString &name) const;
/**
* @brief
* @param name
* @return
*/
virtual QList<Result::DesNode*> queryStoryDepiction(const QString &name) const;
};
}
}
namespace Syntax {
/**
* .
*/
enum class ParseResult
{
SelfManipulate = 1,
EnterNext = 2,
Completed = 3,
Failed = 4,
};
/**
* .
*/
class SyntaxParser
{
public:
virtual ~SyntaxParser() = default;
/**
* Doc实例.
*
* \param ins
*/
virtual void docActive(Parse::Result::DocCore *ins) = 0;
/**
* .
*
* \return
*/
virtual Parse::Result::DocCore* docRef() const = 0;
/**
* .
*
* \param seqs
* \return
*/
virtual bool applied(const QList<Lex::LexResult>& seqs) = 0;
/**
*
*/
virtual void reset() = 0;
/**
* Token序列
*
* \param seqs
* \param next_ps
* \return
*/
virtual ParseResult parse(QList<Lex::LexResult>& seqs)= 0;
/**
* .
*
* \return
*/
virtual QList<SyntaxParser*> children() const = 0;
/**
* .
*
* \return
*/
virtual Parse::Result::DesNode* currNode() const = 0;
protected:
/**
* .
*
* \param parsers
*/
virtual void addChild(QList<SyntaxParser*> parsers) = 0;
};
}

View File

@ -1,49 +0,0 @@
#include "WordsPeak.h"
#include <QDebug>
using namespace Lex;
ExStream::ExStream() :file_target(nullptr), text_input(nullptr),
current_line(""), current_row(-1), current_col(0) {}
ExStream::~ExStream() {
if (file_target)
delete file_target;
if (text_input)
delete text_input;
}
int ExStream::initSource(const QString & path)
{
if (file_target)
delete file_target;
if (text_input)
delete text_input;
if (!QFile(path).exists())
return -1;
file_target = new QFile(path);
if (!file_target->open(QIODevice::ReadOnly | QIODevice::Text))
return -2;
text_input = new QTextStream(file_target);
return 0;
}
std::tuple<ExStream::n_row, ExStream::n_col, QChar> ExStream::read()
{
if (current_col >= current_line.length()) {
if (!text_input->atEnd()) {
current_row++;
current_col = 0;
current_line = text_input->readLine() + '\n';
}
else {
return std::make_tuple(-1, -1, EOF);
}
}
return std::make_tuple(current_row, current_col, current_line[current_col++]);
}

View File

@ -1,39 +0,0 @@
#pragma once
#include <QString>
#include <QTextStream>
#include <QFile>
#include <tuple>
namespace Lex {
class ExStream
{
public:
typedef int n_row;
typedef int n_col;
explicit ExStream();
virtual ~ExStream();
/**
* .
*
* \param path
* \return -2-10
*/
int initSource(const QString &path);
/**
* .
*
* \return
*/
std::tuple<n_row, n_col, QChar> read();
private:
QFile * file_target;
QTextStream* text_input;
QString current_line;
int current_row, current_col;
};
}

View File

@ -1,435 +0,0 @@
#include "XSyntaxBase.h"
using namespace Parse;
using namespace Parse::Result;
using namespace Syntax;
using namespace Lex;
using namespace Defines;
Link::Link(const QString & alias, Element * elm)
: alias_name(alias), host_ins(elm), tail_mark(false) {}
QString Link::aliasName() const { return alias_name; }
QString Link::refer() const
{
return name(this->aliasName());
}
QString Link::name(const QString & s)
{
QRegExp exp("^([^0-9]+)[0-9]*$");
if (exp.indexIn(s) == -1)
return "";
return exp.capturedTexts()[1];
}
Element * Link::host() const { return host_ins; }
bool Link::tailTest() const { return tail_mark; }
void Link::markTail(bool v)
{
tail_mark = v;
}
void Link::appendNext(Link * ins) { next_inss << ins; }
QList<Link*> Link::nextElements() const { return next_inss; }
std::tuple<Element::rst_mark, Element::match_len>
Link::linkCheck(const QList<LexResult>& tokens, int offset) const
{
// 本节点匹配失败,剩余标记长度不足
if (tokens.size() <= offset)
return std::make_tuple(false, 0);
// 节点元素匹配,获取匹配结果
auto rst0 = host()->elementCheck(tokens, offset);
if (!std::get<0>(rst0))
return rst0;
// 本节点匹配成功,尝试下一节点匹配,调用参数向下传递
for (auto inss : next_inss) {
auto rst1 = inss->linkCheck(tokens, offset + std::get<1>(rst0));
// 随后节点完全匹配,返回累积匹配结果
if (std::get<0>(rst1))
return std::make_tuple(true, std::get<1>(rst0) + std::get<1>(rst1));
}
// 解析链上的允许结尾,本节点是尾结点则成功,否则失败
if (tailTest())
return rst0;
else
return std::make_tuple(false, std::get<1>(rst0));
}
/**
* .
*
* \param tokens
* \param offset
* \return tuple()
*/
Element::Element(const QString & token)
: value_store(token) {}
QString Element::name() const
{
return Link::name(value_store);
}
DefType Element::type() const
{
return DefType::ELEMENT;
}
std::tuple<Element::rst_mark, Element::match_len>
Element::elementCheck(const QList<LexResult>& tokens, int offset) const
{
auto u = tokens[offset];
if (u.Token == name())
return std::make_tuple(true, 1);
return std::make_tuple(false, 0);
}
Expression::Expression(const QString & name)
: Element(name), name_store(name), chain_store(nullptr)
{
}
Link * Expression::parseFlow() const
{
return chain_store;
}
void Expression::resetLinks(Link * entry)
{
chain_store = entry;
}
DefType Expression::type() const
{
return DefType::EXPRESSION;
}
std::tuple<Element::rst_mark, Element::match_len>
Expression::elementCheck(const QList<LexResult>& tokens, int offset) const
{
if (!chain_store)
return std::make_tuple(false, 0);
return chain_store->linkCheck(tokens, offset);
}
ParseRule::ParseRule(XSyntaxBase * host, const QString & rule_name, unsigned short level,
std::function<ParseResult(const QList<LexResult>&, int)> exc)
: enable_state(true), host_ins(host), level_store(level),
name_store(rule_name), exc_store(exc) {}
int ParseRule::level() const
{
return level_store;
}
QString ParseRule::name() const
{
return name_store;
}
void ParseRule::setEnable(bool v)
{
this->enable_state = v;
}
void Syntax::ParseRule::addExpression(const QString &name, const QList<Elm> &defines)
{
// 生成表达式实例
auto exp = host_ins->get_expression(Link::name(name));
// 逐个构建表达式或者元素
QList<Link*> link_rebuilds;
for (auto& def_it : defines) {
// 校验既有元素回环
auto size0 = link_rebuilds.size();
for (auto prv_it : link_rebuilds) {
if (prv_it->aliasName() == def_it.aliasName()) {
link_rebuilds << prv_it;
break;
}
}
// 没有找到元素回环
if (size0 == link_rebuilds.size()) {
Link* tins = nullptr;
if (def_it.type() == DefType::ELEMENT)
tins = new Link(def_it.aliasName(), host_ins->get_element(def_it.refer()));
else
tins = new Link(def_it.aliasName(), host_ins->get_expression(def_it.refer()));
link_rebuilds << tins;
}
// 标记结尾可能性
if (!link_rebuilds.last()->tailTest())
link_rebuilds.last()->markTail(def_it.isTail());
}
// 匹配链构建
for (auto idx = 1; idx < link_rebuilds.size(); ++idx) {
auto prv_it = link_rebuilds[idx - 1];
prv_it->appendNext(link_rebuilds[idx]);
}
exp->resetLinks(link_rebuilds.first());
expression_list << exp;
}
std::tuple<bool, int> ParseRule::tokensMatch(const QList<LexResult>& token) const
{
if(enable_state)
for (auto expx : expression_list) {
auto result = expx->elementCheck(token, 0);
if (std::get<0>(result)) {
return std::make_tuple(true, std::get<1>(result));
}
}
return std::make_tuple(false, 0);
}
ParseResult ParseRule::syntaxTrigger(const QList<LexResult>& srcs, int count) {
return exc_store(srcs, count);
}
XSyntaxBase::XSyntaxBase(const QString & section, MatchType type)
: target_type(type), section_name(section), current_level(INT_MAX), current_node(nullptr) {}
ParseRule * XSyntaxBase::addRule(const QString & name, unsigned short level,
std::function<ParseResult(const QList<LexResult>&, int)> exc)
{
if (!rule_collect.contains(name)) {
auto rule = new ParseRule(this, name, level, exc);
rule_collect[name] = rule;
}
return rule_collect[name];
}
inline Expression * XSyntaxBase::get_expression(const QString & name) {
if (!expressions_store.contains(name)) {
auto u = new Expression(name);
expressions_store[name] = u;
}
return expressions_store[name];
}
inline Element * XSyntaxBase::get_element(const QString & name)
{
if (!elements_store.contains(name)) {
auto u = new Element(name);
elements_store[name] = u;
}
return elements_store[name];
}
void XSyntaxBase::addChild(QList<SyntaxParser*> parsers)
{
this->child_parsers.append(parsers);
}
void XSyntaxBase::docActive(DocCore * ins)
{
src_ref = ins;
for (auto &it : children())
it->docActive(ins);
}
DocCore * XSyntaxBase::docRef() const
{
return src_ref;
}
bool XSyntaxBase::applied(const QList<LexResult>& seqs)
{
// 求取最小等级的parse-rule
ParseRule* first_rule = *rule_collect.cbegin();
for (auto &rule : rule_collect) {
if (rule->level() <= first_rule->level())
first_rule = rule;
}
// 执行准入匹配,在最小等级匹配规则上进行匹配结算
for (auto &rule : rule_collect) {
if (rule->level() != first_rule->level())
continue;
auto result = rule->tokensMatch(seqs);
if (std::get<0>(result)) {
current_level = rule->level();
return true;
}
}
return false;
}
void XSyntaxBase::reset()
{
// 重置标记
current_level = INT_MAX;
for (auto &x : rule_collect)
if (current_level > x->level())
current_level = x->level();
current_node = nullptr;
}
ParseResult XSyntaxBase::parse(QList<LexResult>& seqs)
{
// 求取符合等级的parse-rule
QList<ParseRule*> rules_set;
for (auto &rule : rule_collect) {
if (rule->level() >= current_level)
rules_set << rule;
}
std::tuple<bool, int, ParseRule*> max_result = std::make_tuple(false, 0, nullptr);
// 使用符合等级的解析规则解析
for (auto &rule : rules_set) {
auto result = rule->tokensMatch(seqs);
if (std::get<0>(result) && current_level <= rule->level()) {
current_level = rule->level();
max_result = std::make_tuple(true, std::get<1>(result), rule);
}
}
if (!std::get<0>(max_result)) {
if (target_type == MatchType::Outline)
return ParseResult::Completed;
return ParseResult::Failed;
}
else { // 匹配成功
if (target_type == MatchType::Outline) {
if (current_node == nullptr) {
return std::get<2>(max_result)->syntaxTrigger(seqs, std::get<1>(max_result));
}
else {
return ParseResult::Completed;
}
}
else {
auto xresult = std::get<2>(max_result)->syntaxTrigger(seqs, std::get<1>(max_result));
if (target_type == MatchType::Entirely) {
auto count = std::get<1>(max_result);
while (count--)
seqs.removeFirst();
}
return xresult;
}
}
}
QList<SyntaxParser*> XSyntaxBase::children() const
{
return child_parsers;
}
void XSyntaxBase::refocusNode(DesNode * ins)
{
current_node = ins;
}
Expression *XSyntaxBase::set_common_expression(const QString &name, const QList<Defines::Elm> &defines)
{
if (expressions_store.contains(Link::name(name)))
return nullptr;
auto ins = get_expression(Link::name(name));
// 逐个构建表达式或者元素
QList<Link*> link_rebuilds;
for (auto& def_it : defines) {
// 校验既有元素回环
auto size0 = link_rebuilds.size();
for (auto prv_it : link_rebuilds) {
if (prv_it->aliasName() == def_it.aliasName()) {
link_rebuilds << prv_it;
break;
}
}
// 没有找到元素回环
if (size0 == link_rebuilds.size()) {
Link* tins = nullptr;
if (def_it.type() == DefType::ELEMENT)
tins = new Link(def_it.aliasName(), get_element(def_it.refer()));
else
tins = new Link(def_it.aliasName(), get_expression(def_it.refer()));
link_rebuilds << tins;
}
// 标记结尾可能性
link_rebuilds.last()->markTail(def_it.isTail());
}
// 匹配链构建
for (auto idx = 1; idx < link_rebuilds.size(); ++idx) {
auto prv_it = link_rebuilds[idx - 1];
prv_it->appendNext(link_rebuilds[idx]);
}
ins->resetLinks(link_rebuilds.first());
return ins;
}
void XSyntaxBase::resetMatch(MatchType mtype)
{
this->target_type = mtype;
}
DesNode * XSyntaxBase::currNode() const
{
return current_node;
}
Elm::Elm(const QString &alias_name, bool tail_mark)
: name_store(alias_name), tail_mark(tail_mark),
type_define(DefType::ELEMENT) {}
QString Elm::aliasName() const
{
return this->name_store;
}
QString Elm::refer() const
{
return Link::name(this->name_store);
}
bool Elm::isTail() const
{
return tail_mark;
}
DefType Elm::type() const
{
return type_define;
}
Exp::Exp(const QString& alias_name, bool tail_mark)
: Elm(alias_name, tail_mark)
{
type_define = DefType::EXPRESSION;
}
DefType Exp::type() const
{
return type_define;
}

View File

@ -1,256 +0,0 @@
#pragma once
#include <QString>
#include <QList>
#include <QHash>
#include "LexFoundation.h"
#include "SyntaxBase.h"
namespace Syntax
{
/**
*
*/
namespace Defines
{
/**
* @brief
*/
enum class DefType
{
ELEMENT,
EXPRESSION
};
/**
* .
*/
class Elm
{
public:
explicit Elm(const QString &alias_name, bool tail_mark = false);
virtual ~Elm() = default;
/**
* .
*
* \return
*/
QString aliasName() const;
/**
* .
*
* \return
*/
QString refer() const;
/**
* .
*
* \return
*/
virtual DefType type() const;
/**
* .
*
* \return
*/
bool isTail() const;
private:
QString name_store;
bool tail_mark;
protected:
DefType type_define;
};
/**
* .
*/
class Exp : public Elm
{
public:
explicit Exp(const QString &alias_name, bool tail_mark = false);
virtual ~Exp() = default;
virtual DefType type() const override;
};
}
/**
* token校验.
*/
class Element
{
public:
typedef bool rst_mark;
typedef int match_len;
explicit Element(const QString &token);
virtual ~Element() = default;
QString name() const;
virtual Defines::DefType type() const;
/**
* .
*
* \param tokens
* \param offset
* \return tuple()
*/
virtual std::tuple<rst_mark, match_len>
elementCheck(const QList<Lex::LexResult> &tokens, int offset) const;
private:
QString value_store;
};
/**
* @brief
*/
class Link
{
public:
Link(const QString &alias, Element *elm);
virtual ~Link() = default;
static QString name(const QString &s);
QString aliasName() const;
QString refer() const;
Element* host() const;
bool tailTest() const;
void markTail(bool v);
void appendNext(Link* ins);
QList<Link*> nextElements() const;
virtual std::tuple<Element::rst_mark, Element::match_len>
linkCheck(const QList<Lex::LexResult> &tokens, int offset) const;
private:
QString alias_name;
Element *const host_ins;
bool tail_mark;
QList<Link*> next_inss;
};
/**
* @brief
*/
class Expression : public Element
{
public:
explicit Expression(const QString &name);
virtual ~Expression() = default;
Link* parseFlow() const;
void resetLinks(Link* entry);
virtual Defines::DefType type() const override;
/**
* .
*
* \param tokens
* \param offset
* \return tuple()
*/
virtual std::tuple<rst_mark, match_len>
elementCheck(const QList<Lex::LexResult> &tokens, int offset) const override;
private:
QString name_store;
Link* chain_store;
};
class XSyntaxBase;
/**
* @brief
*/
class ParseRule
{
public:
ParseRule(XSyntaxBase *host, const QString &rule_name, unsigned short level,
std::function<ParseResult(const QList<Lex::LexResult>&, int)>);
virtual ~ParseRule() = default;
int level() const;
QString name() const;
void setEnable(bool v);
void addExpression(const QString &name, const QList<Defines::Elm> &_defines);
std::tuple<bool, int> tokensMatch(const QList<Lex::LexResult> &token) const;
ParseResult syntaxTrigger(const QList<Lex::LexResult>& srcs, int count);
private:
bool enable_state;
XSyntaxBase *const host_ins;
int level_store;
QString name_store;
QList<Expression*> expression_list;
std::function<ParseResult(const QList<Lex::LexResult>&, int)> exc_store;
};
/**
* @brief
*/
enum class MatchType
{
Outline,
Entirely
};
/**
* .
*/
class XSyntaxBase : public Syntax::SyntaxParser
{
public:
explicit XSyntaxBase(const QString &section, MatchType type = MatchType::Entirely);
Expression* get_expression(const QString &name);
Element *get_element(const QString &name);
// 通过 Parse::SyntaxParser 继承
virtual void docActive(Parse::Result::DocCore *ins) override;
virtual Parse::Result::DocCore *docRef() const override;
virtual bool applied(const QList<Lex::LexResult>& seqs) override;
virtual void reset() override;
virtual ParseResult parse(QList<Lex::LexResult>& seqs) override;
virtual QList<Syntax::SyntaxParser*> children() const override;
virtual Parse::Result::DesNode * currNode() const override;
protected:
ParseRule* addRule(const QString &name, unsigned short level, std::function<ParseResult(const QList<Lex::LexResult>&, int)> exc);
virtual void addChild(QList<Syntax::SyntaxParser*> parsers) override;
void refocusNode(Parse::Result::DesNode *ins);
Expression* set_common_expression(const QString &name, const QList<Defines::Elm> &defines);
void resetMatch(MatchType mtype);
private:
MatchType target_type;
QString section_name;
int current_level;
Parse::Result::DesNode *current_node;
Parse::Result::DocCore *src_ref;
QHash<QString, Element*> elements_store;
QHash<QString, Expression*> expressions_store;
QList<Syntax::SyntaxParser*> child_parsers;
QHash<QString, ParseRule*> rule_collect;
};
}