From 4e99a6f120a9ce5fb0c17bd2dc149ce9d0b1a4aa Mon Sep 17 00:00:00 2001
From: codeboss <2422523675@qq.com>
Date: Thu, 20 Jun 2024 21:36:46 +0800
Subject: [PATCH] =?UTF-8?q?=E8=AF=AD=E6=B3=95=E6=8C=87=E5=AF=BC=E7=9A=84?=
=?UTF-8?q?=E6=BA=90=E4=BB=A3=E7=A0=81=E7=BF=BB=E8=AF=91=E5=99=A8=E5=AE=8C?=
=?UTF-8?q?=E6=88=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
WsNovelParser/WsNovelParser.vcxproj.user | 2 +-
WsNovelParser/novelparser.cpp | 8 +-
libParse/parse_novel.cpp | 94 +++++++++++-
libParse/parse_novel.h | 18 ++-
libSyntax/ast_basic.cpp | 12 +-
libSyntax/ast_basic.h | 33 +++--
libSyntax/ast_gen.cpp | 12 +-
libSyntax/ast_gen.h | 15 +-
libSyntax/ast_novel.cpp | 91 ++++++++----
libSyntax/ast_novel.h | 21 ++-
libSyntax/libsyntax.cpp | 180 ++++++-----------------
libSyntax/libsyntax.h | 56 +++----
libSyntax/syntax_novel.cpp | 31 ++--
libSyntax/syntax_novel.h | 8 -
14 files changed, 324 insertions(+), 257 deletions(-)
diff --git a/WsNovelParser/WsNovelParser.vcxproj.user b/WsNovelParser/WsNovelParser.vcxproj.user
index fe96f15..c94f467 100644
--- a/WsNovelParser/WsNovelParser.vcxproj.user
+++ b/WsNovelParser/WsNovelParser.vcxproj.user
@@ -3,7 +3,7 @@
$(SolutionDir)$(Platform)\$(Configuration)\
WindowsLocalDebugger
- --path "D:\手作小说\科学+修仙+创造世界"
+ --path "D:\Projects\Cpp\WsNovelParser\x64\test_file"
--path "D:\手作小说\科学+修仙+创造世界"
diff --git a/WsNovelParser/novelparser.cpp b/WsNovelParser/novelparser.cpp
index 8de0f6d..d252b68 100644
--- a/WsNovelParser/novelparser.cpp
+++ b/WsNovelParser/novelparser.cpp
@@ -12,6 +12,7 @@ NovelParser::NovelParser()
{
this->syntax_defines = example_novel::NovalSyntax::getParseTree();
checker_list << std::make_shared();
+ checker_list << std::make_shared();
checker_list << std::make_shared();
analyzer_ref = std::make_shared(checker_list);
@@ -24,13 +25,14 @@ QString NovelParser::version() const
std::shared_ptr NovelParser::parse(const QFileInfoList source_list) const {
QList> forst_root;
- auto lex_reader = NovalSyntax::getLexReader();
+ auto word_reader = std::make_shared();
auto context = std::make_shared(u8"С˵");
auto time_stamp = QTime::currentTime();
for (auto& file : source_list) {
- auto tokens = lex_reader->tokensWithin(file.canonicalFilePath());
- auto exprs_result = this->syntax_defines->parse(context, tokens);
+ context->setCurrentFile(file.canonicalFilePath());
+ auto words = word_reader->wordsFrom(file.canonicalFilePath());
+ auto exprs_result = this->syntax_defines->parse(context, words);
forst_root.append(std::get<0>(exprs_result));
}
auto current_stamp = QTime::currentTime();
diff --git a/libParse/parse_novel.cpp b/libParse/parse_novel.cpp
index b126154..42e1a42 100644
--- a/libParse/parse_novel.cpp
+++ b/libParse/parse_novel.cpp
@@ -4,6 +4,7 @@
#include
#include
+using namespace lib_parse;
using namespace example_novel;
using namespace ast_basic;
using namespace ast_gen;
@@ -15,7 +16,9 @@ void FragmentExistsCheck::exists_check(std::shared_ptr root
if (target->element()->typeMark() == (int)NovelNode::FragmentRefer) {
auto refer = std::dynamic_pointer_cast(target->element());
auto signature = refer->storyRefer() + u8"&" + refer->fragmentRefer();
- root->getNamedNodeBy((int)NovelNode::FragmentDefine, signature);
+ if(!root->getNamedNodeBy((int)NovelNode::FragmentDefine, signature))
+ throw new SyntaxException(QString(u8"CheckError[0x0005]ϵͳвָǩĽڵ㣺%1{%3:(%4)}")
+ .arg(signature).arg((int)NovelNode::FragmentDefine).arg(refer->signature()).arg(refer->filePath()));
}
for (auto& xit : target->children()) {
@@ -28,7 +31,7 @@ void FragmentExistsCheck::validCheck(std::shared_ptr root)
}
QString FragmentExistsCheck::name() const {
- return u8"FragmentExistsCheck";
+ return u8"ЧԼ";
}
QList> FragmentGraphCheck::refers_cycle_check(
@@ -188,19 +191,19 @@ void FragmentGraphCheck::validCheck(std::shared_ptr root) c
for (auto node : elements_store.values()) {
auto cycle_link = refers_cycle_check(node);
- QString error_msg = u8"Parse[0x0006]ͼڻνṹ\n";
+ QString error_msg = u8"CheckError[0x0006]ôڻνṹ\n";
for (auto n : cycle_link) {
error_msg += QString(u8"%1->").arg(n->nodePeer()->signature());
}
if (cycle_link.size())
- throw new lib_parse::CheckException(error_msg);
+ throw new CheckException(error_msg);
}
}
}
QString FragmentGraphCheck::name() const {
- return u8"FragmentGraphCheck";
+ return u8"ЧԼ";
}
FragmentGraphHelper::FragmentGraphHelper(std::shared_ptr node) : node_peer(node) {}
@@ -223,3 +226,84 @@ uint& FragmentGraphHelper::inDegree()
{
return this->indegree;
}
+
+QList> StoryOrderCheck::valid_docs_peak(std::shared_ptr pnode) const {
+ QList> values;
+ auto type_code = pnode->element()->typeMark();
+
+ switch ((NovelNode)type_code) {
+ case NovelNode::GlobalElement:{
+ auto children = pnode->children();
+ for(auto &cinst : children){
+ values.append(valid_docs_peak(cinst));
+ }
+ }break;
+
+ case NovelNode::Document: {
+ auto storys_collection = pnode->children();
+
+ bool story_exists = false;
+ for (auto& syntax_elm : storys_collection) {
+ if (syntax_elm->element()->typeMark() == (int)NovelNode::StoryDefine) {
+ story_exists = true;
+ break;
+ }
+ }
+
+ if (story_exists) {
+ auto first_elm = storys_collection.at(0);
+ values.append(pnode);
+
+ if(first_elm->element()->typeMark() != (int)NovelNode::RankDeclaration)
+ throw new CheckException(QString(u8"CheckError[0x0007]й½ڵĵڵһָ%1").arg(pnode->element()->path()));
+ }
+ }break;
+
+ default:
+ break;
+ }
+
+ return values;
+}
+
+QString StoryOrderCheck::name() const
+{
+ return u8"ЧԼ";
+}
+
+void StoryOrderCheck::validCheck(std::shared_ptr root) const
+{
+ const_cast(this)->sort_index = 1;
+
+ auto story_docs = valid_docs_peak(root);
+ std::sort(story_docs.begin(), story_docs.end(), [](std::shared_ptr adoc, std::shared_ptr bdoc){
+ auto elm_xa = std::dynamic_pointer_cast(adoc->children().first()->element());
+ auto elm_xb = std::dynamic_pointer_cast(bdoc->children().first()->element());
+ return elm_xa->rankNumber() < elm_xb->rankNumber();
+ });
+
+ // page_rank valid
+ int page_rank = 0;
+ for (auto& item : story_docs) {
+ auto elm_xa = std::dynamic_pointer_cast(item->children().first()->element());
+ if (page_rank >= elm_xa->rankNumber()) {
+ throw new CheckException(QString(u8"CheckError[0x0009]ĵֱ0ͬĵظ{%1}").arg(elm_xa->path()));
+ }
+ }
+
+ // ½ڵ
+ auto story_node_sort = [](std::shared_ptr doc_node, int start_index) -> int{
+ auto childs = doc_node->children();
+ for (auto &inst : childs) {
+ if (inst->element()->typeMark() == (int)NovelNode::StoryDefine) {
+ auto cast_inst = std::dynamic_pointer_cast(inst->element());
+ std::const_pointer_cast(cast_inst)->setSort(start_index++);
+ }
+ }
+ return start_index;
+ };
+
+ int ranks_number = 1;
+ for(auto &story : story_docs)
+ ranks_number = story_node_sort(story, ranks_number);
+}
diff --git a/libParse/parse_novel.h b/libParse/parse_novel.h
index 65c4963..17de0c9 100644
--- a/libParse/parse_novel.h
+++ b/libParse/parse_novel.h
@@ -4,7 +4,6 @@
#include
namespace example_novel {
-
class LIBPARSE_EXPORT FragmentExistsCheck : public lib_parse::CheckProvider {
private:
void exists_check(std::shared_ptr root, std::shared_ptr target) const;
@@ -15,6 +14,7 @@ namespace example_novel {
virtual QString name() const override;
};
+
class FragmentGraphHelper;
class LIBPARSE_EXPORT FragmentGraphCheck : public std::enable_shared_from_this, public lib_parse::CheckProvider {
private:
@@ -54,4 +54,20 @@ namespace example_novel {
};
+ class LIBPARSE_EXPORT StoryOrderCheck : public lib_parse::CheckProvider {
+ private:
+ uint sort_index = 1;
+ /**
+ * ȡʵĵڵ.
+ *
+ * \param pnode
+ * \return
+ */
+ QList> valid_docs_peak(std::shared_ptr pnode) const;
+
+ public:
+ // ͨ CheckProvider ̳
+ QString name() const override;
+ void validCheck(std::shared_ptr root) const override;
+ };
} // namespace example_novel
diff --git a/libSyntax/ast_basic.cpp b/libSyntax/ast_basic.cpp
index 18b19ec..f695f70 100644
--- a/libSyntax/ast_basic.cpp
+++ b/libSyntax/ast_basic.cpp
@@ -18,11 +18,11 @@ QString ast_basic::ExpressionElement::filePath() const {
return tokens_bind.first()->file();
}
-void ast_basic::ExpressionElement::tokensReset(const QList>& list) {
+void ast_basic::ExpressionElement::tokensReset(const QList>& list) {
this->tokens_bind = list;
}
-void ast_basic::ExpressionElement::addToken(std::shared_ptr token_inst) {
+void ast_basic::ExpressionElement::addToken(std::shared_ptr token_inst) {
this->tokens_bind.append(token_inst);
}
@@ -34,10 +34,16 @@ void ast_basic::ExpressionElement::addChild(std::shared_ptr in
this->children_store.append(inst);
}
-QList> ExpressionElement::tokens() const {
+QList> ExpressionElement::tokens() const {
return this->tokens_bind;
}
+ast_basic::ExpressionContext::ExpressionContext() {}
+
+void ast_basic::ExpressionContext::setCurrentFile(const QString& path) { this->current_file_path = path; }
+
+QString ast_basic::ExpressionContext::currentFile() const { return this->current_file_path; }
+
std::shared_ptr ast_basic::ExpressionContext::currentInst() const
{
if(expression_stack.size())
diff --git a/libSyntax/ast_basic.h b/libSyntax/ast_basic.h
index 4146b2b..d5f5110 100644
--- a/libSyntax/ast_basic.h
+++ b/libSyntax/ast_basic.h
@@ -19,7 +19,6 @@ namespace ast_basic {
* @return
*/
virtual std::shared_ptr definedRule() const = 0;
-
//=====================================================
/**
* ȡڵԴļ·.
@@ -32,15 +31,19 @@ namespace ast_basic {
*
* \return token
*/
- virtual QList> tokens() const = 0;
- virtual void tokensReset(const QList> &list) = 0;
+ virtual QList> tokens() const = 0;
+ /**
+ * Token.
+ *
+ * \param list
+ */
+ virtual void tokensReset(const QList> &list) = 0;
/**
* Уʽڲtokenʵ.
*
* \param token_inst ʵ
*/
- virtual void addToken(std::shared_ptr token_inst) = 0;
-
+ virtual void addToken(std::shared_ptr token_inst) = 0;
//=====================================================
/**
* @brief ӱʽ
@@ -60,29 +63,24 @@ namespace ast_basic {
/**
* @brief ʽڵ
*/
- class LIBSYNTAX_EXPORT ExpressionElement : public ast_basic::Expression,
- public std::enable_shared_from_this {
+ class LIBSYNTAX_EXPORT ExpressionElement : public ast_basic::Expression, public std::enable_shared_from_this {
private:
std::shared_ptr _expr_rule;
QList> children_store;
- QList> tokens_bind;
+ QList> tokens_bind;
public:
ExpressionElement(std::shared_ptr bind);
// ͨ Expression ̳
std::shared_ptr definedRule() const override;
-
QString filePath() const override;
- QList> tokens() const override;
-
- void tokensReset(const QList>& list) override;
-
- void addToken(std::shared_ptr token_inst) override;
+ QList> tokens() const override;
+ void tokensReset(const QList>& list) override;
+ void addToken(std::shared_ptr token_inst) override;
QList> children() const override;
-
void addChild(std::shared_ptr inst) override;
};
@@ -90,10 +88,13 @@ namespace ast_basic {
private:
QList> rule_stack;
QList> expression_stack;
+ QString current_file_path;
public:
- ExpressionContext(){}
+ ExpressionContext();
+ virtual void setCurrentFile(const QString& path);
+ virtual QString currentFile() const;
// ͨ ParseContext ̳
std::shared_ptr currentInst() const override;
diff --git a/libSyntax/ast_gen.cpp b/libSyntax/ast_gen.cpp
index e406c07..1e3a521 100644
--- a/libSyntax/ast_gen.cpp
+++ b/libSyntax/ast_gen.cpp
@@ -10,18 +10,18 @@ GlobalElement::GlobalElement(const QString& name) :names_store(name) {
void GlobalElement::clearCache() { node_cache.clear(); }
-void GlobalElement::appendToCache(std::shared_ptr named_node) {
+std::shared_ptr GlobalElement::appendToCache(std::shared_ptr named_node) {
auto mixed_key = QString(u8"%1<%2>").arg(named_node->signature()).arg(named_node->typeMark());
if (node_cache.contains(mixed_key))
- throw new lib_syntax::SyntaxException(QString(u8"Parse[0x0004]ϵͳаͬڵ㣺%1")
- .arg(named_node->signature()).arg(named_node->typeMark()));
+ return node_cache[mixed_key];
node_cache[mixed_key] = named_node;
+ return nullptr;
}
std::shared_ptr GlobalElement::getNamedNodeBy(int type, const QString& signature) const {
auto mixed_key = QString(u8"%1<%2>").arg(signature).arg(type);
if (!node_cache.contains(mixed_key))
- throw new lib_syntax::SyntaxException(QString(u8"Parse[0x0005]ϵͳвָǩĽڵ㣺%1").arg(signature).arg(type));
+ return nullptr;
return node_cache[mixed_key];
}
@@ -73,10 +73,10 @@ QList> ElementAccess::tokens() const {
return element()->selfTokens();
}
-TokenAccess::TokenAccess(std::shared_ptr elm_inst, std::shared_ptr token_inst)
+TokenAccess::TokenAccess(std::shared_ptr elm_inst, std::shared_ptr token_inst)
: element_bind(elm_inst), token_store(token_inst) {}
std::shared_ptr TokenAccess::bind() const { return element_bind; }
-std::shared_ptr TokenAccess::token() const { return token_store; }
+std::shared_ptr TokenAccess::token() const { return token_store; }
diff --git a/libSyntax/ast_gen.h b/libSyntax/ast_gen.h
index 7bf8bf6..d748556 100644
--- a/libSyntax/ast_gen.h
+++ b/libSyntax/ast_gen.h
@@ -53,6 +53,11 @@ namespace ast_gen
* @return δparentnullptr
*/
virtual std::shared_ptr parent() const = 0;
+ /**
+ * @brief øָ.
+ *
+ * \param inst
+ */
virtual void setParent(std::shared_ptr inst) = 0;
/**
@@ -74,7 +79,6 @@ namespace ast_gen
ElementAccess(std::shared_ptr point);
std::shared_ptr element() const;
-
QList> children() const;
/**
@@ -87,12 +91,12 @@ namespace ast_gen
class LIBSYNTAX_EXPORT TokenAccess {
private:
std::shared_ptr element_bind;
- std::shared_ptr token_store;
+ std::shared_ptr token_store;
public:
- TokenAccess(std::shared_ptr elm_inst, std::shared_ptr token_inst);
+ TokenAccess(std::shared_ptr elm_inst, std::shared_ptr token_inst);
virtual std::shared_ptr bind() const;
- virtual std::shared_ptr token() const;
+ virtual std::shared_ptr token() const;
};
/**
@@ -110,7 +114,7 @@ namespace ast_gen
GlobalElement(const QString& name);
virtual void clearCache();
- virtual void appendToCache(std::shared_ptr named_node);
+ virtual std::shared_ptr appendToCache(std::shared_ptr named_node);
/**
* @brief ͨڵǩȡڵ
* @param signature ȫǩ
@@ -118,7 +122,6 @@ namespace ast_gen
* @throws ûָڵ׳쳣
*/
virtual std::shared_ptr getNamedNodeBy(int type, const QString& signature) const;
-
virtual void addChild(std::shared_ptr citem);
// ParseElement interface
diff --git a/libSyntax/ast_novel.cpp b/libSyntax/ast_novel.cpp
index 737b532..25a9e78 100644
--- a/libSyntax/ast_novel.cpp
+++ b/libSyntax/ast_novel.cpp
@@ -2,25 +2,26 @@
using namespace example_novel;
+using namespace lib_syntax;
-TextSection::TextSection(std::shared_ptr rule_bind)
+TextSection::TextSection(std::shared_ptr rule_bind)
: AbstractImpl(rule_bind) {}
-QString example_novel::TextSection::content() const
+QString TextSection::content() const
{
return context_store;
}
int TextSection::typeMark() const { return (int)NovelNode::TextSection; }
-bool example_novel::TextSection::isAnonymous() const
+bool TextSection::isAnonymous() const
{
return true;
}
QString TextSection::signature() const { return u8"::section"; }
-void example_novel::TextSection::cacheLoad()
+void TextSection::cacheLoad()
{
QString text;
for (auto& t : selfTokens()) {
@@ -29,14 +30,14 @@ void example_novel::TextSection::cacheLoad()
context_store = text;
}
-FragmentRefers::FragmentRefers(std::shared_ptr rule_bind)
+FragmentRefers::FragmentRefers(std::shared_ptr rule_bind)
: AbstractImpl(rule_bind) {}
QString FragmentRefers::storyRefer() const { return story_refs; }
QString FragmentRefers::fragmentRefer() const { return fragment_ref; }
-void example_novel::FragmentRefers::cacheLoad()
+void FragmentRefers::cacheLoad()
{
this->story_refs = selfTokens()[5]->token()->content();
this->fragment_ref = selfTokens()[3]->token()->content();
@@ -47,7 +48,7 @@ QString FragmentRefers::referSignature() const {
int FragmentRefers::typeMark() const { return (int)NovelNode::FragmentRefer; }
-bool example_novel::FragmentRefers::isAnonymous() const
+bool FragmentRefers::isAnonymous() const
{
return true;
}
@@ -58,18 +59,18 @@ QString FragmentRefers::signature() const {
}
-FragmentDefine::FragmentDefine(std::shared_ptr rule_bind)
+FragmentDefine::FragmentDefine(std::shared_ptr rule_bind)
: AbstractImpl(rule_bind) {}
QString FragmentDefine::name() const { return name_store; }
-void example_novel::FragmentDefine::cacheLoad()
+void FragmentDefine::cacheLoad()
{
name_store = selfTokens()[2]->token()->content();
}
int FragmentDefine::typeMark() const { return (int)NovelNode::FragmentDefine; }
-bool example_novel::FragmentDefine::isAnonymous() const
+bool FragmentDefine::isAnonymous() const
{
return false;
}
@@ -77,14 +78,18 @@ bool example_novel::FragmentDefine::isAnonymous() const
QString FragmentDefine::signature() const { return parent()->signature() + u8"&" + name(); }
-StoryDefine::StoryDefine(std::shared_ptr rule_bind)
- : AbstractImpl(rule_bind) {}
+StoryDefine::StoryDefine(std::shared_ptr rule_bind)
+ : AbstractImpl(rule_bind), sort_index(0) {}
QString StoryDefine::name() const { return name_store; }
+void example_novel::StoryDefine::setSort(int value){
+ sort_index = value;
+}
+
int StoryDefine::sort() const { return sort_index; }
-void example_novel::StoryDefine::cacheLoad()
+void StoryDefine::cacheLoad()
{
name_store = selfTokens()[3]->token()->content();
sort_index = selfTokens()[2]->token()->content().toInt();
@@ -92,7 +97,7 @@ void example_novel::StoryDefine::cacheLoad()
int StoryDefine::typeMark() const { return (int)NovelNode::StoryDefine; }
-bool example_novel::StoryDefine::isAnonymous() const
+bool StoryDefine::isAnonymous() const
{
return false;
}
@@ -100,23 +105,23 @@ bool example_novel::StoryDefine::isAnonymous() const
QString StoryDefine::signature() const { return name(); }
#include "syntax_novel.h"
-Document::Document(std::shared_ptr rule_bind)
+Document::Document(std::shared_ptr rule_bind)
: AbstractImpl(rule_bind) {}
int Document::typeMark() const { return (int)NovelNode::Document; }
-bool example_novel::Document::isAnonymous() const
+bool Document::isAnonymous() const
{
return true;
}
QString Document::signature() const { return QString(u8"::document<%1>").arg(path()); }
-void example_novel::Document::cacheLoad()
+void Document::cacheLoad()
{
}
-example_novel::AbstractImpl::AbstractImpl(std::shared_ptr rule_bind)
+AbstractImpl::AbstractImpl(std::shared_ptr rule_bind)
: ExpressionElement(rule_bind) { parent_store.reset(); }
QList > AbstractImpl::selfTokens() const {
@@ -129,61 +134,91 @@ QList > AbstractImpl::selfTokens() c
return values;
}
-std::shared_ptr example_novel::AbstractImpl::parent() const
+std::shared_ptr AbstractImpl::parent() const
{
return this->parent_store.lock();
}
-void example_novel::AbstractImpl::setParent(std::shared_ptr inst)
+void AbstractImpl::setParent(std::shared_ptr inst)
{
this->parent_store = inst;
}
// ͨ SyntaxElement ̳
-std::shared_ptr example_novel::AbstractImpl::bindExpression() const {
+std::shared_ptr AbstractImpl::bindExpression() const {
return shared_from_this();
}
-QString example_novel::AbstractImpl::path() const
+QString AbstractImpl::path() const
{
return ast_basic::ExpressionElement::filePath();
}
-VolumeDefine::VolumeDefine(std::shared_ptr rule_bind)
+VolumeDefine::VolumeDefine(std::shared_ptr rule_bind)
: AbstractImpl(rule_bind) {}
QString VolumeDefine::name() const { return name_store; }
-void example_novel::VolumeDefine::cacheLoad()
+void VolumeDefine::cacheLoad()
{
name_store = selfTokens()[2]->token()->content();
}
int VolumeDefine::typeMark() const { return (int)NovelNode::VolumeDefine; }
-bool example_novel::VolumeDefine::isAnonymous() const
+bool VolumeDefine::isAnonymous() const
{
return false;
}
QString VolumeDefine::signature() const { return name(); }
-ArticleDefine::ArticleDefine(std::shared_ptr rule_bind)
+ArticleDefine::ArticleDefine(std::shared_ptr rule_bind)
: AbstractImpl(rule_bind) {}
QString ArticleDefine::name() const { return name_store; }
-void example_novel::ArticleDefine::cacheLoad()
+void ArticleDefine::cacheLoad()
{
name_store = selfTokens()[2]->token()->content();
}
int ArticleDefine::typeMark() const { return (int)NovelNode::ArticleDefine; }
-bool example_novel::ArticleDefine::isAnonymous() const
+bool ArticleDefine::isAnonymous() const
{
return false;
}
QString ArticleDefine::signature() const { return parent()->signature() + u8"&" + name(); }
+
+RankDeclare::RankDeclare(std::shared_ptr rule)
+: AbstractImpl(rule)
+{
+}
+
+int example_novel::RankDeclare::rankNumber() const
+{
+ return page_rank;
+}
+
+int RankDeclare::typeMark() const
+{
+ return (int)NovelNode::RankDeclaration;
+}
+
+bool RankDeclare::isAnonymous() const
+{
+ return true;
+}
+
+QString RankDeclare::signature() const
+{
+ return u8"::rank";
+}
+
+void RankDeclare::cacheLoad()
+{
+ page_rank = selfTokens()[2]->token()->content().toInt();
+}
diff --git a/libSyntax/ast_novel.h b/libSyntax/ast_novel.h
index 9fc4859..47c10ea 100644
--- a/libSyntax/ast_novel.h
+++ b/libSyntax/ast_novel.h
@@ -5,6 +5,7 @@
namespace example_novel
{
enum class NovelNode {
+ GlobalElement = 0,
TextSection = 1,
FragmentRefer = 2,
FragmentDefine = 3,
@@ -12,10 +13,10 @@ namespace example_novel
Document = 5,
ArticleDefine = 6,
VolumeDefine = 7,
+ RankDeclaration = 8,
};
- class LIBSYNTAX_EXPORT AbstractImpl :
- public ast_basic::ExpressionElement, public ast_gen::SyntaxElement {
+ class LIBSYNTAX_EXPORT AbstractImpl : public ast_basic::ExpressionElement, public ast_gen::SyntaxElement {
private:
std::weak_ptr parent_store;
@@ -123,6 +124,7 @@ namespace example_novel
StoryDefine(std::shared_ptr rule_bind);
QString name() const;
+ void setSort(int value);
int sort() const;
// SyntaxElement interface
@@ -148,4 +150,19 @@ namespace example_novel
virtual QString signature() const override;
virtual void cacheLoad() override;
};
+
+ class LIBSYNTAX_EXPORT RankDeclare : public AbstractImpl {
+ private:
+ int page_rank = 0;
+ public:
+ RankDeclare(std::shared_ptr rule);
+
+ int rankNumber() const;
+
+ // ͨ AbstractImpl ̳
+ int typeMark() const override;
+ bool isAnonymous() const override;
+ QString signature() const override;
+ void cacheLoad() override;
+ };
}
diff --git a/libSyntax/libsyntax.cpp b/libSyntax/libsyntax.cpp
index 146aae7..5649b00 100644
--- a/libSyntax/libsyntax.cpp
+++ b/libSyntax/libsyntax.cpp
@@ -6,30 +6,28 @@ using namespace std;
using namespace lib_token;
using namespace ast_basic;
-TokenMatch::TokenMatch(shared_ptr define) : define_peer(define) {}
+TokenMatch::TokenMatch(shared_ptr define) : define_peer(define) {}
QList> TokenMatch::children() const { return QList>(); }
-std::tuple> TokenMatch::match(std::shared_ptr remains_head) const {
- QString token_seqs = this->token_present();
- if (remains_head && remains_head->define()->typeMark() == define_peer->typeMark())
- return std::make_tuple(MatchResult::Success, 1, remains_head->nextToken());
-
- return std::make_tuple(MatchResult::Fail, 0, nullptr);
- // auto mis_match = define_peer->name();
- // auto real_match = stream.first()->define()->name();
-}
-// std::tuple, std::shared_ptr>
-std::tuple, std::shared_ptr> TokenMatch::parse(std::shared_ptr rt_inst, std::shared_ptr head) const {
+std::tuple, std::shared_ptr> TokenMatch::parse(std::shared_ptr rt_inst, std::shared_ptr head) const {
if (!head)
- throw std::make_shared();
+ throw new InputTerminal(rt_inst->currentFile());
- if (head->define()->typeMark() == define_peer->typeMark()) {
- rt_inst->currentInst()->addToken(head);
- return std::make_tuple(nullptr, head->nextToken());
+ auto match_result = define_peer->analysis(head);
+ if (std::get<0>(match_result)) {
+ rt_inst->currentInst()->addToken(std::get<0>(match_result));
+ }
+ else {
+ throw new MismatchException(head);
}
- throw std::make_shared(head);
+ if (std::get<1>(match_result)) {
+ return std::make_tuple(nullptr, std::make_shared(std::get<1>(match_result), head->nextWord()));
+ }
+ else {
+ return std::make_tuple(nullptr, head->nextWord());
+ }
}
QString TokenMatch::token_present() const {
@@ -40,41 +38,7 @@ Rept::Rept(std::shared_ptr rule, int min, int max) : rule_peer(r
QList> Rept::children() const { return QList>() << rule_peer; }
-std::tuple> Rept::match(std::shared_ptr list_head) const {
- auto token_offset = 0;
- QString token_seqs = this->token_present();
- auto temp_head = list_head;
-
- // min-match
- for (auto idx = 0; idx < min_match; ++idx) {
- auto result = rule_peer->match(temp_head);
- token_offset += std::get<1>(result);
- temp_head = std::get<2>(result);
-
- if (std::get<0>(result) != MatchResult::Success) {
- return std::make_tuple(token_offset ? MatchResult::Part : MatchResult::Fail, token_offset, temp_head);
- }
- }
-
- // max-match
- for (auto idx = min_match; idx < max_match; ++idx) {
- auto result = rule_peer->match(temp_head);
-
- switch (std::get<0>(result)) {
- case MatchResult::Fail:
- case MatchResult::Part:
- return std::make_tuple(MatchResult::Success, token_offset, temp_head);
- default:
- temp_head = std::get<2>(result);
- token_offset += std::get<1>(result);
- break;
- }
- }
-
- return std::make_tuple(MatchResult::Success, token_offset, temp_head);
-}
-
-std::tuple, std::shared_ptr> Rept::parse(std::shared_ptr rt_inst, std::shared_ptr head) const {
+std::tuple, std::shared_ptr> Rept::parse(std::shared_ptr rt_inst, std::shared_ptr head) const {
auto temp_head = head;
// min-match
@@ -95,10 +59,8 @@ std::tuple, std::shared_ptr> Rept
temp_head = std::get<1>(result_gen);
}
- catch (std::shared_ptr ex) {
- return std::make_tuple(nullptr, temp_head);
- }
- catch (std::shared_ptr ex) {
+ catch (SyntaxException* ex) {
+ delete ex;
return std::make_tuple(nullptr, temp_head);
}
}
@@ -115,30 +77,7 @@ Seqs::Seqs(const QList> mbrs) : mbrs_store(mbrs)
QList> Seqs::children() const { return mbrs_store; }
-std::tuple> Seqs::match(std::shared_ptr list_head) const {
- auto token_offset = 0;
- QString token_seqs = this->token_present();
- auto temp_head = list_head;
-
- for (auto& r : mbrs_store) {
- auto v_token_seqs = r->token_present();
- auto result = r->match(list_head);
- token_offset += std::get<1>(result);
- temp_head = std::get<2>(result);
-
- switch (std::get<0>(result)) {
- case MatchResult::Fail:
- case MatchResult::Part:
- return std::make_tuple(token_offset ? MatchResult::Part : MatchResult::Fail, token_offset, temp_head);
- default:
- break;
- }
- }
-
- return std::make_tuple(MatchResult::Success, token_offset, temp_head);
-}
-
-std::tuple, std::shared_ptr> Seqs::parse(std::shared_ptr rt_inst, std::shared_ptr head) const {
+std::tuple, std::shared_ptr> Seqs::parse(std::shared_ptr rt_inst, std::shared_ptr head) const {
auto temp_head = head;
for (auto& r : mbrs_store) {
@@ -160,53 +99,30 @@ QString Seqs::token_present() const
return QString(u8"(%1)").arg(content);
}
-std::tuple, std::shared_ptr>
-Any::rule_select(std::shared_ptr head) const {
- QString token_seqs = this->token_present();
- std::tuple, std::shared_ptr> temp = std::make_tuple(MatchResult::Fail, 0, nullptr, nullptr);
-
- for (auto& r : mbrs_store) {
- auto mbr_seqs = r->token_present();
- auto result = r->match(head);
- if (std::get<0>(result) == MatchResult::Success)
- return std::make_tuple(std::get<0>(result), std::get<1>(result), r, std::get<2>(result));
-
- else if (std::get<0>(result) == MatchResult::Part) {
- if (std::get<0>(temp) == MatchResult::Fail || std::get<1>(result) > std::get<1>(temp))
- temp = std::make_tuple(MatchResult::Part, std::get<1>(result), r, std::get<2>(result));
- else
- temp = std::make_tuple(MatchResult::Part, std::get<1>(temp), std::get<2>(temp), std::get<3>(temp));
- }
-
- else if (std::get<0>(temp) == MatchResult::Fail) {
- if (!std::get<2>(temp) || std::get<1>(result) > std::get<1>(temp))
- temp = std::make_tuple(MatchResult::Fail, std::get<1>(result), r, std::get<2>(result));
- else
- temp = std::make_tuple(MatchResult::Fail, std::get<1>(temp), std::get<2>(temp), std::get<3>(temp));
- }
- }
-
- return temp;
-}
-
+//std::tuple, std::shared_ptr>
Any::Any(const QList> mbrs) : mbrs_store(mbrs) {}
QList> Any::children() const { return mbrs_store; }
-std::tuple> Any::match(std::shared_ptr list_head) const {
- auto item = rule_select(list_head);
- return std::make_tuple(std::get<0>(item), std::get<1>(item), std::get<3>(item));
-}
-
-std::tuple, std::shared_ptr> Any::parse(std::shared_ptr rt_inst, std::shared_ptr head) const {
- std::function, std::shared_ptr)> measure_span =
- [&](std::shared_ptr anchor, std::shared_ptr head)->int {
- if (anchor == head)
- return 1;
- return measure_span(anchor, head->nextToken()) + 1;
+class words_span {
+public:
+ int row_span, column_span;
+ words_span(int rspan, int cspan):row_span(rspan), column_span(cspan){}
+ bool operator>(const words_span& other) {
+ if(row_span > other.row_span)
+ return true;
+ if(row_span == other.row_span)
+ return column_span > other.column_span;
+ return false;
+ }
+};
+std::tuple, std::shared_ptr> Any::parse(std::shared_ptr rt_inst, std::shared_ptr head) const {
+ std::function, std::shared_ptr)> measure_span =
+ [&](std::shared_ptr anchor, std::shared_ptr head)->words_span {
+ return words_span(anchor->row() - head->row(), anchor->column() - head->column());
};
- std::tuple, int> temp_result = std::make_tuple(mbrs_store.first(), 0);
+ std::tuple, words_span> temp_result = std::make_tuple(mbrs_store.first(), words_span(0,0));
for (auto& fork : mbrs_store) {
try {
auto gen = fork->parse(rt_inst, head);
@@ -217,11 +133,13 @@ std::tuple, std::shared_ptr> Any:
return std::make_tuple(nullptr, std::get<1>(gen));
}
// ĻбȽ
- catch (std::shared_ptr ex) {
- auto current_span = measure_span(ex->targetToken(), head);
+ catch (MismatchException* ex) {
+ auto current_span = measure_span(ex->targetWord(), head);
if (current_span > std::get<1>(temp_result))
temp_result = std::make_tuple(fork, current_span);
+
+ delete ex;
}
}
@@ -263,11 +181,7 @@ QList> ExpressionRule::children() const {
return QList>() << this->child_store;
}
-std::tuple> ExpressionRule::match(std::shared_ptr list_head) const {
- return child_store->match(list_head);
-}
-
-std::tuple, std::shared_ptr> ExpressionRule::parse(std::shared_ptr rt_inst, std::shared_ptr head) const {
+std::tuple, std::shared_ptr> ExpressionRule::parse(std::shared_ptr rt_inst, std::shared_ptr head) const {
std::shared_ptr elm_ast = this->newEmptyInstance();
rt_inst->pushExpressionRule(this->shared_from_this());
@@ -294,11 +208,13 @@ QString ExpressionRule::token_present() const {
return QString(u8"(%1)").arg(child_store->token_present());
}
-MismatchException::MismatchException(std::shared_ptr inst) :SyntaxException(
- QString(u8"Syntax[0x00001]ƥʶtoken%1<%2,%3>").arg(inst->content()).arg(inst->row()).arg(inst->column())), target(inst) {}
+MismatchException::MismatchException(std::shared_ptr inst) :SyntaxException(
+ QString(u8"Syntax[0x00001]ƥʶtoken%1<%2,%3>(%4)")
+ .arg(inst->content()).arg(inst->row()).arg(inst->column()).arg(inst->file())), target(inst) {}
-std::shared_ptrMismatchException::targetToken() const {
+std::shared_ptrMismatchException::targetWord() const {
return this->target;
}
-InputTerminal::InputTerminal() :SyntaxException(u8"Syntax[0x0000]tokenǰֹ") {}
\ No newline at end of file
+InputTerminal::InputTerminal(const QString& file_path)
+ :SyntaxException(QString(u8"Syntax[0x0000]token%1ǰֹ").arg(file_path)) {}
diff --git a/libSyntax/libsyntax.h b/libSyntax/libsyntax.h
index 27e91c6..56da438 100644
--- a/libSyntax/libsyntax.h
+++ b/libSyntax/libsyntax.h
@@ -16,7 +16,7 @@ namespace lib_syntax {
/**
* @brief 쳣
*/
- class SyntaxException {
+ class LIBSYNTAX_EXPORT SyntaxException {
private:
QString msg_store;
@@ -35,6 +35,9 @@ namespace lib_syntax {
public:
virtual ~ParseContext() = default;
+ virtual void setCurrentFile(const QString &path) = 0;
+ virtual QString currentFile() const = 0;
+
/**
* \brief ǰʽԪ.
*
@@ -70,20 +73,14 @@ namespace lib_syntax {
Fail // ӵһȫƥ
};
- /**
- * @brief tokenƥ
- * @return ײ룬ƥtoken<ƥƥ䳤ȣʣбͷָ>
- */
- virtual std::tuple> match(std::shared_ptr remains_head) const = 0;
-
/**
* @brief
* @param rt_inst
* @param head бͷ
* @return ؽ<ƥбͷ,ƥ䳤>
*/
- virtual std::tuple, std::shared_ptr>
- parse(std::shared_ptr rt_inst, std::shared_ptr head) const = 0;
+ virtual std::tuple, std::shared_ptr>
+ parse(std::shared_ptr rt_inst, std::shared_ptr head) const = 0;
/**
* ƥĴʷб
@@ -99,17 +96,16 @@ namespace lib_syntax {
*/
class LIBSYNTAX_EXPORT TokenMatch : public BaseRule, public std::enable_shared_from_this {
private:
- std::shared_ptr define_peer;
+ std::shared_ptr define_peer;
public:
- TokenMatch(std::shared_ptr define);
+ TokenMatch(std::shared_ptr define);
// BaseRule interface
public:
virtual QList> children() const override;
- virtual std::tuple> match(std::shared_ptr head) const override;
- virtual std::tuple, std::shared_ptr>
- parse(std::shared_ptr rt_inst, std::shared_ptr head) const override;
+ virtual std::tuple, std::shared_ptr