slash
This commit is contained in:
parent
a7b92805f1
commit
4dd5a0e728
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!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>
|
||||
<data>
|
||||
<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 "WordsPeak.h"
|
||||
#include "lex_foundation.h"
|
||||
|
||||
using namespace Parse;
|
||||
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);
|
||||
|
||||
QList<LexResult> lex_seqence;
|
||||
QList<Token> lex_seqence;
|
||||
std::tuple<int, int, QChar> temp;
|
||||
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);
|
||||
|
||||
QList<LexResult> lex_seqence;
|
||||
QList<Token> lex_seqence;
|
||||
std::tuple<int, int, QChar> temp;
|
||||
while ((std::get<2>(temp = stream.read())) != EOF)
|
||||
{
|
||||
|
|
@ -92,8 +92,7 @@ QList<DesNode *> ParseFrame::analysisSource(Parse::Result::DocCore *doc, const Q
|
|||
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;
|
||||
token_seqs.append(seqs);
|
||||
}
|
||||
|
|
@ -103,8 +102,7 @@ void ParseFrame::appendParser(SyntaxParser * 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;
|
||||
|
||||
if(lex_seqence.size())
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include "SyntaxBase.h"
|
||||
#include "lex_foundation.h"
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
namespace Syntax
|
||||
{
|
||||
|
|
@ -18,15 +19,17 @@ namespace Syntax
|
|||
QList<Parse::Result::DesNode*> analysisSource(Parse::Result::DocCore *doc, const QString &src);
|
||||
|
||||
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);
|
||||
|
||||
private:
|
||||
Lex::TokensReader *const tokens_in;
|
||||
|
||||
QString unknown_token;
|
||||
QList<Lex::LexDef> token_seqs;
|
||||
QList<Lex::TokenDef *> token_seqs;
|
||||
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<Parse::Result::DesNode*> &nodes_out);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ NodeStoryBoardParser::NodeStoryBoardParser(Result::ParseCore *core)
|
|||
:Syntax::XSyntaxBase("情节引用"), project_ins(core)
|
||||
{
|
||||
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 nmunit = seqs[cnt-2];
|
||||
|
|
@ -151,7 +151,7 @@ NodeStoryBoardParser::NodeStoryBoardParser(Result::ParseCore *core)
|
|||
rule->addExpression("基础故事定义", {Elm("{故事定义}"), Elm("{描述文本}1"), Elm("{描述文本}2", 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 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("拓展成分解析", { 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 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)});
|
||||
|
||||
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 name_u = seqs[cnt-2];
|
||||
|
|
@ -224,7 +224,7 @@ NodeStoryFragmentReferParser::NodeStoryFragmentReferParser(XSyntaxBase *parent)
|
|||
rule->addExpression("基础情节定义", {Elm("{情节引用}"), Elm("{描述文本}1"), Elm("{描述文本}2", 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 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("拓展成分解析", { 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 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)});
|
||||
|
||||
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;
|
||||
|
||||
// 构建语法节点
|
||||
|
|
@ -31,10 +30,7 @@ NodeStoryChainParser::NodeStoryChainParser(ParseCore *core)
|
|||
rule->addExpression("脉络定义基础", { Elm("{脉络定义}"), Elm("{描述文本}", 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 nmidx = cnt - 1;
|
||||
|
||||
// 获取语法节点
|
||||
|
|
@ -49,10 +45,7 @@ NodeStoryChainParser::NodeStoryChainParser(ParseCore *core)
|
|||
rule->addExpression("基础脉络界限", { Elm("{左界限}", 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 nmidx = cnt - 1;
|
||||
|
||||
// 获取语法节点
|
||||
|
|
@ -81,7 +74,7 @@ NodeStoryPointParser::NodeStoryPointParser(NodeStoryChainParser *chain)
|
|||
{
|
||||
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;
|
||||
|
||||
// 语法节点定义
|
||||
|
|
@ -101,10 +94,7 @@ NodeStoryPointParser::NodeStoryPointParser(NodeStoryChainParser *chain)
|
|||
rule->addExpression("基础节点定义", { Elm("{节点定义}"), Elm("{描述文本}", 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 nmidx = cnt - 1;
|
||||
auto word = new Words(this->currNode(), this->storyChainParser()->docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol);
|
||||
this->docRef()->append(word);
|
||||
|
|
@ -114,10 +104,7 @@ NodeStoryPointParser::NodeStoryPointParser(NodeStoryChainParser *chain)
|
|||
rule->addExpression("基础节点界限", { Elm("{左界限}", 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 nmidx = cnt - 1;
|
||||
auto word = new Words(this->currNode(), this->storyChainParser()->docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol);
|
||||
this->docRef()->append(word);
|
||||
|
|
@ -255,7 +242,7 @@ NodeStoryPureTextDesGroupParser::NodeStoryPureTextDesGroupParser(XSyntaxBase * p
|
|||
: XSyntaxBase("描述块"), parent_parser(pparser)
|
||||
{
|
||||
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());
|
||||
refocusNode(curr_node);
|
||||
pparser->currNode()->appendChild(curr_node);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ NodeStoryDepictionParser::NodeStoryDepictionParser(Result::ParseCore *core)
|
|||
: XSyntaxBase("叙事节点")
|
||||
{
|
||||
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 defunit = seqs[cnt-2];
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ NodeStoryDepictionParser::NodeStoryDepictionParser(Result::ParseCore *core)
|
|||
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 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 = 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 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)
|
||||
{
|
||||
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 node = new NodeStoryUnit(this->docRef(), seqs[nmidx].Text);
|
||||
|
|
@ -163,7 +163,7 @@ NodeStoryUnitParser::NodeStoryUnitParser(ParseCore * core)
|
|||
rule->addExpression("基础单元解析", { Elm("{单元定义}"), Elm("{描述文本}", 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 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("拓展单元成分解析", { 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 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)
|
||||
{
|
||||
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 parent_parser = nodeStoryUnitParser();
|
||||
|
|
@ -236,7 +236,7 @@ NodeStoryFragmentParser::NodeStoryFragmentParser(NodeStoryUnitParser * pparser)
|
|||
rule->addExpression("基础情节解析", { Elm("{情节定义}"), Elm("{描述文本}1"), Elm("{描述文本}2", 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 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("拓展情节成分解析", { 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 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("{描述文本}", 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("{换行符}");
|
||||
unique_tidy->setMatchEnable(state);
|
||||
|
||||
|
|
@ -308,7 +308,7 @@ NodeStoryTextSpanParser::NodeStoryTextSpanParser(XSyntaxBase *parent)
|
|||
{
|
||||
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();
|
||||
for(auto idx=0; idx<cnt; ++idx){
|
||||
DesNode *node = docRef()->unknowns();
|
||||
|
|
@ -333,7 +333,7 @@ NodeStoryPointReferParser::NodeStoryPointReferParser(XSyntaxBase *parent)
|
|||
{
|
||||
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 chain_unit = seqs[cnt-3];
|
||||
auto point_unit = seqs[cnt-2];
|
||||
|
|
@ -425,7 +425,7 @@ NodeStoryPointReferParser::NodeStoryPointReferParser(XSyntaxBase *parent)
|
|||
NodeStoryLinePrefixParser::NodeStoryLinePrefixParser(SyntaxParser *pparent)
|
||||
: 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);
|
||||
return ParseResult::Completed;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#define SYNTAXBASE_H
|
||||
|
||||
#include "libParse.h"
|
||||
#include "LexFoundation.h"
|
||||
#include "lex_foundation.h"
|
||||
|
||||
namespace Syntax {
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ namespace Syntax {
|
|||
* \param seqs
|
||||
* \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 下一步需要用到的解析器
|
||||
* \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; }
|
||||
|
||||
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)
|
||||
|
|
@ -87,7 +87,7 @@ DefType Element::type() const
|
|||
}
|
||||
|
||||
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];
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ DefType Expression::type() const
|
|||
}
|
||||
|
||||
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)
|
||||
return std::make_tuple(false, 0);
|
||||
|
|
@ -188,7 +188,7 @@ void Syntax::ParseRule::addExpression(const QString &name, const QList<Elm> &def
|
|||
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)
|
||||
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);
|
||||
}
|
||||
|
||||
ParseResult ParseRule::syntaxTrigger(const QList<LexResult>& srcs, int count) {
|
||||
ParseResult ParseRule::syntaxTrigger(const QList<Token>& srcs, int count) {
|
||||
return exc_store(srcs, count);
|
||||
}
|
||||
|
||||
|
|
@ -252,7 +252,7 @@ DocCore * XSyntaxBase::docRef() const
|
|||
return src_ref;
|
||||
}
|
||||
|
||||
bool XSyntaxBase::applied(const QList<LexResult>& seqs)
|
||||
bool XSyntaxBase::applied(const QList<Token>& seqs)
|
||||
{
|
||||
if(!seqs.size())
|
||||
return false;
|
||||
|
|
@ -292,7 +292,7 @@ void XSyntaxBase::reset()
|
|||
current_node = nullptr;
|
||||
}
|
||||
|
||||
ParseResult XSyntaxBase::parse(QList<LexResult>& seqs)
|
||||
ParseResult XSyntaxBase::parse(QList<Token>& seqs)
|
||||
{
|
||||
if(!seqs.size())
|
||||
return ParseResult::Failed;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include <QList>
|
||||
#include <QHash>
|
||||
#include <functional>
|
||||
#include "LexFoundation.h"
|
||||
#include "lex_foundation.h"
|
||||
#include "SyntaxBase.h"
|
||||
|
||||
namespace Syntax
|
||||
|
|
@ -102,7 +102,7 @@ namespace Syntax
|
|||
* \return tuple(完全匹配指示,最大匹配长度)
|
||||
*/
|
||||
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:
|
||||
QString value_store;
|
||||
|
|
@ -129,7 +129,7 @@ namespace Syntax
|
|||
QList<Link*> nextElements() const;
|
||||
|
||||
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:
|
||||
QString alias_name;
|
||||
|
|
@ -161,7 +161,7 @@ namespace Syntax
|
|||
* \return tuple(完全匹配指示,最大匹配长度)
|
||||
*/
|
||||
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:
|
||||
QString name_store;
|
||||
|
|
@ -187,8 +187,8 @@ namespace Syntax
|
|||
void setEnable(bool v);
|
||||
|
||||
void addExpression(const QString &name, const QList<Defines::Elm> &_defines);
|
||||
std::tuple<bool, int> tokensMatch(const QList<Lex::LexResult> &token) const;
|
||||
ParseResult syntaxTrigger(const QList<Lex::LexResult>& srcs, int count);
|
||||
std::tuple<bool, int> tokensMatch(const QList<Lex::Token> &token) const;
|
||||
ParseResult syntaxTrigger(const QList<Lex::Token>& srcs, int count);
|
||||
|
||||
private:
|
||||
bool enable_state;
|
||||
|
|
@ -224,9 +224,9 @@ namespace Syntax
|
|||
// 通过 Parse::SyntaxParser 继承
|
||||
virtual void docActive(Parse::Result::DocCore *ins) override;
|
||||
virtual Parse::Result::DocCore *docRef() const override;
|
||||
virtual bool applied(const QList<Lex::LexResult>& seqs) override;
|
||||
virtual bool applied(const QList<Lex::Token>& seqs) 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 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 += \
|
||||
LexFoundation.cpp \
|
||||
ParseFrame.cpp \
|
||||
StoryBoardDocumentParser.cpp \
|
||||
StoryChainDocumentParser.cpp \
|
||||
StoryOutlineDocumentParser.cpp \
|
||||
StoryTool.cpp \
|
||||
StoryUnitDocumentParser.cpp \
|
||||
WordsPeak.cpp \
|
||||
XSyntaxBase.cpp \
|
||||
lex_foundation.cpp \
|
||||
libParse.cpp \
|
||||
parsechecks.cpp \
|
||||
storyconceptdocumentparser.cpp
|
||||
storyconceptdocumentparser.cpp \
|
||||
tokeniimpl.cpp
|
||||
|
||||
HEADERS += \
|
||||
ComnDef.h \
|
||||
LexFoundation.h \
|
||||
ParseFrame.h \
|
||||
StoryBoardDocumentParser.h \
|
||||
StoryChainDocumentParser.h \
|
||||
|
|
@ -39,12 +38,13 @@ HEADERS += \
|
|||
StoryTool.h \
|
||||
StoryUnitDocumentParser.h \
|
||||
SyntaxBase.h \
|
||||
WordsPeak.h \
|
||||
XSyntaxBase.h \
|
||||
lex_foundation.h \
|
||||
libParse.h \
|
||||
libParse_global.h \
|
||||
parsechecks.h \
|
||||
storyconceptdocumentparser.h
|
||||
storyconceptdocumentparser.h \
|
||||
tokeniimpl.h
|
||||
|
||||
TRANSLATIONS += \
|
||||
libParse_zh_CN.ts
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ NodeStoryConceptParser::NodeStoryConceptParser(Result::ParseCore *core)
|
|||
{
|
||||
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 defunit = seqs[cnt-2];
|
||||
|
|
@ -115,7 +115,7 @@ NodeStoryConceptParser::NodeStoryConceptParser(Result::ParseCore *core)
|
|||
rule->addExpression("基础概念定义", {Elm("{概念定义}"), Elm("{描述文本}", 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 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("拓展成分解析", { 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 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)});
|
||||
|
||||
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 defunit = seqs[cnt-2];
|
||||
|
|
@ -167,7 +167,7 @@ NodeStoryStrongPointParser::NodeStoryStrongPointParser(NodeStoryConceptParser *p
|
|||
rule->addExpression("基础要点定义", {Elm("{要点定义}"), Elm("{描述文本}", 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 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("拓展成分解析", { 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 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