This commit is contained in:
玉宇清音 2023-03-25 10:10:32 +08:00
parent a7b92805f1
commit 4dd5a0e728
20 changed files with 496 additions and 411 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.15.0, 2023-03-18T21:33:06. --> <!-- Written by QtCreator 4.15.0, 2023-03-24T01:07:04. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

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 + match_len;
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,5 +1,5 @@
#include "ParseFrame.h" #include "ParseFrame.h"
#include "WordsPeak.h" #include "lex_foundation.h"
using namespace Parse; using namespace Parse;
using namespace Parse::Result; using namespace Parse::Result;
@ -17,7 +17,7 @@ QList<DesNode*> ParseFrame::analysis(DocCore*doc, const QString & path)
LexFoundation token_s(this->token_seqs, this->unknown_token); LexFoundation token_s(this->token_seqs, this->unknown_token);
QList<LexResult> lex_seqence; QList<Token> lex_seqence;
std::tuple<int, int, QChar> temp; std::tuple<int, int, QChar> temp;
while ((std::get<2>(temp = stream.read())) != EOF) while ((std::get<2>(temp = stream.read())) != EOF)
{ {
@ -58,7 +58,7 @@ QList<DesNode *> ParseFrame::analysisSource(Parse::Result::DocCore *doc, const Q
LexFoundation token_s(this->token_seqs, this->unknown_token); LexFoundation token_s(this->token_seqs, this->unknown_token);
QList<LexResult> lex_seqence; QList<Token> lex_seqence;
std::tuple<int, int, QChar> temp; std::tuple<int, int, QChar> temp;
while ((std::get<2>(temp = stream.read())) != EOF) while ((std::get<2>(temp = stream.read())) != EOF)
{ {
@ -92,8 +92,7 @@ QList<DesNode *> ParseFrame::analysisSource(Parse::Result::DocCore *doc, const Q
return xrets; return xrets;
} }
void ParseFrame::appendTokensDefine(QList<LexDef> seqs, const QString & unknown_token) void ParseFrame::appendTokensDefine(QList<TokenDef> seqs, const QString &unknown_token) {
{
this->unknown_token = unknown_token; this->unknown_token = unknown_token;
token_seqs.append(seqs); token_seqs.append(seqs);
} }
@ -103,8 +102,7 @@ void ParseFrame::appendParser(SyntaxParser * u)
cascade_parsers << u; cascade_parsers << u;
} }
ParseResult ParseFrame::inner_parse(QList<LexResult> &lex_seqence, QList<SyntaxParser*> parsers, QList<DesNode*> &nodes_out) ParseResult ParseFrame::inner_parse(QList<Token> &lex_seqence, QList<SyntaxParser *> parsers, QList<DesNode *> &nodes_out) {
{
QList<DesNode*> nodes; QList<DesNode*> nodes;
if(lex_seqence.size()) if(lex_seqence.size())

View File

@ -1,7 +1,8 @@
#pragma once #pragma once
#include <QString>
#include <QList>
#include "SyntaxBase.h" #include "SyntaxBase.h"
#include "lex_foundation.h"
#include <QList>
#include <QString>
namespace Syntax namespace Syntax
{ {
@ -18,15 +19,17 @@ namespace Syntax
QList<Parse::Result::DesNode*> analysisSource(Parse::Result::DocCore *doc, const QString &src); QList<Parse::Result::DesNode*> analysisSource(Parse::Result::DocCore *doc, const QString &src);
protected: protected:
void appendTokensDefine(QList<Lex::LexDef> seqs, const QString &unknown_token); void appendTokensDefine(QList<Lex::TokenDef> seqs, const QString &unknown_token);
void appendParser(Syntax::SyntaxParser* u); void appendParser(Syntax::SyntaxParser *u);
private: private:
QString unknown_token; Lex::TokensReader *const tokens_in;
QList<Lex::LexDef> token_seqs;
QString unknown_token;
QList<Lex::TokenDef *> token_seqs;
QList<SyntaxParser*> cascade_parsers; QList<SyntaxParser*> cascade_parsers;
ParseResult ParseFrame::inner_parse(QList<Lex::LexResult> &lex_seqence, ParseResult ParseFrame::inner_parse(QList<Lex::Token> &lex_seqence,
QList<Syntax::SyntaxParser*> parsers, QList<Syntax::SyntaxParser*> parsers,
QList<Parse::Result::DesNode*> &nodes_out); QList<Parse::Result::DesNode*> &nodes_out);
}; };

View File

@ -130,7 +130,7 @@ NodeStoryBoardParser::NodeStoryBoardParser(Result::ParseCore *core)
:Syntax::XSyntaxBase("情节引用"), project_ins(core) :Syntax::XSyntaxBase("情节引用"), project_ins(core)
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)});
auto rule = addRule("进入作品解析", 0, [this](const QList<LexResult> &seqs, int cnt)->ParseResult auto rule = addRule("进入作品解析", 0, [this](const QList<Token> &seqs, int cnt)->ParseResult
{ {
auto mbunit = seqs[cnt-1]; auto mbunit = seqs[cnt-1];
auto nmunit = seqs[cnt-2]; auto nmunit = seqs[cnt-2];
@ -151,7 +151,7 @@ NodeStoryBoardParser::NodeStoryBoardParser(Result::ParseCore *core)
rule->addExpression("基础故事定义", {Elm("{故事定义}"), Elm("{描述文本}1"), Elm("{描述文本}2", true)}); rule->addExpression("基础故事定义", {Elm("{故事定义}"), Elm("{描述文本}1"), Elm("{描述文本}2", true)});
rule->addExpression("拓展故事定义", {Exp("::换行前缀"), Exp("基础故事定义", true)}); rule->addExpression("拓展故事定义", {Exp("::换行前缀"), Exp("基础故事定义", true)});
rule = addRule("进入成分解析", 1, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("进入成分解析", 1, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);
@ -162,7 +162,7 @@ NodeStoryBoardParser::NodeStoryBoardParser(Result::ParseCore *core)
rule->addExpression("基础成分解析", { Elm("{左界限}", true) }); rule->addExpression("基础成分解析", { Elm("{左界限}", true) });
rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) }); rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) });
rule = addRule("跳出成分解析", 2, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("跳出成分解析", 2, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);
@ -200,7 +200,7 @@ NodeStoryFragmentReferParser::NodeStoryFragmentReferParser(XSyntaxBase *parent)
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"), Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"), Elm("{换行符}", true)});
auto rule = addRule("进入情节引用", 0, [this, parent](const QList<LexResult> &seqs, int cnt)->ParseResult auto rule = addRule("进入情节引用", 0, [this, parent](const QList<Token> &seqs, int cnt)->ParseResult
{ {
auto unit_u = seqs[cnt-1]; auto unit_u = seqs[cnt-1];
auto name_u = seqs[cnt-2]; auto name_u = seqs[cnt-2];
@ -224,7 +224,7 @@ NodeStoryFragmentReferParser::NodeStoryFragmentReferParser(XSyntaxBase *parent)
rule->addExpression("基础情节定义", {Elm("{情节引用}"), Elm("{描述文本}1"), Elm("{描述文本}2", true)}); rule->addExpression("基础情节定义", {Elm("{情节引用}"), Elm("{描述文本}1"), Elm("{描述文本}2", true)});
rule->addExpression("拓展情节定义", {Exp("::换行前缀"), Exp("基础情节定义", true)}); rule->addExpression("拓展情节定义", {Exp("::换行前缀"), Exp("基础情节定义", true)});
rule = addRule("进入成分解析", 1, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("进入成分解析", 1, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);
@ -235,7 +235,7 @@ NodeStoryFragmentReferParser::NodeStoryFragmentReferParser(XSyntaxBase *parent)
rule->addExpression("基础成分解析", { Elm("{左界限}", true) }); rule->addExpression("基础成分解析", { Elm("{左界限}", true) });
rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) }); rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) });
rule = addRule("跳出成分解析", 2, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("跳出成分解析", 2, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);

View File

@ -12,8 +12,7 @@ NodeStoryChainParser::NodeStoryChainParser(ParseCore *core)
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)});
auto rule = addRule("文学脉络定义", 0, [this](const QList<LexResult> &seqs, int cnt)->ParseResult auto rule = addRule("文学脉络定义", 0, [this](const QList<Token> &seqs, int cnt) -> ParseResult {
{
auto nmidx = cnt - 1, defidx = cnt - 2; auto nmidx = cnt - 1, defidx = cnt - 2;
// 构建语法节点 // 构建语法节点
@ -27,14 +26,11 @@ NodeStoryChainParser::NodeStoryChainParser(ParseCore *core)
docRef()->append(words1); docRef()->append(words1);
return ParseResult::SelfManipulate; return ParseResult::SelfManipulate;
}); });
rule->addExpression("脉络定义基础", { Elm("{脉络定义}"), Elm("{描述文本}", true) }); rule->addExpression("脉络定义基础", { Elm("{脉络定义}"), Elm("{描述文本}", true) });
rule->addExpression("脉络定义拓展", { Exp("::换行前缀"), Exp("脉络定义基础", true)}); rule->addExpression("脉络定义拓展", { Exp("::换行前缀"), Exp("脉络定义基础", true)});
rule = addRule("脉络成分解析", 1, [this](const QList<Token> &seqs, int cnt) -> ParseResult {
rule = addRule("脉络成分解析", 1, [this](const QList<LexResult> &seqs, int cnt)->ParseResult
{
auto nmidx = cnt - 1; auto nmidx = cnt - 1;
// 获取语法节点 // 获取语法节点
@ -45,14 +41,11 @@ NodeStoryChainParser::NodeStoryChainParser(ParseCore *core)
docRef()->append(word); docRef()->append(word);
return ParseResult::EnterNext; return ParseResult::EnterNext;
}); });
rule->addExpression("基础脉络界限", { Elm("{左界限}", true) }); rule->addExpression("基础脉络界限", { Elm("{左界限}", true) });
rule->addExpression("拓展脉络界限", { Exp("::换行前缀"), Exp("基础脉络界限", true) }); rule->addExpression("拓展脉络界限", { Exp("::换行前缀"), Exp("基础脉络界限", true) });
rule = addRule("完成脉络解析", 2, [this](const QList<Token> &seqs, int cnt) -> ParseResult {
rule = addRule("完成脉络解析", 2, [this](const QList<LexResult> &seqs, int cnt)->ParseResult
{
auto nmidx = cnt - 1; auto nmidx = cnt - 1;
// 获取语法节点 // 获取语法节点
@ -63,7 +56,7 @@ NodeStoryChainParser::NodeStoryChainParser(ParseCore *core)
docRef()->append(word); docRef()->append(word);
return ParseResult::Completed; return ParseResult::Completed;
}); });
rule->addExpression("基础脉络跳出", { Elm("{右界限}", true) }); rule->addExpression("基础脉络跳出", { Elm("{右界限}", true) });
rule->addExpression("拓展脉络跳出", { Exp("::换行前缀"), Exp("基础脉络跳出", true) }); rule->addExpression("拓展脉络跳出", { Exp("::换行前缀"), Exp("基础脉络跳出", true) });
@ -81,8 +74,8 @@ NodeStoryPointParser::NodeStoryPointParser(NodeStoryChainParser *chain)
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)});
auto rule = addRule("脉络驻点定义", 0, [this](const QList<LexResult> &seqs, int c)->ParseResult { auto rule = addRule("脉络驻点定义", 0, [this](const QList<Token> &seqs, int c) -> ParseResult {
auto nmidx = c - 1, defidx = c - 2; auto nmidx = c - 1, defidx = c - 2;
// 语法节点定义 // 语法节点定义
auto node = this->storyChainParser()->currNode(); auto node = this->storyChainParser()->currNode();
@ -97,33 +90,27 @@ NodeStoryPointParser::NodeStoryPointParser(NodeStoryChainParser *chain)
node->doc()->append(word1); node->doc()->append(word1);
return ParseResult::SelfManipulate; return ParseResult::SelfManipulate;
}); });
rule->addExpression("基础节点定义", { Elm("{节点定义}"), Elm("{描述文本}", true) }); rule->addExpression("基础节点定义", { Elm("{节点定义}"), Elm("{描述文本}", true) });
rule->addExpression("拓展节点定义", { Exp("::换行前缀"), Exp("基础节点定义", true) }); rule->addExpression("拓展节点定义", { Exp("::换行前缀"), Exp("基础节点定义", true) });
rule = addRule("节点成分解析", 1, [this](const QList<Token> &seqs, int cnt) -> ParseResult {
rule = addRule("节点成分解析", 1, [this](const QList<LexResult> &seqs, int cnt)->ParseResult
{
auto nmidx = cnt - 1; auto nmidx = cnt - 1;
auto word = new Words(this->currNode(), this->storyChainParser()->docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); auto word = new Words(this->currNode(), this->storyChainParser()->docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol);
this->docRef()->append(word); this->docRef()->append(word);
return ParseResult::EnterNext; return ParseResult::EnterNext;
}); });
rule->addExpression("基础节点界限", { Elm("{左界限}", true) }); rule->addExpression("基础节点界限", { Elm("{左界限}", true) });
rule->addExpression("拓展节点界限", { Exp("::换行前缀"), Exp("基础节点界限", true) }); rule->addExpression("拓展节点界限", { Exp("::换行前缀"), Exp("基础节点界限", true) });
rule = addRule("完成节点解析", 2, [this](const QList<Token> &seqs, int cnt) -> ParseResult {
rule = addRule("完成节点解析", 2, [this](const QList<LexResult> &seqs, int cnt)->ParseResult
{
auto nmidx = cnt - 1; auto nmidx = cnt - 1;
auto word = new Words(this->currNode(), this->storyChainParser()->docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); auto word = new Words(this->currNode(), this->storyChainParser()->docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol);
this->docRef()->append(word); this->docRef()->append(word);
return ParseResult::Completed; return ParseResult::Completed;
}); });
rule->addExpression("基础节点跳出", { Elm("{右界限}", true) }); rule->addExpression("基础节点跳出", { Elm("{右界限}", true) });
rule->addExpression("拓展节点跳出", { Exp("::换行前缀"), Exp("基础节点跳出", true) }); rule->addExpression("拓展节点跳出", { Exp("::换行前缀"), Exp("基础节点跳出", true) });
@ -255,8 +242,8 @@ NodeStoryPureTextDesGroupParser::NodeStoryPureTextDesGroupParser(XSyntaxBase * p
: XSyntaxBase("描述块"), parent_parser(pparser) : XSyntaxBase("描述块"), parent_parser(pparser)
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)});
auto rule = addRule("提取文本", 0, [this, pparser](const QList<LexResult> &seqs, int cnt)->ParseResult { auto rule = addRule("提取文本", 0, [this, pparser](const QList<Token> &seqs, int cnt) -> ParseResult {
auto curr_node = new NodeStoryDesGroup(pparser->currNode()); auto curr_node = new NodeStoryDesGroup(pparser->currNode());
refocusNode(curr_node); refocusNode(curr_node);
pparser->currNode()->appendChild(curr_node); pparser->currNode()->appendChild(curr_node);
@ -269,7 +256,7 @@ NodeStoryPureTextDesGroupParser::NodeStoryPureTextDesGroupParser(XSyntaxBase * p
} }
return ParseResult::Completed; return ParseResult::Completed;
}); });
rule->addExpression("基础提取文本", { Elm("{描述文本}"), Elm("{描述文本}", true) }); rule->addExpression("基础提取文本", { Elm("{描述文本}"), Elm("{描述文本}", true) });
rule->addExpression("拓展提取文本", { Exp("::换行前缀"), Exp("基础提取文本", true) }); rule->addExpression("拓展提取文本", { Exp("::换行前缀"), Exp("基础提取文本", true) });

View File

@ -26,7 +26,7 @@ NodeStoryDepictionParser::NodeStoryDepictionParser(Result::ParseCore *core)
: XSyntaxBase("叙事节点") : XSyntaxBase("叙事节点")
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)});
auto rule = addRule("进入卷宗叙事", 0, [this](const QList<LexResult> &seqs, int cnt)->ParseResult{ auto rule = addRule("进入卷宗叙事", 0, [this](const QList<Token> &seqs, int cnt)->ParseResult{
auto nmunit = seqs[cnt-1]; auto nmunit = seqs[cnt-1];
auto defunit = seqs[cnt-2]; auto defunit = seqs[cnt-2];
@ -44,7 +44,7 @@ NodeStoryDepictionParser::NodeStoryDepictionParser(Result::ParseCore *core)
rule->addExpression("拓展叙述", {Exp("{::换行前缀}"), Exp("基本叙述")}); rule->addExpression("拓展叙述", {Exp("{::换行前缀}"), Exp("基本叙述")});
rule = addRule("进入成分解析", 1, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("进入成分解析", 1, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);
@ -56,7 +56,7 @@ NodeStoryDepictionParser::NodeStoryDepictionParser(Result::ParseCore *core)
rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) }); rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) });
rule = addRule("跳出成分解析", 2, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("跳出成分解析", 2, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);

View File

@ -147,7 +147,7 @@ NodeStoryUnitParser::NodeStoryUnitParser(ParseCore * core)
: XSyntaxBase("故事单元"), pjt_core(core) : XSyntaxBase("故事单元"), pjt_core(core)
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)});
auto rule = addRule("进入单元解析", 0, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { auto rule = addRule("进入单元解析", 0, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto nmidx = cnt - 1, defidx = cnt - 2;; auto nmidx = cnt - 1, defidx = cnt - 2;;
auto node = new NodeStoryUnit(this->docRef(), seqs[nmidx].Text); auto node = new NodeStoryUnit(this->docRef(), seqs[nmidx].Text);
@ -163,7 +163,7 @@ NodeStoryUnitParser::NodeStoryUnitParser(ParseCore * core)
rule->addExpression("基础单元解析", { Elm("{单元定义}"), Elm("{描述文本}", true) }); rule->addExpression("基础单元解析", { Elm("{单元定义}"), Elm("{描述文本}", true) });
rule->addExpression("拓展单元解析", { Exp("::换行前缀"), Exp("基础单元解析", true) }); rule->addExpression("拓展单元解析", { Exp("::换行前缀"), Exp("基础单元解析", true) });
rule = addRule("单元成分解析", 1, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("单元成分解析", 1, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);
@ -174,7 +174,7 @@ NodeStoryUnitParser::NodeStoryUnitParser(ParseCore * core)
rule->addExpression("基础单元成分解析", { Elm("{左界限}", true) }); rule->addExpression("基础单元成分解析", { Elm("{左界限}", true) });
rule->addExpression("拓展单元成分解析", { Exp("::换行前缀"), Exp("基础单元成分解析", true) }); rule->addExpression("拓展单元成分解析", { Exp("::换行前缀"), Exp("基础单元成分解析", true) });
rule = addRule("跳出单元成分解析", 2, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("跳出单元成分解析", 2, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);
@ -214,7 +214,7 @@ NodeStoryFragmentParser::NodeStoryFragmentParser(NodeStoryUnitParser * pparser)
: XSyntaxBase("故事情节"), parent_parser(pparser) : XSyntaxBase("故事情节"), parent_parser(pparser)
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)});
auto rule = addRule("进入情节解析", 0, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { auto rule = addRule("进入情节解析", 0, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto nmidx = cnt - 2, defidx = cnt - 3, ordidx=cnt-1; auto nmidx = cnt - 2, defidx = cnt - 3, ordidx=cnt-1;
auto parent_parser = nodeStoryUnitParser(); auto parent_parser = nodeStoryUnitParser();
@ -236,7 +236,7 @@ NodeStoryFragmentParser::NodeStoryFragmentParser(NodeStoryUnitParser * pparser)
rule->addExpression("基础情节解析", { Elm("{情节定义}"), Elm("{描述文本}1"), Elm("{描述文本}2", true) }); rule->addExpression("基础情节解析", { Elm("{情节定义}"), Elm("{描述文本}1"), Elm("{描述文本}2", true) });
rule->addExpression("拓展情节解析", { Exp("::换行前缀"), Exp("基础情节解析", true) }); rule->addExpression("拓展情节解析", { Exp("::换行前缀"), Exp("基础情节解析", true) });
rule = addRule("情节成分解析", 1, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("情节成分解析", 1, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);
@ -247,7 +247,7 @@ NodeStoryFragmentParser::NodeStoryFragmentParser(NodeStoryUnitParser * pparser)
rule->addExpression("基础情节成分解析", { Elm("{左界限}", true) }); rule->addExpression("基础情节成分解析", { Elm("{左界限}", true) });
rule->addExpression("拓展情节成分解析", { Exp("::换行前缀"), Exp("基础情节成分解析", true) }); rule->addExpression("拓展情节成分解析", { Exp("::换行前缀"), Exp("基础情节成分解析", true) });
rule = addRule("跳出情节成分解析", 2, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("跳出情节成分解析", 2, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);
@ -280,7 +280,7 @@ NodeStoryMixedDesGroupParser::NodeStoryMixedDesGroupParser(XSyntaxBase * parent)
set_common_expression("::基础引用定义", { Elm("{节点引用}"),Elm("{描述文本}1"), Elm("{描述文本}2"), Elm("{右界限}", true) }); set_common_expression("::基础引用定义", { Elm("{节点引用}"),Elm("{描述文本}1"), Elm("{描述文本}2"), Elm("{右界限}", true) });
set_common_expression("::基础文本块定义", {Elm("{描述文本}"), Elm("{描述文本}", true) }); set_common_expression("::基础文本块定义", {Elm("{描述文本}"), Elm("{描述文本}", true) });
auto rule = addRule("进入描述块解析", 0, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { auto rule = addRule("进入描述块解析", 0, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto state = seqs[0].Token == QString("{换行符}"); auto state = seqs[0].Token == QString("{换行符}");
unique_tidy->setMatchEnable(state); unique_tidy->setMatchEnable(state);
@ -308,7 +308,7 @@ NodeStoryTextSpanParser::NodeStoryTextSpanParser(XSyntaxBase *parent)
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)});
auto rule = addRule("解析TextSpan", 0, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { auto rule = addRule("解析TextSpan", 0, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto pnode = parent_parser->currNode(); auto pnode = parent_parser->currNode();
for(auto idx=0; idx<cnt; ++idx){ for(auto idx=0; idx<cnt; ++idx){
DesNode *node = docRef()->unknowns(); DesNode *node = docRef()->unknowns();
@ -333,7 +333,7 @@ NodeStoryPointReferParser::NodeStoryPointReferParser(XSyntaxBase *parent)
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)});
auto rule = addRule("解析节点引用", 0, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { auto rule = addRule("解析节点引用", 0, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto pnode = parent_parser->currNode(); auto pnode = parent_parser->currNode();
auto chain_unit = seqs[cnt-3]; auto chain_unit = seqs[cnt-3];
auto point_unit = seqs[cnt-2]; auto point_unit = seqs[cnt-2];
@ -425,7 +425,7 @@ NodeStoryPointReferParser::NodeStoryPointReferParser(XSyntaxBase *parent)
NodeStoryLinePrefixParser::NodeStoryLinePrefixParser(SyntaxParser *pparent) NodeStoryLinePrefixParser::NodeStoryLinePrefixParser(SyntaxParser *pparent)
: Syntax::XSyntaxBase("换行符清理", MatchType::Entirely), critical_rule(nullptr) : Syntax::XSyntaxBase("换行符清理", MatchType::Entirely), critical_rule(nullptr)
{ {
critical_rule = addRule("清理换行符", 0, [this](const QList<LexResult> &seqs, int cnt)->ParseResult critical_rule = addRule("清理换行符", 0, [this](const QList<Token> &seqs, int cnt)->ParseResult
{ {
this->setMatchEnable(false); this->setMatchEnable(false);
return ParseResult::Completed; return ParseResult::Completed;

View File

@ -2,7 +2,7 @@
#define SYNTAXBASE_H #define SYNTAXBASE_H
#include "libParse.h" #include "libParse.h"
#include "LexFoundation.h" #include "lex_foundation.h"
namespace Syntax { namespace Syntax {
@ -46,7 +46,7 @@ namespace Syntax {
* \param seqs * \param seqs
* \return * \return
*/ */
virtual bool applied(const QList<Lex::LexResult>& seqs) = 0; virtual bool applied(const QList<Lex::Token>& seqs) = 0;
/** /**
* *
@ -60,7 +60,7 @@ namespace Syntax {
* \param next_ps * \param next_ps
* \return * \return
*/ */
virtual ParseResult parse(QList<Lex::LexResult>& seqs)= 0; virtual ParseResult parse(QList<Lex::Token>& seqs)= 0;
/** /**
* . * .

View File

@ -1,61 +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);
text_input->setCodec("UTF-8");
return 0;
}
void ExStream::setSourceCode(const QString &codes)
{
if (file_target)
delete file_target;
if (text_input)
delete text_input;
this->contents_temp = codes;
this->text_input = new QTextStream(&this->contents_temp, QIODevice::ReadOnly);
}
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,46 +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);
/**
* @brief
* @param codes
*/
void setSourceCode(const QString &codes);
/**
* .
*
* \return
*/
std::tuple<n_row, n_col, QChar> read();
private:
QFile * file_target;
QString contents_temp;
QTextStream* text_input;
QString current_line;
int current_row, current_col;
};
}

View File

@ -38,7 +38,7 @@ void Link::appendNext(Link * ins) { next_inss << ins; }
QList<Link*> Link::nextElements() const { return next_inss; } QList<Link*> Link::nextElements() const { return next_inss; }
std::tuple<Element::rst_mark, Element::match_len> std::tuple<Element::rst_mark, Element::match_len>
Link::linkCheck(const QList<LexResult>& tokens, int offset) const Link::linkCheck(const QList<Token>& tokens, int offset) const
{ {
// 本节点匹配失败,剩余标记长度不足 // 本节点匹配失败,剩余标记长度不足
if (tokens.size() <= offset) if (tokens.size() <= offset)
@ -87,7 +87,7 @@ DefType Element::type() const
} }
std::tuple<Element::rst_mark, Element::match_len> std::tuple<Element::rst_mark, Element::match_len>
Element::elementCheck(const QList<LexResult>& tokens, int offset) const Element::elementCheck(const QList<Token>& tokens, int offset) const
{ {
auto u = tokens[offset]; auto u = tokens[offset];
@ -117,7 +117,7 @@ DefType Expression::type() const
} }
std::tuple<Element::rst_mark, Element::match_len> std::tuple<Element::rst_mark, Element::match_len>
Expression::elementCheck(const QList<LexResult>& tokens, int offset) const Expression::elementCheck(const QList<Token>& tokens, int offset) const
{ {
if (!chain_store) if (!chain_store)
return std::make_tuple(false, 0); return std::make_tuple(false, 0);
@ -188,7 +188,7 @@ void Syntax::ParseRule::addExpression(const QString &name, const QList<Elm> &def
expression_list << exp; expression_list << exp;
} }
std::tuple<bool, int> ParseRule::tokensMatch(const QList<LexResult>& token) const std::tuple<bool, int> ParseRule::tokensMatch(const QList<Token>& token) const
{ {
if(enable_state) if(enable_state)
for (auto expx : expression_list) { for (auto expx : expression_list) {
@ -201,7 +201,7 @@ std::tuple<bool, int> ParseRule::tokensMatch(const QList<LexResult>& token) cons
return std::make_tuple(false, 0); return std::make_tuple(false, 0);
} }
ParseResult ParseRule::syntaxTrigger(const QList<LexResult>& srcs, int count) { ParseResult ParseRule::syntaxTrigger(const QList<Token>& srcs, int count) {
return exc_store(srcs, count); return exc_store(srcs, count);
} }
@ -252,7 +252,7 @@ DocCore * XSyntaxBase::docRef() const
return src_ref; return src_ref;
} }
bool XSyntaxBase::applied(const QList<LexResult>& seqs) bool XSyntaxBase::applied(const QList<Token>& seqs)
{ {
if(!seqs.size()) if(!seqs.size())
return false; return false;
@ -292,7 +292,7 @@ void XSyntaxBase::reset()
current_node = nullptr; current_node = nullptr;
} }
ParseResult XSyntaxBase::parse(QList<LexResult>& seqs) ParseResult XSyntaxBase::parse(QList<Token>& seqs)
{ {
if(!seqs.size()) if(!seqs.size())
return ParseResult::Failed; return ParseResult::Failed;

View File

@ -3,7 +3,7 @@
#include <QList> #include <QList>
#include <QHash> #include <QHash>
#include <functional> #include <functional>
#include "LexFoundation.h" #include "lex_foundation.h"
#include "SyntaxBase.h" #include "SyntaxBase.h"
namespace Syntax namespace Syntax
@ -102,7 +102,7 @@ namespace Syntax
* \return tuple() * \return tuple()
*/ */
virtual std::tuple<rst_mark, match_len> virtual std::tuple<rst_mark, match_len>
elementCheck(const QList<Lex::LexResult> &tokens, int offset) const; elementCheck(const QList<Lex::Token> &tokens, int offset) const;
private: private:
QString value_store; QString value_store;
@ -129,7 +129,7 @@ namespace Syntax
QList<Link*> nextElements() const; QList<Link*> nextElements() const;
virtual std::tuple<Element::rst_mark, Element::match_len> virtual std::tuple<Element::rst_mark, Element::match_len>
linkCheck(const QList<Lex::LexResult> &tokens, int offset) const; linkCheck(const QList<Lex::Token> &tokens, int offset) const;
private: private:
QString alias_name; QString alias_name;
@ -161,7 +161,7 @@ namespace Syntax
* \return tuple() * \return tuple()
*/ */
virtual std::tuple<rst_mark, match_len> virtual std::tuple<rst_mark, match_len>
elementCheck(const QList<Lex::LexResult> &tokens, int offset) const override; elementCheck(const QList<Lex::Token> &tokens, int offset) const override;
private: private:
QString name_store; QString name_store;
@ -187,8 +187,8 @@ namespace Syntax
void setEnable(bool v); void setEnable(bool v);
void addExpression(const QString &name, const QList<Defines::Elm> &_defines); void addExpression(const QString &name, const QList<Defines::Elm> &_defines);
std::tuple<bool, int> tokensMatch(const QList<Lex::LexResult> &token) const; std::tuple<bool, int> tokensMatch(const QList<Lex::Token> &token) const;
ParseResult syntaxTrigger(const QList<Lex::LexResult>& srcs, int count); ParseResult syntaxTrigger(const QList<Lex::Token>& srcs, int count);
private: private:
bool enable_state; bool enable_state;
@ -224,9 +224,9 @@ namespace Syntax
// 通过 Parse::SyntaxParser 继承 // 通过 Parse::SyntaxParser 继承
virtual void docActive(Parse::Result::DocCore *ins) override; virtual void docActive(Parse::Result::DocCore *ins) override;
virtual Parse::Result::DocCore *docRef() const override; virtual Parse::Result::DocCore *docRef() const override;
virtual bool applied(const QList<Lex::LexResult>& seqs) override; virtual bool applied(const QList<Lex::Token>& seqs) override;
virtual void reset() override; virtual void reset() override;
virtual ParseResult parse(QList<Lex::LexResult>& seqs) override; virtual ParseResult parse(QList<Lex::Token>& seqs) override;
virtual QList<Syntax::SyntaxParser*> children() const override; virtual QList<Syntax::SyntaxParser*> children() const override;
virtual Parse::Result::DesNode * currNode() const override; virtual Parse::Result::DesNode * currNode() const override;

View File

@ -0,0 +1,93 @@
#include "lex_foundation.h"
#include "tokeniimpl.h"
#include <tuple>
using namespace Lex;
TokensReader::TokensReader(QList<TokenDef *> sequence) { analysis_sequences = sequence; }
QList<Token *> TokensReader::getTokensOfDocument(const QFileInfo &file) {
auto batch_row = 0;
QList<Token *> list;
QFile byte_input(file.canonicalFilePath());
if (!byte_input.open(QIODevice::Text | QIODevice::ReadOnly))
throw new LexException("指定文件无法打开:" + file.canonicalFilePath());
QTextStream source(&byte_input);
source.setCodec("UTF-8");
while (!source.atEnd()) {
auto line = source.readLine();
list.append(get_tokens_of_line(file, line, batch_row));
batch_row++;
}
return list;
}
QList<Token *> TokensReader::getTokensOfContents(const QByteArray &buff, const QFileInfo &_file) {
auto batch_row = 0;
QList<Token *> list;
QTextStream source(buff, QIODevice::ReadOnly);
source.setCodec("UTF-8");
while (!source.atEnd()) {
auto line = source.readLine();
list.append(get_tokens_of_line(_file, line, batch_row));
batch_row++;
}
return list;
}
QList<Token *> TokensReader::get_tokens_of_line(const QFileInfo &associate, const QString &line, int row) {
auto split_seqs = line.split(" ", QString::SplitBehavior::SkipEmptyParts);
auto batch_column = 0;
// 转换单行的内容为源列表
QList<WordBase *> source_sequences;
for (auto &it : split_seqs) {
auto inst = new TokenWord(associate.canonicalFilePath());
source_sequences.append(inst);
auto start_index = line.indexOf(it, batch_column);
inst->reset(it, row, start_index);
batch_column = start_index + it.length();
}
// 对单行的所有的内容进行解析
QList<Token *> results;
for (auto idx = 0; idx < source_sequences.size(); ++idx) {
// 对单个词语进行解析
auto inst = source_sequences[idx];
auto retv = get_token(*inst);
results.append(retv);
// 如果存在未解析的剩余的内容
if (retv->remains())
source_sequences.insert(idx + 1, retv->remains());
delete inst;
}
return results;
}
Token *TokensReader::get_token(const WordBase &word) {
for (auto &it : analysis_sequences) {
auto lex_result = it->analysis(word);
if (lex_result)
return lex_result;
}
throw new LexException(QString("指定的词语无法解析:%1 <row:%2,col:%3>").arg(word.content()).arg(word.row()).arg(word.column()));
}
LexException::LexException(const QString &msg) { this->msg_store = msg; }
QString LexException::message() { return msg_store; }
const char *LexException::what() const { return msg_store.toLocal8Bit(); }

142
libParse/lex_foundation.h Normal file
View File

@ -0,0 +1,142 @@
#pragma once
#include <QFileInfo>
#include <QList>
#include <QString>
#include <QTextStream>
namespace Lex {
class Token;
/**
* @brief
*/
class LexException : std::exception {
public:
explicit LexException(const QString &msg);
virtual QString message();
private:
QString msg_store;
// exception interface
public:
virtual const char *what() const override;
};
/**
* \brief
*/
class WordBase {
public:
virtual ~WordBase() = default;
/**
* \brief Token包含内容
* \return
*/
virtual QString content() const = 0;
/**
* \brief Token绑定的文档路径
* \return
*/
virtual QString filePath() const = 0;
/**
* \brief Token源代码行定义
* \return
*/
virtual int row() const = 0;
/**
* \brief Token源代码列定义
* \return
*/
virtual int column() const = 0;
};
/**
*
*/
class TokenDef {
public:
virtual ~TokenDef() = default;
/**
* \brief Token类型
* \return
*/
virtual QString typeName() = 0;
/**
* \brief
* \return
*/
virtual QString regexp() = 0;
/**
* \brief Token实例并移交实例所有权
* @param word
* \return nullptr
*/
virtual Token *analysis(const WordBase &word) = 0;
};
/**
* Token.
*/
class Token : public WordBase {
public:
/**
* @brief Token关联的
* @return
*/
virtual TokenDef *def() const = 0;
/**
* @brief
* @return
*/
virtual WordBase *remains() const = 0;
};
/**
* \brief Token读取数据源定义类型
*/
class TokensReader {
public:
/**
* @brief Token数据源
* @param file
* @param sequence
*/
TokensReader(QList<TokenDef *> sequence);
virtual ~TokensReader() = default;
/**
* \brief Tokens
* \return
*/
QList<Token *> getTokensOfDocument(const QFileInfo &file);
/**
* @brief Tokens
* @param buff
* @param file
* @return
*/
QList<Token *> getTokensOfContents(const QByteArray &buff, const QFileInfo &file);
private:
QList<TokenDef *> analysis_sequences;
/**
* \brief Token序列集合
* \param source
* \return
*/
QList<Token *> get_tokens_of_line(const QFileInfo &associate, const QString &line, int row);
/**
* \brief Token结果实例
* \param
* \returns null
*/
Token *get_token(const WordBase &word);
};
} // namespace Lex

View File

@ -16,22 +16,21 @@ msvc{
} }
SOURCES += \ SOURCES += \
LexFoundation.cpp \
ParseFrame.cpp \ ParseFrame.cpp \
StoryBoardDocumentParser.cpp \ StoryBoardDocumentParser.cpp \
StoryChainDocumentParser.cpp \ StoryChainDocumentParser.cpp \
StoryOutlineDocumentParser.cpp \ StoryOutlineDocumentParser.cpp \
StoryTool.cpp \ StoryTool.cpp \
StoryUnitDocumentParser.cpp \ StoryUnitDocumentParser.cpp \
WordsPeak.cpp \
XSyntaxBase.cpp \ XSyntaxBase.cpp \
lex_foundation.cpp \
libParse.cpp \ libParse.cpp \
parsechecks.cpp \ parsechecks.cpp \
storyconceptdocumentparser.cpp storyconceptdocumentparser.cpp \
tokeniimpl.cpp
HEADERS += \ HEADERS += \
ComnDef.h \ ComnDef.h \
LexFoundation.h \
ParseFrame.h \ ParseFrame.h \
StoryBoardDocumentParser.h \ StoryBoardDocumentParser.h \
StoryChainDocumentParser.h \ StoryChainDocumentParser.h \
@ -39,12 +38,13 @@ HEADERS += \
StoryTool.h \ StoryTool.h \
StoryUnitDocumentParser.h \ StoryUnitDocumentParser.h \
SyntaxBase.h \ SyntaxBase.h \
WordsPeak.h \
XSyntaxBase.h \ XSyntaxBase.h \
lex_foundation.h \
libParse.h \ libParse.h \
libParse_global.h \ libParse_global.h \
parsechecks.h \ parsechecks.h \
storyconceptdocumentparser.h storyconceptdocumentparser.h \
tokeniimpl.h
TRANSLATIONS += \ TRANSLATIONS += \
libParse_zh_CN.ts libParse_zh_CN.ts

View File

@ -98,7 +98,7 @@ NodeStoryConceptParser::NodeStoryConceptParser(Result::ParseCore *core)
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"), Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"), Elm("{换行符}", true)});
auto rule = addRule("进入概念解析", 0, [this](const QList<LexResult> &seqs, int cnt)->ParseResult auto rule = addRule("进入概念解析", 0, [this](const QList<Token> &seqs, int cnt)->ParseResult
{ {
auto nmunit = seqs[cnt-1]; auto nmunit = seqs[cnt-1];
auto defunit = seqs[cnt-2]; auto defunit = seqs[cnt-2];
@ -115,7 +115,7 @@ NodeStoryConceptParser::NodeStoryConceptParser(Result::ParseCore *core)
rule->addExpression("基础概念定义", {Elm("{概念定义}"), Elm("{描述文本}", true)}); rule->addExpression("基础概念定义", {Elm("{概念定义}"), Elm("{描述文本}", true)});
rule->addExpression("拓展概念定义", {Exp("::换行前缀"), Exp("基础概念定义", true)}); rule->addExpression("拓展概念定义", {Exp("::换行前缀"), Exp("基础概念定义", true)});
rule = addRule("进入成分解析", 1, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("进入成分解析", 1, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);
@ -126,7 +126,7 @@ NodeStoryConceptParser::NodeStoryConceptParser(Result::ParseCore *core)
rule->addExpression("基础成分解析", { Elm("{左界限}", true) }); rule->addExpression("基础成分解析", { Elm("{左界限}", true) });
rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) }); rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) });
rule = addRule("跳出成分解析", 2, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("跳出成分解析", 2, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);
@ -149,7 +149,7 @@ NodeStoryStrongPointParser::NodeStoryStrongPointParser(NodeStoryConceptParser *p
{ {
set_common_expression("::换行前缀", {Elm("{换行符}"), Elm("{换行符}", true)}); set_common_expression("::换行前缀", {Elm("{换行符}"), Elm("{换行符}", true)});
auto rule = addRule("进入要点解析", 0, [this, pparser](const QList<LexResult> &seqs, int cnt)->ParseResult auto rule = addRule("进入要点解析", 0, [this, pparser](const QList<Token> &seqs, int cnt)->ParseResult
{ {
auto nmunit = seqs[cnt-1]; auto nmunit = seqs[cnt-1];
auto defunit = seqs[cnt-2]; auto defunit = seqs[cnt-2];
@ -167,7 +167,7 @@ NodeStoryStrongPointParser::NodeStoryStrongPointParser(NodeStoryConceptParser *p
rule->addExpression("基础要点定义", {Elm("{要点定义}"), Elm("{描述文本}", true)}); rule->addExpression("基础要点定义", {Elm("{要点定义}"), Elm("{描述文本}", true)});
rule->addExpression("拓展要点定义", {Exp("::换行前缀"), Exp("基础要点定义", true)}); rule->addExpression("拓展要点定义", {Exp("::换行前缀"), Exp("基础要点定义", true)});
rule = addRule("进入成分解析", 1, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("进入成分解析", 1, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);
@ -178,7 +178,7 @@ NodeStoryStrongPointParser::NodeStoryStrongPointParser(NodeStoryConceptParser *p
rule->addExpression("基础成分解析", { Elm("{左界限}", true) }); rule->addExpression("基础成分解析", { Elm("{左界限}", true) });
rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) }); rule->addExpression("拓展成分解析", { Exp("::换行前缀"), Exp("基础成分解析", true) });
rule = addRule("跳出成分解析", 2, [this](const QList<LexResult> &seqs, int cnt)->ParseResult { rule = addRule("跳出成分解析", 2, [this](const QList<Token> &seqs, int cnt)->ParseResult {
auto node = currNode(); auto node = currNode();
auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol); auto word = new Words(node, docRef(), seqs[cnt - 1].Text, seqs[cnt - 1].StartRow, seqs[cnt - 1].StartCol);

53
libParse/tokeniimpl.cpp Normal file
View File

@ -0,0 +1,53 @@
#include "tokeniimpl.h"
using namespace Lex;
TokenWord::TokenWord(const QString &file_path) { filepath_val = file_path; }
QString TokenWord::content() const { return content_val; }
QString TokenWord::filePath() const { return filepath_val; }
int TokenWord::row() const { return row_val; }
int TokenWord::column() const { return column_val; }
// WordBase &TokenWord::operator=(const WordBase &other) {
// this->content_val = other.content();
// this->filepath_val = other.filePath();
// this->row_val = other.row();
// this->column_val = other.column();
// return *this;
//}
void TokenWord::reset(const QString &word, int row, int col) {
content_val = word;
row_val = row;
column_val = col;
}
TokenResult::TokenResult(TokenDef *def, WordBase *word, int length) : def_store(def), remains_store(nullptr) {
TokenWord *inst = nullptr;
if (word->content().length() != length) {
inst = new TokenWord(word->filePath());
inst->reset(word->content().mid(length), word->row(), word->column() + length);
}
remains_store = inst;
content_store = word->content().mid(0, length);
filepath_store = word->filePath();
row_store = word->row();
col_store = word->column();
}
TokenDef *TokenResult::def() const { return def_store; }
WordBase *TokenResult::remains() const { return remains_store; }
QString TokenResult::content() const { return content_store; }
QString TokenResult::filePath() const { return filepath_store; }
int TokenResult::row() const { return row_store; }
int TokenResult::column() const { return col_store; }

126
libParse/tokeniimpl.h Normal file
View File

@ -0,0 +1,126 @@
#ifndef TOKENIIMPL_H
#define TOKENIIMPL_H
#include "lex_foundation.h"
namespace Lex {
/**
* \brief
*/
class TokenWord : public WordBase {
public:
virtual ~TokenWord() = default;
/**
* \brief
* \param file_path
*/
explicit TokenWord(const QString &file_path);
/**
* \brief
*/
virtual QString content() const override;
/**
* \brief
*/
virtual QString filePath() const override;
/**
* \brief
*/
virtual int row() const override;
/**
* \brief
*/
virtual int column() const override;
/**
* @brief
* @param other
* @return
*/
// virtual WordBase &operator=(const WordBase &other) override;
/**
* \brief
/// <param name="word">词语文本</param>
/// <param name="row">行定义</param>
/// <param name="col">列定义</param>
*/
void reset(const QString &word, int row, int col);
private:
QString content_val;
QString filepath_val;
int row_val, column_val;
};
/**
* @brief
*/
class TokenResult : public Token {
private:
TokenDef *const def_store;
WordBase *remains_store;
QString content_store;
QString filepath_store;
int row_store, col_store;
public:
/**
* @brief Token解析结果实例
* @param def
* @param word
* @param length
*/
TokenResult(TokenDef *def, WordBase *word, int length);
virtual ~TokenResult() = default;
/**
* @brief Token解析定义
* @return
*/
virtual TokenDef *def() const override;
/**
* @brief
* @return
*/
virtual WordBase *remains() const override;
/**
* \brief Token包含内容
* \return
*/
virtual QString content() const override;
/**
* \brief Token绑定的文档路径
* \return
*/
virtual QString filePath() const override;
/**
* \brief Token源代码行定义
* \return
*/
virtual int row() const override;
/**
* \brief Token源代码列定义
* \return
*/
virtual int column() const override;
/**
* @brief
* @param other
* @return
*/
// virtual WordBase &operator=(const WordBase &other);
};
} // namespace Lex
#endif // TOKENIIMPL_H