From 4dd5a0e728a7b24a0f339f2bfa4d3e0eb0fc322d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=89=E5=AE=87=E6=B8=85=E9=9F=B3?= <2422523675@qq.com> Date: Sat, 25 Mar 2023 10:10:32 +0800 Subject: [PATCH] slash --- QtNovelDesc.pro.user | 2 +- libParse/LexFoundation.cpp | 134 ---------------------- libParse/LexFoundation.h | 76 ------------- libParse/ParseFrame.cpp | 12 +- libParse/ParseFrame.h | 19 ++-- libParse/StoryBoardDocumentParser.cpp | 12 +- libParse/StoryChainDocumentParser.cpp | 45 +++----- libParse/StoryOutlineDocumentParser.cpp | 6 +- libParse/StoryUnitDocumentParser.cpp | 20 ++-- libParse/SyntaxBase.h | 6 +- libParse/WordsPeak.cpp | 61 ---------- libParse/WordsPeak.h | 46 -------- libParse/XSyntaxBase.cpp | 14 +-- libParse/XSyntaxBase.h | 16 +-- libParse/lex_foundation.cpp | 93 ++++++++++++++++ libParse/lex_foundation.h | 142 ++++++++++++++++++++++++ libParse/libParse.pro | 12 +- libParse/storyconceptdocumentparser.cpp | 12 +- libParse/tokeniimpl.cpp | 53 +++++++++ libParse/tokeniimpl.h | 126 +++++++++++++++++++++ 20 files changed, 496 insertions(+), 411 deletions(-) delete mode 100644 libParse/LexFoundation.cpp delete mode 100644 libParse/LexFoundation.h delete mode 100644 libParse/WordsPeak.cpp delete mode 100644 libParse/WordsPeak.h create mode 100644 libParse/lex_foundation.cpp create mode 100644 libParse/lex_foundation.h create mode 100644 libParse/tokeniimpl.cpp create mode 100644 libParse/tokeniimpl.h diff --git a/QtNovelDesc.pro.user b/QtNovelDesc.pro.user index 99d9400..06cf352 100644 --- a/QtNovelDesc.pro.user +++ b/QtNovelDesc.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/libParse/LexFoundation.cpp b/libParse/LexFoundation.cpp deleted file mode 100644 index 41ddcf9..0000000 --- a/libParse/LexFoundation.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "LexFoundation.h" -#include - -using namespace Lex; - -LexFoundation::LexFoundation(QList 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 LexFoundation::push(int row, int col, const QChar w) -{ - QList 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 LexFoundation::lexical_parse(const QString & segment) -{ - // 获取匹配词法分析 - QList result; - QList> 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 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; -} diff --git a/libParse/LexFoundation.h b/libParse/LexFoundation.h deleted file mode 100644 index a9474be..0000000 --- a/libParse/LexFoundation.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include -#include - -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 seqence, const QString UnknownToken); - virtual ~LexFoundation() = default; - - /** - * 词法分析器累积解析单个字符流. - * - * \param row 行 - * \param col 列 - * \param w 字符 - * \return 累积适配结果,空累积, - */ - QList push(int row, int col, const QChar w); - - private: - QString unknown_token; - QList empty_seq; - - QList code_acc; - QList lexical_seq; - - QList lexical_parse(const QString &segment); - }; -} diff --git a/libParse/ParseFrame.cpp b/libParse/ParseFrame.cpp index d2df423..bd82103 100644 --- a/libParse/ParseFrame.cpp +++ b/libParse/ParseFrame.cpp @@ -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 ParseFrame::analysis(DocCore*doc, const QString & path) LexFoundation token_s(this->token_seqs, this->unknown_token); - QList lex_seqence; + QList lex_seqence; std::tuple temp; while ((std::get<2>(temp = stream.read())) != EOF) { @@ -58,7 +58,7 @@ QList ParseFrame::analysisSource(Parse::Result::DocCore *doc, const Q LexFoundation token_s(this->token_seqs, this->unknown_token); - QList lex_seqence; + QList lex_seqence; std::tuple temp; while ((std::get<2>(temp = stream.read())) != EOF) { @@ -92,8 +92,7 @@ QList ParseFrame::analysisSource(Parse::Result::DocCore *doc, const Q return xrets; } -void ParseFrame::appendTokensDefine(QList seqs, const QString & unknown_token) -{ +void ParseFrame::appendTokensDefine(QList 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 &lex_seqence, QList parsers, QList &nodes_out) -{ +ParseResult ParseFrame::inner_parse(QList &lex_seqence, QList parsers, QList &nodes_out) { QList nodes; if(lex_seqence.size()) diff --git a/libParse/ParseFrame.h b/libParse/ParseFrame.h index 6f2b43a..b1f521d 100644 --- a/libParse/ParseFrame.h +++ b/libParse/ParseFrame.h @@ -1,7 +1,8 @@ #pragma once -#include -#include #include "SyntaxBase.h" +#include "lex_foundation.h" +#include +#include namespace Syntax { @@ -18,15 +19,17 @@ namespace Syntax QList analysisSource(Parse::Result::DocCore *doc, const QString &src); protected: - void appendTokensDefine(QList seqs, const QString &unknown_token); - void appendParser(Syntax::SyntaxParser* u); + void appendTokensDefine(QList seqs, const QString &unknown_token); + void appendParser(Syntax::SyntaxParser *u); - private: - QString unknown_token; - QList token_seqs; + private: + Lex::TokensReader *const tokens_in; + + QString unknown_token; + QList token_seqs; QList cascade_parsers; - ParseResult ParseFrame::inner_parse(QList &lex_seqence, + ParseResult ParseFrame::inner_parse(QList &lex_seqence, QList parsers, QList &nodes_out); }; diff --git a/libParse/StoryBoardDocumentParser.cpp b/libParse/StoryBoardDocumentParser.cpp index a6e53fc..cf4be4f 100644 --- a/libParse/StoryBoardDocumentParser.cpp +++ b/libParse/StoryBoardDocumentParser.cpp @@ -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 &seqs, int cnt)->ParseResult + auto rule = addRule("进入作品解析", 0, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("进入成分解析", 1, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("跳出成分解析", 2, [this](const QList &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 &seqs, int cnt)->ParseResult + auto rule = addRule("进入情节引用", 0, [this, parent](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("进入成分解析", 1, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("跳出成分解析", 2, [this](const QList &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); diff --git a/libParse/StoryChainDocumentParser.cpp b/libParse/StoryChainDocumentParser.cpp index 0eb4fde..31b70b6 100644 --- a/libParse/StoryChainDocumentParser.cpp +++ b/libParse/StoryChainDocumentParser.cpp @@ -12,8 +12,7 @@ NodeStoryChainParser::NodeStoryChainParser(ParseCore *core) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); - auto rule = addRule("文学脉络定义", 0, [this](const QList &seqs, int cnt)->ParseResult - { + auto rule = addRule("文学脉络定义", 0, [this](const QList &seqs, int cnt) -> ParseResult { auto nmidx = cnt - 1, defidx = cnt - 2; // 构建语法节点 @@ -27,14 +26,11 @@ NodeStoryChainParser::NodeStoryChainParser(ParseCore *core) docRef()->append(words1); return ParseResult::SelfManipulate; - }); + }); rule->addExpression("脉络定义基础", { Elm("{脉络定义}"), Elm("{描述文本}", true) }); rule->addExpression("脉络定义拓展", { Exp("::换行前缀"), Exp("脉络定义基础", true)}); - - - rule = addRule("脉络成分解析", 1, [this](const QList &seqs, int cnt)->ParseResult - { + rule = addRule("脉络成分解析", 1, [this](const QList &seqs, int cnt) -> ParseResult { auto nmidx = cnt - 1; // 获取语法节点 @@ -45,14 +41,11 @@ NodeStoryChainParser::NodeStoryChainParser(ParseCore *core) docRef()->append(word); return ParseResult::EnterNext; - }); + }); rule->addExpression("基础脉络界限", { Elm("{左界限}", true) }); rule->addExpression("拓展脉络界限", { Exp("::换行前缀"), Exp("基础脉络界限", true) }); - - - rule = addRule("完成脉络解析", 2, [this](const QList &seqs, int cnt)->ParseResult - { + rule = addRule("完成脉络解析", 2, [this](const QList &seqs, int cnt) -> ParseResult { auto nmidx = cnt - 1; // 获取语法节点 @@ -63,7 +56,7 @@ NodeStoryChainParser::NodeStoryChainParser(ParseCore *core) docRef()->append(word); return ParseResult::Completed; - }); + }); rule->addExpression("基础脉络跳出", { Elm("{右界限}", true) }); rule->addExpression("拓展脉络跳出", { Exp("::换行前缀"), Exp("基础脉络跳出", true) }); @@ -81,8 +74,8 @@ NodeStoryPointParser::NodeStoryPointParser(NodeStoryChainParser *chain) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); - auto rule = addRule("脉络驻点定义", 0, [this](const QList &seqs, int c)->ParseResult { - auto nmidx = c - 1, defidx = c - 2; + auto rule = addRule("脉络驻点定义", 0, [this](const QList &seqs, int c) -> ParseResult { + auto nmidx = c - 1, defidx = c - 2; // 语法节点定义 auto node = this->storyChainParser()->currNode(); @@ -97,33 +90,27 @@ NodeStoryPointParser::NodeStoryPointParser(NodeStoryChainParser *chain) node->doc()->append(word1); return ParseResult::SelfManipulate; - }); + }); rule->addExpression("基础节点定义", { Elm("{节点定义}"), Elm("{描述文本}", true) }); rule->addExpression("拓展节点定义", { Exp("::换行前缀"), Exp("基础节点定义", true) }); - - - rule = addRule("节点成分解析", 1, [this](const QList &seqs, int cnt)->ParseResult - { + rule = addRule("节点成分解析", 1, [this](const QList &seqs, int cnt) -> ParseResult { auto nmidx = cnt - 1; auto word = new Words(this->currNode(), this->storyChainParser()->docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); this->docRef()->append(word); return ParseResult::EnterNext; - }); + }); rule->addExpression("基础节点界限", { Elm("{左界限}", true) }); rule->addExpression("拓展节点界限", { Exp("::换行前缀"), Exp("基础节点界限", true) }); - - - rule = addRule("完成节点解析", 2, [this](const QList &seqs, int cnt)->ParseResult - { + rule = addRule("完成节点解析", 2, [this](const QList &seqs, int cnt) -> ParseResult { auto nmidx = cnt - 1; auto word = new Words(this->currNode(), this->storyChainParser()->docRef(), seqs[nmidx].Text, seqs[nmidx].StartRow, seqs[nmidx].StartCol); this->docRef()->append(word); return ParseResult::Completed; - }); + }); rule->addExpression("基础节点跳出", { Elm("{右界限}", true) }); rule->addExpression("拓展节点跳出", { Exp("::换行前缀"), Exp("基础节点跳出", true) }); @@ -255,8 +242,8 @@ NodeStoryPureTextDesGroupParser::NodeStoryPureTextDesGroupParser(XSyntaxBase * p : XSyntaxBase("描述块"), parent_parser(pparser) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); - auto rule = addRule("提取文本", 0, [this, pparser](const QList &seqs, int cnt)->ParseResult { - auto curr_node = new NodeStoryDesGroup(pparser->currNode()); + auto rule = addRule("提取文本", 0, [this, pparser](const QList &seqs, int cnt) -> ParseResult { + auto curr_node = new NodeStoryDesGroup(pparser->currNode()); refocusNode(curr_node); pparser->currNode()->appendChild(curr_node); @@ -269,7 +256,7 @@ NodeStoryPureTextDesGroupParser::NodeStoryPureTextDesGroupParser(XSyntaxBase * p } return ParseResult::Completed; - }); + }); rule->addExpression("基础提取文本", { Elm("{描述文本}"), Elm("{描述文本}", true) }); rule->addExpression("拓展提取文本", { Exp("::换行前缀"), Exp("基础提取文本", true) }); diff --git a/libParse/StoryOutlineDocumentParser.cpp b/libParse/StoryOutlineDocumentParser.cpp index 18797d6..51564b2 100644 --- a/libParse/StoryOutlineDocumentParser.cpp +++ b/libParse/StoryOutlineDocumentParser.cpp @@ -26,7 +26,7 @@ NodeStoryDepictionParser::NodeStoryDepictionParser(Result::ParseCore *core) : XSyntaxBase("叙事节点") { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); - auto rule = addRule("进入卷宗叙事", 0, [this](const QList &seqs, int cnt)->ParseResult{ + auto rule = addRule("进入卷宗叙事", 0, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("进入成分解析", 1, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("跳出成分解析", 2, [this](const QList &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); diff --git a/libParse/StoryUnitDocumentParser.cpp b/libParse/StoryUnitDocumentParser.cpp index 5386ad4..9662aae 100644 --- a/libParse/StoryUnitDocumentParser.cpp +++ b/libParse/StoryUnitDocumentParser.cpp @@ -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 &seqs, int cnt)->ParseResult { + auto rule = addRule("进入单元解析", 0, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("单元成分解析", 1, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("跳出单元成分解析", 2, [this](const QList &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 &seqs, int cnt)->ParseResult { + auto rule = addRule("进入情节解析", 0, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("情节成分解析", 1, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("跳出情节成分解析", 2, [this](const QList &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 &seqs, int cnt)->ParseResult { + auto rule = addRule("进入描述块解析", 0, [this](const QList &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 &seqs, int cnt)->ParseResult { + auto rule = addRule("解析TextSpan", 0, [this](const QList &seqs, int cnt)->ParseResult { auto pnode = parent_parser->currNode(); for(auto idx=0; idxunknowns(); @@ -333,7 +333,7 @@ NodeStoryPointReferParser::NodeStoryPointReferParser(XSyntaxBase *parent) { set_common_expression("::换行前缀", {Elm("{换行符}"),Elm("{换行符}", true)}); - auto rule = addRule("解析节点引用", 0, [this](const QList &seqs, int cnt)->ParseResult { + auto rule = addRule("解析节点引用", 0, [this](const QList &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 &seqs, int cnt)->ParseResult + critical_rule = addRule("清理换行符", 0, [this](const QList &seqs, int cnt)->ParseResult { this->setMatchEnable(false); return ParseResult::Completed; diff --git a/libParse/SyntaxBase.h b/libParse/SyntaxBase.h index 2be2888..6a58aa1 100644 --- a/libParse/SyntaxBase.h +++ b/libParse/SyntaxBase.h @@ -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& seqs) = 0; + virtual bool applied(const QList& seqs) = 0; /** * 重置解析器 @@ -60,7 +60,7 @@ namespace Syntax { * \param next_ps 下一步需要用到的解析器 * \return 解析操作类型 */ - virtual ParseResult parse(QList& seqs)= 0; + virtual ParseResult parse(QList& seqs)= 0; /** * 子解析器集合. diff --git a/libParse/WordsPeak.cpp b/libParse/WordsPeak.cpp deleted file mode 100644 index 98b2330..0000000 --- a/libParse/WordsPeak.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "WordsPeak.h" -#include - -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::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++]); -} - diff --git a/libParse/WordsPeak.h b/libParse/WordsPeak.h deleted file mode 100644 index 64f853e..0000000 --- a/libParse/WordsPeak.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once -#include -#include -#include -#include - -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 read(); - - private: - QFile * file_target; - QString contents_temp; - QTextStream* text_input; - - QString current_line; - int current_row, current_col; - - }; -} diff --git a/libParse/XSyntaxBase.cpp b/libParse/XSyntaxBase.cpp index fed6320..5fa32fc 100644 --- a/libParse/XSyntaxBase.cpp +++ b/libParse/XSyntaxBase.cpp @@ -38,7 +38,7 @@ void Link::appendNext(Link * ins) { next_inss << ins; } QList Link::nextElements() const { return next_inss; } std::tuple -Link::linkCheck(const QList& tokens, int offset) const +Link::linkCheck(const QList& tokens, int offset) const { // 本节点匹配失败,剩余标记长度不足 if (tokens.size() <= offset) @@ -87,7 +87,7 @@ DefType Element::type() const } std::tuple -Element::elementCheck(const QList& tokens, int offset) const +Element::elementCheck(const QList& tokens, int offset) const { auto u = tokens[offset]; @@ -117,7 +117,7 @@ DefType Expression::type() const } std::tuple -Expression::elementCheck(const QList& tokens, int offset) const +Expression::elementCheck(const QList& 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 &def expression_list << exp; } -std::tuple ParseRule::tokensMatch(const QList& token) const +std::tuple ParseRule::tokensMatch(const QList& token) const { if(enable_state) for (auto expx : expression_list) { @@ -201,7 +201,7 @@ std::tuple ParseRule::tokensMatch(const QList& token) cons return std::make_tuple(false, 0); } -ParseResult ParseRule::syntaxTrigger(const QList& srcs, int count) { +ParseResult ParseRule::syntaxTrigger(const QList& srcs, int count) { return exc_store(srcs, count); } @@ -252,7 +252,7 @@ DocCore * XSyntaxBase::docRef() const return src_ref; } -bool XSyntaxBase::applied(const QList& seqs) +bool XSyntaxBase::applied(const QList& seqs) { if(!seqs.size()) return false; @@ -292,7 +292,7 @@ void XSyntaxBase::reset() current_node = nullptr; } -ParseResult XSyntaxBase::parse(QList& seqs) +ParseResult XSyntaxBase::parse(QList& seqs) { if(!seqs.size()) return ParseResult::Failed; diff --git a/libParse/XSyntaxBase.h b/libParse/XSyntaxBase.h index a32362a..7138afd 100644 --- a/libParse/XSyntaxBase.h +++ b/libParse/XSyntaxBase.h @@ -3,7 +3,7 @@ #include #include #include -#include "LexFoundation.h" +#include "lex_foundation.h" #include "SyntaxBase.h" namespace Syntax @@ -102,7 +102,7 @@ namespace Syntax * \return tuple(完全匹配指示,最大匹配长度) */ virtual std::tuple - elementCheck(const QList &tokens, int offset) const; + elementCheck(const QList &tokens, int offset) const; private: QString value_store; @@ -129,7 +129,7 @@ namespace Syntax QList nextElements() const; virtual std::tuple - linkCheck(const QList &tokens, int offset) const; + linkCheck(const QList &tokens, int offset) const; private: QString alias_name; @@ -161,7 +161,7 @@ namespace Syntax * \return tuple(完全匹配指示,最大匹配长度) */ virtual std::tuple - elementCheck(const QList &tokens, int offset) const override; + elementCheck(const QList &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); - std::tuple tokensMatch(const QList &token) const; - ParseResult syntaxTrigger(const QList& srcs, int count); + std::tuple tokensMatch(const QList &token) const; + ParseResult syntaxTrigger(const QList& 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& seqs) override; + virtual bool applied(const QList& seqs) override; virtual void reset() override; - virtual ParseResult parse(QList& seqs) override; + virtual ParseResult parse(QList& seqs) override; virtual QList children() const override; virtual Parse::Result::DesNode * currNode() const override; diff --git a/libParse/lex_foundation.cpp b/libParse/lex_foundation.cpp new file mode 100644 index 0000000..7bc395e --- /dev/null +++ b/libParse/lex_foundation.cpp @@ -0,0 +1,93 @@ +#include "lex_foundation.h" +#include "tokeniimpl.h" +#include + +using namespace Lex; + +TokensReader::TokensReader(QList sequence) { analysis_sequences = sequence; } + +QList TokensReader::getTokensOfDocument(const QFileInfo &file) { + auto batch_row = 0; + QList 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 TokensReader::getTokensOfContents(const QByteArray &buff, const QFileInfo &_file) { + auto batch_row = 0; + QList 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 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 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 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 ").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(); } diff --git a/libParse/lex_foundation.h b/libParse/lex_foundation.h new file mode 100644 index 0000000..241bb1f --- /dev/null +++ b/libParse/lex_foundation.h @@ -0,0 +1,142 @@ +#pragma once + +#include +#include +#include +#include + +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 sequence); + virtual ~TokensReader() = default; + + /** + * \brief 获取此文件的所有Tokens,转移所有权 + * \return + */ + QList getTokensOfDocument(const QFileInfo &file); + /** + * @brief 获取指定缓冲区内的文本代表的所有Tokens,转移所有权 + * @param buff 缓冲区 + * @param file 提供文件符号 + * @return + */ + QList getTokensOfContents(const QByteArray &buff, const QFileInfo &file); + + private: + QList analysis_sequences; + + /** + * \brief 获取Token序列集合,移交所有权 + * \param source 获取一列内容包含的 + * \return + */ + QList 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 diff --git a/libParse/libParse.pro b/libParse/libParse.pro index 25b6e96..edbf9af 100644 --- a/libParse/libParse.pro +++ b/libParse/libParse.pro @@ -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 diff --git a/libParse/storyconceptdocumentparser.cpp b/libParse/storyconceptdocumentparser.cpp index 48fb6b5..74809f2 100644 --- a/libParse/storyconceptdocumentparser.cpp +++ b/libParse/storyconceptdocumentparser.cpp @@ -98,7 +98,7 @@ NodeStoryConceptParser::NodeStoryConceptParser(Result::ParseCore *core) { set_common_expression("::换行前缀", {Elm("{换行符}"), Elm("{换行符}", true)}); - auto rule = addRule("进入概念解析", 0, [this](const QList &seqs, int cnt)->ParseResult + auto rule = addRule("进入概念解析", 0, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("进入成分解析", 1, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("跳出成分解析", 2, [this](const QList &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 &seqs, int cnt)->ParseResult + auto rule = addRule("进入要点解析", 0, [this, pparser](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("进入成分解析", 1, [this](const QList &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 &seqs, int cnt)->ParseResult { + rule = addRule("跳出成分解析", 2, [this](const QList &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); diff --git a/libParse/tokeniimpl.cpp b/libParse/tokeniimpl.cpp new file mode 100644 index 0000000..bd98997 --- /dev/null +++ b/libParse/tokeniimpl.cpp @@ -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; } diff --git a/libParse/tokeniimpl.h b/libParse/tokeniimpl.h new file mode 100644 index 0000000..8b2b82d --- /dev/null +++ b/libParse/tokeniimpl.h @@ -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 设置实例的内容定义 + /// 词语文本 + /// 行定义 + /// 列定义 + */ + 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