slash
This commit is contained in:
parent
a7b92805f1
commit
4dd5a0e728
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -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())
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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) });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 子解析器集合.
|
* 子解析器集合.
|
||||||
|
|
|
||||||
|
|
@ -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++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -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无法打开:-1:文件不存在,0:成功
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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(); }
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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; }
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue