语法指导的源代码翻译器完成
This commit is contained in:
parent
dba8c71f84
commit
4e99a6f120
|
@ -3,7 +3,7 @@
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LocalDebuggerWorkingDirectory>$(SolutionDir)$(Platform)\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
<LocalDebuggerWorkingDirectory>$(SolutionDir)$(Platform)\$(Configuration)\</LocalDebuggerWorkingDirectory>
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
<LocalDebuggerCommandArguments>--path "D:\手作小说\科学+修仙+创造世界"</LocalDebuggerCommandArguments>
|
<LocalDebuggerCommandArguments>--path "D:\Projects\Cpp\WsNovelParser\x64\test_file"</LocalDebuggerCommandArguments>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LocalDebuggerCommandArguments>--path "D:\手作小说\科学+修仙+创造世界"</LocalDebuggerCommandArguments>
|
<LocalDebuggerCommandArguments>--path "D:\手作小说\科学+修仙+创造世界"</LocalDebuggerCommandArguments>
|
||||||
|
|
|
@ -12,6 +12,7 @@ NovelParser::NovelParser()
|
||||||
{
|
{
|
||||||
this->syntax_defines = example_novel::NovalSyntax::getParseTree();
|
this->syntax_defines = example_novel::NovalSyntax::getParseTree();
|
||||||
checker_list << std::make_shared<example_novel::FragmentExistsCheck>();
|
checker_list << std::make_shared<example_novel::FragmentExistsCheck>();
|
||||||
|
checker_list << std::make_shared<example_novel::StoryOrderCheck>();
|
||||||
checker_list << std::make_shared<example_novel::FragmentGraphCheck>();
|
checker_list << std::make_shared<example_novel::FragmentGraphCheck>();
|
||||||
|
|
||||||
analyzer_ref = std::make_shared<lib_parse::Analyzer>(checker_list);
|
analyzer_ref = std::make_shared<lib_parse::Analyzer>(checker_list);
|
||||||
|
@ -24,13 +25,14 @@ QString NovelParser::version() const
|
||||||
|
|
||||||
std::shared_ptr<const ast_gen::ElementAccess> NovelParser::parse(const QFileInfoList source_list) const {
|
std::shared_ptr<const ast_gen::ElementAccess> NovelParser::parse(const QFileInfoList source_list) const {
|
||||||
QList<std::shared_ptr<const ast_basic::Expression>> forst_root;
|
QList<std::shared_ptr<const ast_basic::Expression>> forst_root;
|
||||||
auto lex_reader = NovalSyntax::getLexReader();
|
auto word_reader = std::make_shared<lib_token::WordReader>();
|
||||||
auto context = std::make_shared<ast_gen::GlobalElement>(u8"С˵");
|
auto context = std::make_shared<ast_gen::GlobalElement>(u8"С˵");
|
||||||
|
|
||||||
auto time_stamp = QTime::currentTime();
|
auto time_stamp = QTime::currentTime();
|
||||||
for (auto& file : source_list) {
|
for (auto& file : source_list) {
|
||||||
auto tokens = lex_reader->tokensWithin(file.canonicalFilePath());
|
context->setCurrentFile(file.canonicalFilePath());
|
||||||
auto exprs_result = this->syntax_defines->parse(context, tokens);
|
auto words = word_reader->wordsFrom(file.canonicalFilePath());
|
||||||
|
auto exprs_result = this->syntax_defines->parse(context, words);
|
||||||
forst_root.append(std::get<0>(exprs_result));
|
forst_root.append(std::get<0>(exprs_result));
|
||||||
}
|
}
|
||||||
auto current_stamp = QTime::currentTime();
|
auto current_stamp = QTime::currentTime();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
|
using namespace lib_parse;
|
||||||
using namespace example_novel;
|
using namespace example_novel;
|
||||||
using namespace ast_basic;
|
using namespace ast_basic;
|
||||||
using namespace ast_gen;
|
using namespace ast_gen;
|
||||||
|
@ -15,7 +16,9 @@ void FragmentExistsCheck::exists_check(std::shared_ptr<const GlobalElement> root
|
||||||
if (target->element()->typeMark() == (int)NovelNode::FragmentRefer) {
|
if (target->element()->typeMark() == (int)NovelNode::FragmentRefer) {
|
||||||
auto refer = std::dynamic_pointer_cast<const FragmentRefers>(target->element());
|
auto refer = std::dynamic_pointer_cast<const FragmentRefers>(target->element());
|
||||||
auto signature = refer->storyRefer() + u8"&" + refer->fragmentRefer();
|
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<type:%2>{%3:(%4)}")
|
||||||
|
.arg(signature).arg((int)NovelNode::FragmentDefine).arg(refer->signature()).arg(refer->filePath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& xit : target->children()) {
|
for (auto& xit : target->children()) {
|
||||||
|
@ -28,7 +31,7 @@ void FragmentExistsCheck::validCheck(std::shared_ptr<const ElementAccess> root)
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FragmentExistsCheck::name() const {
|
QString FragmentExistsCheck::name() const {
|
||||||
return u8"FragmentExistsCheck";
|
return u8"情节引用有效性检查器";
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<std::shared_ptr<FragmentGraphHelper>> FragmentGraphCheck::refers_cycle_check(
|
QList<std::shared_ptr<FragmentGraphHelper>> FragmentGraphCheck::refers_cycle_check(
|
||||||
|
@ -188,19 +191,19 @@ void FragmentGraphCheck::validCheck(std::shared_ptr<const ElementAccess> root) c
|
||||||
for (auto node : elements_store.values()) {
|
for (auto node : elements_store.values()) {
|
||||||
auto cycle_link = refers_cycle_check(node);
|
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) {
|
for (auto n : cycle_link) {
|
||||||
error_msg += QString(u8"%1->").arg(n->nodePeer()->signature());
|
error_msg += QString(u8"%1->").arg(n->nodePeer()->signature());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cycle_link.size())
|
if (cycle_link.size())
|
||||||
throw new lib_parse::CheckException(error_msg);
|
throw new CheckException(error_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FragmentGraphCheck::name() const {
|
QString FragmentGraphCheck::name() const {
|
||||||
return u8"FragmentGraphCheck";
|
return u8"情节网络有效性检查器";
|
||||||
}
|
}
|
||||||
|
|
||||||
FragmentGraphHelper::FragmentGraphHelper(std::shared_ptr<const FragmentDefine> node) : node_peer(node) {}
|
FragmentGraphHelper::FragmentGraphHelper(std::shared_ptr<const FragmentDefine> node) : node_peer(node) {}
|
||||||
|
@ -223,3 +226,84 @@ uint& FragmentGraphHelper::inDegree()
|
||||||
{
|
{
|
||||||
return this->indegree;
|
return this->indegree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<std::shared_ptr<const ElementAccess>> StoryOrderCheck::valid_docs_peak(std::shared_ptr<const ElementAccess> pnode) const {
|
||||||
|
QList<std::shared_ptr<const ElementAccess>> 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<const ElementAccess> root) const
|
||||||
|
{
|
||||||
|
const_cast<StoryOrderCheck*>(this)->sort_index = 1;
|
||||||
|
|
||||||
|
auto story_docs = valid_docs_peak(root);
|
||||||
|
std::sort(story_docs.begin(), story_docs.end(), [](std::shared_ptr<const ElementAccess> adoc, std::shared_ptr<const ElementAccess> bdoc){
|
||||||
|
auto elm_xa = std::dynamic_pointer_cast<const RankDeclare>(adoc->children().first()->element());
|
||||||
|
auto elm_xb = std::dynamic_pointer_cast<const RankDeclare>(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<const RankDeclare>(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<const ElementAccess> 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<const StoryDefine>(inst->element());
|
||||||
|
std::const_pointer_cast<StoryDefine>(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);
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include <ast_novel.h>
|
#include <ast_novel.h>
|
||||||
|
|
||||||
namespace example_novel {
|
namespace example_novel {
|
||||||
|
|
||||||
class LIBPARSE_EXPORT FragmentExistsCheck : public lib_parse::CheckProvider {
|
class LIBPARSE_EXPORT FragmentExistsCheck : public lib_parse::CheckProvider {
|
||||||
private:
|
private:
|
||||||
void exists_check(std::shared_ptr<const ast_gen::GlobalElement> root, std::shared_ptr<const ast_gen::ElementAccess> target) const;
|
void exists_check(std::shared_ptr<const ast_gen::GlobalElement> root, std::shared_ptr<const ast_gen::ElementAccess> target) const;
|
||||||
|
@ -15,6 +14,7 @@ namespace example_novel {
|
||||||
virtual QString name() const override;
|
virtual QString name() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class FragmentGraphHelper;
|
class FragmentGraphHelper;
|
||||||
class LIBPARSE_EXPORT FragmentGraphCheck : public std::enable_shared_from_this<FragmentGraphCheck>, public lib_parse::CheckProvider {
|
class LIBPARSE_EXPORT FragmentGraphCheck : public std::enable_shared_from_this<FragmentGraphCheck>, public lib_parse::CheckProvider {
|
||||||
private:
|
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<std::shared_ptr<const ast_gen::ElementAccess>> valid_docs_peak(std::shared_ptr<const ast_gen::ElementAccess> pnode) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// 通过 CheckProvider 继承
|
||||||
|
QString name() const override;
|
||||||
|
void validCheck(std::shared_ptr<const ast_gen::ElementAccess> root) const override;
|
||||||
|
};
|
||||||
} // namespace example_novel
|
} // namespace example_novel
|
||||||
|
|
|
@ -18,11 +18,11 @@ QString ast_basic::ExpressionElement::filePath() const {
|
||||||
return tokens_bind.first()->file();
|
return tokens_bind.first()->file();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ast_basic::ExpressionElement::tokensReset(const QList<std::shared_ptr<const lib_token::Token>>& list) {
|
void ast_basic::ExpressionElement::tokensReset(const QList<std::shared_ptr<const IToken>>& list) {
|
||||||
this->tokens_bind = list;
|
this->tokens_bind = list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ast_basic::ExpressionElement::addToken(std::shared_ptr<const lib_token::Token> token_inst) {
|
void ast_basic::ExpressionElement::addToken(std::shared_ptr<const IToken> token_inst) {
|
||||||
this->tokens_bind.append(token_inst);
|
this->tokens_bind.append(token_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,10 +34,16 @@ void ast_basic::ExpressionElement::addChild(std::shared_ptr<const Expression> in
|
||||||
this->children_store.append(inst);
|
this->children_store.append(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<std::shared_ptr<const Token>> ExpressionElement::tokens() const {
|
QList<std::shared_ptr<const IToken>> ExpressionElement::tokens() const {
|
||||||
return this->tokens_bind;
|
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::Expression> ast_basic::ExpressionContext::currentInst() const
|
std::shared_ptr<ast_basic::Expression> ast_basic::ExpressionContext::currentInst() const
|
||||||
{
|
{
|
||||||
if(expression_stack.size())
|
if(expression_stack.size())
|
||||||
|
|
|
@ -19,7 +19,6 @@ namespace ast_basic {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual std::shared_ptr<const lib_syntax::ExpressionRule> definedRule() const = 0;
|
virtual std::shared_ptr<const lib_syntax::ExpressionRule> definedRule() const = 0;
|
||||||
|
|
||||||
//=====================================================
|
//=====================================================
|
||||||
/**
|
/**
|
||||||
* 获取语法节点的源码文件路径.
|
* 获取语法节点的源码文件路径.
|
||||||
|
@ -32,15 +31,19 @@ namespace ast_basic {
|
||||||
*
|
*
|
||||||
* \return token序列
|
* \return token序列
|
||||||
*/
|
*/
|
||||||
virtual QList<std::shared_ptr<const lib_token::Token>> tokens() const = 0;
|
virtual QList<std::shared_ptr<const lib_token::IToken>> tokens() const = 0;
|
||||||
virtual void tokensReset(const QList<std::shared_ptr<const lib_token::Token>> &list) = 0;
|
/**
|
||||||
|
* ÖØÖÃÓï·¨Token¼¯.
|
||||||
|
*
|
||||||
|
* \param list
|
||||||
|
*/
|
||||||
|
virtual void tokensReset(const QList<std::shared_ptr<const lib_token::IToken>> &list) = 0;
|
||||||
/**
|
/**
|
||||||
* 解析过程中,向表达式内部添加token实例.
|
* 解析过程中,向表达式内部添加token实例.
|
||||||
*
|
*
|
||||||
* \param token_inst 实例
|
* \param token_inst 实例
|
||||||
*/
|
*/
|
||||||
virtual void addToken(std::shared_ptr<const lib_token::Token> token_inst) = 0;
|
virtual void addToken(std::shared_ptr<const lib_token::IToken> token_inst) = 0;
|
||||||
|
|
||||||
//=====================================================
|
//=====================================================
|
||||||
/**
|
/**
|
||||||
* @brief 子表达式集合
|
* @brief 子表达式集合
|
||||||
|
@ -60,29 +63,24 @@ namespace ast_basic {
|
||||||
/**
|
/**
|
||||||
* @brief 表达式节点
|
* @brief 表达式节点
|
||||||
*/
|
*/
|
||||||
class LIBSYNTAX_EXPORT ExpressionElement : public ast_basic::Expression,
|
class LIBSYNTAX_EXPORT ExpressionElement : public ast_basic::Expression, public std::enable_shared_from_this<ExpressionElement> {
|
||||||
public std::enable_shared_from_this<ExpressionElement> {
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<const lib_syntax::ExpressionRule> _expr_rule;
|
std::shared_ptr<const lib_syntax::ExpressionRule> _expr_rule;
|
||||||
QList<std::shared_ptr<const Expression>> children_store;
|
QList<std::shared_ptr<const Expression>> children_store;
|
||||||
QList<std::shared_ptr<const lib_token::Token>> tokens_bind;
|
QList<std::shared_ptr<const lib_token::IToken>> tokens_bind;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExpressionElement(std::shared_ptr<const lib_syntax::ExpressionRule> bind);
|
ExpressionElement(std::shared_ptr<const lib_syntax::ExpressionRule> bind);
|
||||||
|
|
||||||
// 通过 Expression 继承
|
// 通过 Expression 继承
|
||||||
std::shared_ptr<const lib_syntax::ExpressionRule> definedRule() const override;
|
std::shared_ptr<const lib_syntax::ExpressionRule> definedRule() const override;
|
||||||
|
|
||||||
QString filePath() const override;
|
QString filePath() const override;
|
||||||
|
|
||||||
QList<std::shared_ptr<const lib_token::Token>> tokens() const override;
|
QList<std::shared_ptr<const lib_token::IToken>> tokens() const override;
|
||||||
|
void tokensReset(const QList<std::shared_ptr<const lib_token::IToken>>& list) override;
|
||||||
void tokensReset(const QList<std::shared_ptr<const lib_token::Token>>& list) override;
|
void addToken(std::shared_ptr<const lib_token::IToken> token_inst) override;
|
||||||
|
|
||||||
void addToken(std::shared_ptr<const lib_token::Token> token_inst) override;
|
|
||||||
|
|
||||||
QList<std::shared_ptr<const Expression>> children() const override;
|
QList<std::shared_ptr<const Expression>> children() const override;
|
||||||
|
|
||||||
void addChild(std::shared_ptr<const Expression> inst) override;
|
void addChild(std::shared_ptr<const Expression> inst) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,10 +88,13 @@ namespace ast_basic {
|
||||||
private:
|
private:
|
||||||
QList<std::shared_ptr<const lib_syntax::BaseRule>> rule_stack;
|
QList<std::shared_ptr<const lib_syntax::BaseRule>> rule_stack;
|
||||||
QList<std::shared_ptr<Expression>> expression_stack;
|
QList<std::shared_ptr<Expression>> expression_stack;
|
||||||
|
QString current_file_path;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExpressionContext(){}
|
ExpressionContext();
|
||||||
|
|
||||||
|
virtual void setCurrentFile(const QString& path);
|
||||||
|
virtual QString currentFile() const;
|
||||||
|
|
||||||
// 通过 ParseContext 继承
|
// 通过 ParseContext 继承
|
||||||
std::shared_ptr<ast_basic::Expression> currentInst() const override;
|
std::shared_ptr<ast_basic::Expression> currentInst() const override;
|
||||||
|
|
|
@ -10,18 +10,18 @@ GlobalElement::GlobalElement(const QString& name) :names_store(name) {
|
||||||
|
|
||||||
void GlobalElement::clearCache() { node_cache.clear(); }
|
void GlobalElement::clearCache() { node_cache.clear(); }
|
||||||
|
|
||||||
void GlobalElement::appendToCache(std::shared_ptr<const SyntaxElement> named_node) {
|
std::shared_ptr<const SyntaxElement> GlobalElement::appendToCache(std::shared_ptr<const SyntaxElement> named_node) {
|
||||||
auto mixed_key = QString(u8"%1<%2>").arg(named_node->signature()).arg(named_node->typeMark());
|
auto mixed_key = QString(u8"%1<%2>").arg(named_node->signature()).arg(named_node->typeMark());
|
||||||
if (node_cache.contains(mixed_key))
|
if (node_cache.contains(mixed_key))
|
||||||
throw new lib_syntax::SyntaxException(QString(u8"Parse[0x0004]系统中包含同类型重名命名节点:%1<type:%2>")
|
return node_cache[mixed_key];
|
||||||
.arg(named_node->signature()).arg(named_node->typeMark()));
|
|
||||||
node_cache[mixed_key] = named_node;
|
node_cache[mixed_key] = named_node;
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const SyntaxElement> GlobalElement::getNamedNodeBy(int type, const QString& signature) const {
|
std::shared_ptr<const SyntaxElement> GlobalElement::getNamedNodeBy(int type, const QString& signature) const {
|
||||||
auto mixed_key = QString(u8"%1<%2>").arg(signature).arg(type);
|
auto mixed_key = QString(u8"%1<%2>").arg(signature).arg(type);
|
||||||
if (!node_cache.contains(mixed_key))
|
if (!node_cache.contains(mixed_key))
|
||||||
throw new lib_syntax::SyntaxException(QString(u8"Parse[0x0005]系统中不包含指定签名的节点:%1<type:%2>").arg(signature).arg(type));
|
return nullptr;
|
||||||
return node_cache[mixed_key];
|
return node_cache[mixed_key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,10 +73,10 @@ QList<std::shared_ptr<const TokenAccess>> ElementAccess::tokens() const {
|
||||||
return element()->selfTokens();
|
return element()->selfTokens();
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenAccess::TokenAccess(std::shared_ptr<const SyntaxElement> elm_inst, std::shared_ptr<const lib_token::Token> token_inst)
|
TokenAccess::TokenAccess(std::shared_ptr<const SyntaxElement> elm_inst, std::shared_ptr<const lib_token::IToken> token_inst)
|
||||||
: element_bind(elm_inst), token_store(token_inst) {}
|
: element_bind(elm_inst), token_store(token_inst) {}
|
||||||
|
|
||||||
std::shared_ptr<const SyntaxElement> TokenAccess::bind() const { return element_bind; }
|
std::shared_ptr<const SyntaxElement> TokenAccess::bind() const { return element_bind; }
|
||||||
|
|
||||||
std::shared_ptr<const lib_token::Token> TokenAccess::token() const { return token_store; }
|
std::shared_ptr<const lib_token::IToken> TokenAccess::token() const { return token_store; }
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,11 @@ namespace ast_gen
|
||||||
* @return 未设置parent,返回nullptr
|
* @return 未设置parent,返回nullptr
|
||||||
*/
|
*/
|
||||||
virtual std::shared_ptr<const SyntaxElement> parent() const = 0;
|
virtual std::shared_ptr<const SyntaxElement> parent() const = 0;
|
||||||
|
/**
|
||||||
|
* @brief ÖØÖø¸Ö¸Õë.
|
||||||
|
*
|
||||||
|
* \param inst
|
||||||
|
*/
|
||||||
virtual void setParent(std::shared_ptr<const SyntaxElement> inst) = 0;
|
virtual void setParent(std::shared_ptr<const SyntaxElement> inst) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +79,6 @@ namespace ast_gen
|
||||||
ElementAccess(std::shared_ptr<const SyntaxElement> point);
|
ElementAccess(std::shared_ptr<const SyntaxElement> point);
|
||||||
|
|
||||||
std::shared_ptr<const SyntaxElement> element() const;
|
std::shared_ptr<const SyntaxElement> element() const;
|
||||||
|
|
||||||
QList<std::shared_ptr<const ElementAccess>> children() const;
|
QList<std::shared_ptr<const ElementAccess>> children() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,12 +91,12 @@ namespace ast_gen
|
||||||
class LIBSYNTAX_EXPORT TokenAccess {
|
class LIBSYNTAX_EXPORT TokenAccess {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<const ast_gen::SyntaxElement> element_bind;
|
std::shared_ptr<const ast_gen::SyntaxElement> element_bind;
|
||||||
std::shared_ptr<const lib_token::Token> token_store;
|
std::shared_ptr<const lib_token::IToken> token_store;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TokenAccess(std::shared_ptr<const ast_gen::SyntaxElement> elm_inst, std::shared_ptr<const lib_token::Token> token_inst);
|
TokenAccess(std::shared_ptr<const ast_gen::SyntaxElement> elm_inst, std::shared_ptr<const lib_token::IToken> token_inst);
|
||||||
virtual std::shared_ptr<const ast_gen::SyntaxElement> bind() const;
|
virtual std::shared_ptr<const ast_gen::SyntaxElement> bind() const;
|
||||||
virtual std::shared_ptr<const lib_token::Token> token() const;
|
virtual std::shared_ptr<const lib_token::IToken> token() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,7 +114,7 @@ namespace ast_gen
|
||||||
GlobalElement(const QString& name);
|
GlobalElement(const QString& name);
|
||||||
|
|
||||||
virtual void clearCache();
|
virtual void clearCache();
|
||||||
virtual void appendToCache(std::shared_ptr<const ast_gen::SyntaxElement> named_node);
|
virtual std::shared_ptr<const ast_gen::SyntaxElement> appendToCache(std::shared_ptr<const ast_gen::SyntaxElement> named_node);
|
||||||
/**
|
/**
|
||||||
* @brief 通过节点签名获取定义节点
|
* @brief 通过节点签名获取定义节点
|
||||||
* @param signature 完全签名
|
* @param signature 完全签名
|
||||||
|
@ -118,7 +122,6 @@ namespace ast_gen
|
||||||
* @throws 没有指定节点抛出异常
|
* @throws 没有指定节点抛出异常
|
||||||
*/
|
*/
|
||||||
virtual std::shared_ptr<const ast_gen::SyntaxElement> getNamedNodeBy(int type, const QString& signature) const;
|
virtual std::shared_ptr<const ast_gen::SyntaxElement> getNamedNodeBy(int type, const QString& signature) const;
|
||||||
|
|
||||||
virtual void addChild(std::shared_ptr<ast_gen::SyntaxElement> citem);
|
virtual void addChild(std::shared_ptr<ast_gen::SyntaxElement> citem);
|
||||||
|
|
||||||
// ParseElement interface
|
// ParseElement interface
|
||||||
|
|
|
@ -2,25 +2,26 @@
|
||||||
|
|
||||||
|
|
||||||
using namespace example_novel;
|
using namespace example_novel;
|
||||||
|
using namespace lib_syntax;
|
||||||
|
|
||||||
TextSection::TextSection(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
|
TextSection::TextSection(std::shared_ptr<const ExpressionRule> rule_bind)
|
||||||
: AbstractImpl(rule_bind) {}
|
: AbstractImpl(rule_bind) {}
|
||||||
|
|
||||||
QString example_novel::TextSection::content() const
|
QString TextSection::content() const
|
||||||
{
|
{
|
||||||
return context_store;
|
return context_store;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextSection::typeMark() const { return (int)NovelNode::TextSection; }
|
int TextSection::typeMark() const { return (int)NovelNode::TextSection; }
|
||||||
|
|
||||||
bool example_novel::TextSection::isAnonymous() const
|
bool TextSection::isAnonymous() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TextSection::signature() const { return u8"::section"; }
|
QString TextSection::signature() const { return u8"::section"; }
|
||||||
|
|
||||||
void example_novel::TextSection::cacheLoad()
|
void TextSection::cacheLoad()
|
||||||
{
|
{
|
||||||
QString text;
|
QString text;
|
||||||
for (auto& t : selfTokens()) {
|
for (auto& t : selfTokens()) {
|
||||||
|
@ -29,14 +30,14 @@ void example_novel::TextSection::cacheLoad()
|
||||||
context_store = text;
|
context_store = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
FragmentRefers::FragmentRefers(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
|
FragmentRefers::FragmentRefers(std::shared_ptr<const ExpressionRule> rule_bind)
|
||||||
: AbstractImpl(rule_bind) {}
|
: AbstractImpl(rule_bind) {}
|
||||||
|
|
||||||
QString FragmentRefers::storyRefer() const { return story_refs; }
|
QString FragmentRefers::storyRefer() const { return story_refs; }
|
||||||
|
|
||||||
QString FragmentRefers::fragmentRefer() const { return fragment_ref; }
|
QString FragmentRefers::fragmentRefer() const { return fragment_ref; }
|
||||||
|
|
||||||
void example_novel::FragmentRefers::cacheLoad()
|
void FragmentRefers::cacheLoad()
|
||||||
{
|
{
|
||||||
this->story_refs = selfTokens()[5]->token()->content();
|
this->story_refs = selfTokens()[5]->token()->content();
|
||||||
this->fragment_ref = selfTokens()[3]->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; }
|
int FragmentRefers::typeMark() const { return (int)NovelNode::FragmentRefer; }
|
||||||
|
|
||||||
bool example_novel::FragmentRefers::isAnonymous() const
|
bool FragmentRefers::isAnonymous() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -58,18 +59,18 @@ QString FragmentRefers::signature() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FragmentDefine::FragmentDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
|
FragmentDefine::FragmentDefine(std::shared_ptr<const ExpressionRule> rule_bind)
|
||||||
: AbstractImpl(rule_bind) {}
|
: AbstractImpl(rule_bind) {}
|
||||||
|
|
||||||
QString FragmentDefine::name() const { return name_store; }
|
QString FragmentDefine::name() const { return name_store; }
|
||||||
|
|
||||||
void example_novel::FragmentDefine::cacheLoad()
|
void FragmentDefine::cacheLoad()
|
||||||
{
|
{
|
||||||
name_store = selfTokens()[2]->token()->content();
|
name_store = selfTokens()[2]->token()->content();
|
||||||
}
|
}
|
||||||
int FragmentDefine::typeMark() const { return (int)NovelNode::FragmentDefine; }
|
int FragmentDefine::typeMark() const { return (int)NovelNode::FragmentDefine; }
|
||||||
|
|
||||||
bool example_novel::FragmentDefine::isAnonymous() const
|
bool FragmentDefine::isAnonymous() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -77,14 +78,18 @@ bool example_novel::FragmentDefine::isAnonymous() const
|
||||||
QString FragmentDefine::signature() const { return parent()->signature() + u8"&" + name(); }
|
QString FragmentDefine::signature() const { return parent()->signature() + u8"&" + name(); }
|
||||||
|
|
||||||
|
|
||||||
StoryDefine::StoryDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
|
StoryDefine::StoryDefine(std::shared_ptr<const ExpressionRule> rule_bind)
|
||||||
: AbstractImpl(rule_bind) {}
|
: AbstractImpl(rule_bind), sort_index(0) {}
|
||||||
|
|
||||||
QString StoryDefine::name() const { return name_store; }
|
QString StoryDefine::name() const { return name_store; }
|
||||||
|
|
||||||
|
void example_novel::StoryDefine::setSort(int value){
|
||||||
|
sort_index = value;
|
||||||
|
}
|
||||||
|
|
||||||
int StoryDefine::sort() const { return sort_index; }
|
int StoryDefine::sort() const { return sort_index; }
|
||||||
|
|
||||||
void example_novel::StoryDefine::cacheLoad()
|
void StoryDefine::cacheLoad()
|
||||||
{
|
{
|
||||||
name_store = selfTokens()[3]->token()->content();
|
name_store = selfTokens()[3]->token()->content();
|
||||||
sort_index = selfTokens()[2]->token()->content().toInt();
|
sort_index = selfTokens()[2]->token()->content().toInt();
|
||||||
|
@ -92,7 +97,7 @@ void example_novel::StoryDefine::cacheLoad()
|
||||||
|
|
||||||
int StoryDefine::typeMark() const { return (int)NovelNode::StoryDefine; }
|
int StoryDefine::typeMark() const { return (int)NovelNode::StoryDefine; }
|
||||||
|
|
||||||
bool example_novel::StoryDefine::isAnonymous() const
|
bool StoryDefine::isAnonymous() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -100,23 +105,23 @@ bool example_novel::StoryDefine::isAnonymous() const
|
||||||
QString StoryDefine::signature() const { return name(); }
|
QString StoryDefine::signature() const { return name(); }
|
||||||
|
|
||||||
#include "syntax_novel.h"
|
#include "syntax_novel.h"
|
||||||
Document::Document(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
|
Document::Document(std::shared_ptr<const ExpressionRule> rule_bind)
|
||||||
: AbstractImpl(rule_bind) {}
|
: AbstractImpl(rule_bind) {}
|
||||||
|
|
||||||
int Document::typeMark() const { return (int)NovelNode::Document; }
|
int Document::typeMark() const { return (int)NovelNode::Document; }
|
||||||
|
|
||||||
bool example_novel::Document::isAnonymous() const
|
bool Document::isAnonymous() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Document::signature() const { return QString(u8"::document<%1>").arg(path()); }
|
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<const lib_syntax::ExpressionRule> rule_bind)
|
AbstractImpl::AbstractImpl(std::shared_ptr<const ExpressionRule> rule_bind)
|
||||||
: ExpressionElement(rule_bind) { parent_store.reset(); }
|
: ExpressionElement(rule_bind) { parent_store.reset(); }
|
||||||
|
|
||||||
QList<std::shared_ptr<const ast_gen::TokenAccess> > AbstractImpl::selfTokens() const {
|
QList<std::shared_ptr<const ast_gen::TokenAccess> > AbstractImpl::selfTokens() const {
|
||||||
|
@ -129,61 +134,91 @@ QList<std::shared_ptr<const ast_gen::TokenAccess> > AbstractImpl::selfTokens() c
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const ast_gen::SyntaxElement> example_novel::AbstractImpl::parent() const
|
std::shared_ptr<const ast_gen::SyntaxElement> AbstractImpl::parent() const
|
||||||
{
|
{
|
||||||
return this->parent_store.lock();
|
return this->parent_store.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void example_novel::AbstractImpl::setParent(std::shared_ptr<const ast_gen::SyntaxElement> inst)
|
void AbstractImpl::setParent(std::shared_ptr<const ast_gen::SyntaxElement> inst)
|
||||||
{
|
{
|
||||||
this->parent_store = inst;
|
this->parent_store = inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ͨ¹ý SyntaxElement ¼Ì³Ð
|
// ͨ¹ý SyntaxElement ¼Ì³Ð
|
||||||
std::shared_ptr<const ast_basic::Expression> example_novel::AbstractImpl::bindExpression() const {
|
std::shared_ptr<const ast_basic::Expression> AbstractImpl::bindExpression() const {
|
||||||
return shared_from_this();
|
return shared_from_this();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString example_novel::AbstractImpl::path() const
|
QString AbstractImpl::path() const
|
||||||
{
|
{
|
||||||
return ast_basic::ExpressionElement::filePath();
|
return ast_basic::ExpressionElement::filePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
VolumeDefine::VolumeDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
|
VolumeDefine::VolumeDefine(std::shared_ptr<const ExpressionRule> rule_bind)
|
||||||
: AbstractImpl(rule_bind) {}
|
: AbstractImpl(rule_bind) {}
|
||||||
|
|
||||||
QString VolumeDefine::name() const { return name_store; }
|
QString VolumeDefine::name() const { return name_store; }
|
||||||
|
|
||||||
void example_novel::VolumeDefine::cacheLoad()
|
void VolumeDefine::cacheLoad()
|
||||||
{
|
{
|
||||||
name_store = selfTokens()[2]->token()->content();
|
name_store = selfTokens()[2]->token()->content();
|
||||||
}
|
}
|
||||||
|
|
||||||
int VolumeDefine::typeMark() const { return (int)NovelNode::VolumeDefine; }
|
int VolumeDefine::typeMark() const { return (int)NovelNode::VolumeDefine; }
|
||||||
|
|
||||||
bool example_novel::VolumeDefine::isAnonymous() const
|
bool VolumeDefine::isAnonymous() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VolumeDefine::signature() const { return name(); }
|
QString VolumeDefine::signature() const { return name(); }
|
||||||
|
|
||||||
ArticleDefine::ArticleDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind)
|
ArticleDefine::ArticleDefine(std::shared_ptr<const ExpressionRule> rule_bind)
|
||||||
: AbstractImpl(rule_bind) {}
|
: AbstractImpl(rule_bind) {}
|
||||||
|
|
||||||
QString ArticleDefine::name() const { return name_store; }
|
QString ArticleDefine::name() const { return name_store; }
|
||||||
|
|
||||||
void example_novel::ArticleDefine::cacheLoad()
|
void ArticleDefine::cacheLoad()
|
||||||
{
|
{
|
||||||
name_store = selfTokens()[2]->token()->content();
|
name_store = selfTokens()[2]->token()->content();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ArticleDefine::typeMark() const { return (int)NovelNode::ArticleDefine; }
|
int ArticleDefine::typeMark() const { return (int)NovelNode::ArticleDefine; }
|
||||||
|
|
||||||
bool example_novel::ArticleDefine::isAnonymous() const
|
bool ArticleDefine::isAnonymous() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ArticleDefine::signature() const { return parent()->signature() + u8"&" + name(); }
|
QString ArticleDefine::signature() const { return parent()->signature() + u8"&" + name(); }
|
||||||
|
|
||||||
|
RankDeclare::RankDeclare(std::shared_ptr<const ExpressionRule> 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();
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
namespace example_novel
|
namespace example_novel
|
||||||
{
|
{
|
||||||
enum class NovelNode {
|
enum class NovelNode {
|
||||||
|
GlobalElement = 0,
|
||||||
TextSection = 1,
|
TextSection = 1,
|
||||||
FragmentRefer = 2,
|
FragmentRefer = 2,
|
||||||
FragmentDefine = 3,
|
FragmentDefine = 3,
|
||||||
|
@ -12,10 +13,10 @@ namespace example_novel
|
||||||
Document = 5,
|
Document = 5,
|
||||||
ArticleDefine = 6,
|
ArticleDefine = 6,
|
||||||
VolumeDefine = 7,
|
VolumeDefine = 7,
|
||||||
|
RankDeclaration = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
class LIBSYNTAX_EXPORT AbstractImpl :
|
class LIBSYNTAX_EXPORT AbstractImpl : public ast_basic::ExpressionElement, public ast_gen::SyntaxElement {
|
||||||
public ast_basic::ExpressionElement, public ast_gen::SyntaxElement {
|
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<const SyntaxElement> parent_store;
|
std::weak_ptr<const SyntaxElement> parent_store;
|
||||||
|
|
||||||
|
@ -123,6 +124,7 @@ namespace example_novel
|
||||||
StoryDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind);
|
StoryDefine(std::shared_ptr<const lib_syntax::ExpressionRule> rule_bind);
|
||||||
|
|
||||||
QString name() const;
|
QString name() const;
|
||||||
|
void setSort(int value);
|
||||||
int sort() const;
|
int sort() const;
|
||||||
|
|
||||||
// SyntaxElement interface
|
// SyntaxElement interface
|
||||||
|
@ -148,4 +150,19 @@ namespace example_novel
|
||||||
virtual QString signature() const override;
|
virtual QString signature() const override;
|
||||||
virtual void cacheLoad() override;
|
virtual void cacheLoad() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LIBSYNTAX_EXPORT RankDeclare : public AbstractImpl {
|
||||||
|
private:
|
||||||
|
int page_rank = 0;
|
||||||
|
public:
|
||||||
|
RankDeclare(std::shared_ptr<const lib_syntax::ExpressionRule> rule);
|
||||||
|
|
||||||
|
int rankNumber() const;
|
||||||
|
|
||||||
|
// ͨ¹ý AbstractImpl ¼Ì³Ð
|
||||||
|
int typeMark() const override;
|
||||||
|
bool isAnonymous() const override;
|
||||||
|
QString signature() const override;
|
||||||
|
void cacheLoad() override;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,30 +6,28 @@ using namespace std;
|
||||||
using namespace lib_token;
|
using namespace lib_token;
|
||||||
using namespace ast_basic;
|
using namespace ast_basic;
|
||||||
|
|
||||||
TokenMatch::TokenMatch(shared_ptr<const TokenDefine> define) : define_peer(define) {}
|
TokenMatch::TokenMatch(shared_ptr<const ITokenDefine> define) : define_peer(define) {}
|
||||||
|
|
||||||
QList<std::shared_ptr<const BaseRule>> TokenMatch::children() const { return QList<std::shared_ptr<const BaseRule>>(); }
|
QList<std::shared_ptr<const BaseRule>> TokenMatch::children() const { return QList<std::shared_ptr<const BaseRule>>(); }
|
||||||
|
|
||||||
std::tuple<BaseRule::MatchResult, uint, std::shared_ptr<const Token>> TokenMatch::match(std::shared_ptr<const Token> remains_head) const {
|
std::tuple<std::shared_ptr<const Expression>, std::shared_ptr<const IWordBase>> TokenMatch::parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const IWordBase> 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<const ast_basic::Expression>, std::shared_ptr<const lib_token::Token>>
|
|
||||||
std::tuple<std::shared_ptr<const Expression>, std::shared_ptr<const Token>> TokenMatch::parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const Token> head) const {
|
|
||||||
if (!head)
|
if (!head)
|
||||||
throw std::make_shared<InputTerminal>();
|
throw new InputTerminal(rt_inst->currentFile());
|
||||||
|
|
||||||
if (head->define()->typeMark() == define_peer->typeMark()) {
|
auto match_result = define_peer->analysis(head);
|
||||||
rt_inst->currentInst()->addToken(head);
|
if (std::get<0>(match_result)) {
|
||||||
return std::make_tuple(nullptr, head->nextToken());
|
rt_inst->currentInst()->addToken(std::get<0>(match_result));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new MismatchException(head);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::make_shared<MismatchException>(head);
|
if (std::get<1>(match_result)) {
|
||||||
|
return std::make_tuple(nullptr, std::make_shared<WordImpl>(std::get<1>(match_result), head->nextWord()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return std::make_tuple(nullptr, head->nextWord());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TokenMatch::token_present() const {
|
QString TokenMatch::token_present() const {
|
||||||
|
@ -40,41 +38,7 @@ Rept::Rept(std::shared_ptr<const BaseRule> rule, int min, int max) : rule_peer(r
|
||||||
|
|
||||||
QList<std::shared_ptr<const BaseRule>> Rept::children() const { return QList<std::shared_ptr<const BaseRule>>() << rule_peer; }
|
QList<std::shared_ptr<const BaseRule>> Rept::children() const { return QList<std::shared_ptr<const BaseRule>>() << rule_peer; }
|
||||||
|
|
||||||
std::tuple<BaseRule::MatchResult, uint, std::shared_ptr<const Token>> Rept::match(std::shared_ptr<const Token> list_head) const {
|
std::tuple<std::shared_ptr<const Expression>, std::shared_ptr<const IWordBase>> Rept::parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const IWordBase> 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<const Expression>, std::shared_ptr<const Token>> Rept::parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const Token> head) const {
|
|
||||||
auto temp_head = head;
|
auto temp_head = head;
|
||||||
|
|
||||||
// min-match
|
// min-match
|
||||||
|
@ -95,10 +59,8 @@ std::tuple<std::shared_ptr<const Expression>, std::shared_ptr<const Token>> Rept
|
||||||
|
|
||||||
temp_head = std::get<1>(result_gen);
|
temp_head = std::get<1>(result_gen);
|
||||||
}
|
}
|
||||||
catch (std::shared_ptr<MismatchException> ex) {
|
catch (SyntaxException* ex) {
|
||||||
return std::make_tuple(nullptr, temp_head);
|
delete ex;
|
||||||
}
|
|
||||||
catch (std::shared_ptr<InputTerminal> ex) {
|
|
||||||
return std::make_tuple(nullptr, temp_head);
|
return std::make_tuple(nullptr, temp_head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,30 +77,7 @@ Seqs::Seqs(const QList<std::shared_ptr<const BaseRule>> mbrs) : mbrs_store(mbrs)
|
||||||
|
|
||||||
QList<std::shared_ptr<const BaseRule>> Seqs::children() const { return mbrs_store; }
|
QList<std::shared_ptr<const BaseRule>> Seqs::children() const { return mbrs_store; }
|
||||||
|
|
||||||
std::tuple<BaseRule::MatchResult, uint, std::shared_ptr<const Token>> Seqs::match(std::shared_ptr<const Token> list_head) const {
|
std::tuple<std::shared_ptr<const Expression>, std::shared_ptr<const IWordBase>> Seqs::parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const IWordBase> 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<const Expression>, std::shared_ptr<const Token>> Seqs::parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const Token> head) const {
|
|
||||||
auto temp_head = head;
|
auto temp_head = head;
|
||||||
|
|
||||||
for (auto& r : mbrs_store) {
|
for (auto& r : mbrs_store) {
|
||||||
|
@ -160,53 +99,30 @@ QString Seqs::token_present() const
|
||||||
return QString(u8"(%1)").arg(content);
|
return QString(u8"(%1)").arg(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<BaseRule::MatchResult, uint, std::shared_ptr<const BaseRule>, std::shared_ptr<const Token>>
|
//std::tuple<BaseRule::MatchResult, uint, std::shared_ptr<const BaseRule>, std::shared_ptr<const Token>>
|
||||||
Any::rule_select(std::shared_ptr<const Token> head) const {
|
|
||||||
QString token_seqs = this->token_present();
|
|
||||||
std::tuple<MatchResult, uint, std::shared_ptr<const BaseRule>, std::shared_ptr<const Token>> 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
Any::Any(const QList<std::shared_ptr<const BaseRule>> mbrs) : mbrs_store(mbrs) {}
|
Any::Any(const QList<std::shared_ptr<const BaseRule>> mbrs) : mbrs_store(mbrs) {}
|
||||||
|
|
||||||
QList<std::shared_ptr<const BaseRule>> Any::children() const { return mbrs_store; }
|
QList<std::shared_ptr<const BaseRule>> Any::children() const { return mbrs_store; }
|
||||||
|
|
||||||
std::tuple<BaseRule::MatchResult, uint, std::shared_ptr<const Token>> Any::match(std::shared_ptr<const Token> list_head) const {
|
class words_span {
|
||||||
auto item = rule_select(list_head);
|
public:
|
||||||
return std::make_tuple(std::get<0>(item), std::get<1>(item), std::get<3>(item));
|
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<const Expression>, std::shared_ptr<const Token>> Any::parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const Token> head) const {
|
std::tuple<std::shared_ptr<const Expression>, std::shared_ptr<const IWordBase>> Any::parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const IWordBase> head) const {
|
||||||
std::function<int(std::shared_ptr<const Token>, std::shared_ptr<const Token>)> measure_span =
|
std::function<words_span(std::shared_ptr<const IWordBase>, std::shared_ptr<const IWordBase>)> measure_span =
|
||||||
[&](std::shared_ptr<const Token> anchor, std::shared_ptr<const Token> head)->int {
|
[&](std::shared_ptr<const IWordBase> anchor, std::shared_ptr<const IWordBase> head)->words_span {
|
||||||
if (anchor == head)
|
return words_span(anchor->row() - head->row(), anchor->column() - head->column());
|
||||||
return 1;
|
|
||||||
return measure_span(anchor, head->nextToken()) + 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
std::tuple<std::shared_ptr<const BaseRule>, int> temp_result = std::make_tuple(mbrs_store.first(), 0);
|
std::tuple<std::shared_ptr<const BaseRule>, words_span> temp_result = std::make_tuple(mbrs_store.first(), words_span(0,0));
|
||||||
for (auto& fork : mbrs_store) {
|
for (auto& fork : mbrs_store) {
|
||||||
try {
|
try {
|
||||||
auto gen = fork->parse(rt_inst, head);
|
auto gen = fork->parse(rt_inst, head);
|
||||||
|
@ -217,11 +133,13 @@ std::tuple<std::shared_ptr<const Expression>, std::shared_ptr<const Token>> Any:
|
||||||
return std::make_tuple(nullptr, std::get<1>(gen));
|
return std::make_tuple(nullptr, std::get<1>(gen));
|
||||||
}
|
}
|
||||||
// Óï·¨´íÎóµÄ»á½øÐбȽÏ
|
// Óï·¨´íÎóµÄ»á½øÐбȽÏ
|
||||||
catch (std::shared_ptr<MismatchException> ex) {
|
catch (MismatchException* ex) {
|
||||||
auto current_span = measure_span(ex->targetToken(), head);
|
auto current_span = measure_span(ex->targetWord(), head);
|
||||||
|
|
||||||
if (current_span > std::get<1>(temp_result))
|
if (current_span > std::get<1>(temp_result))
|
||||||
temp_result = std::make_tuple(fork, current_span);
|
temp_result = std::make_tuple(fork, current_span);
|
||||||
|
|
||||||
|
delete ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,11 +181,7 @@ QList<std::shared_ptr<const BaseRule>> ExpressionRule::children() const {
|
||||||
return QList<std::shared_ptr<const BaseRule>>() << this->child_store;
|
return QList<std::shared_ptr<const BaseRule>>() << this->child_store;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<BaseRule::MatchResult, uint, std::shared_ptr<const Token>> ExpressionRule::match(std::shared_ptr<const Token> list_head) const {
|
std::tuple<std::shared_ptr<const Expression>, std::shared_ptr<const IWordBase>> ExpressionRule::parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const IWordBase> head) const {
|
||||||
return child_store->match(list_head);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::tuple<std::shared_ptr<const Expression>, std::shared_ptr<const Token>> ExpressionRule::parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const Token> head) const {
|
|
||||||
std::shared_ptr<Expression> elm_ast = this->newEmptyInstance();
|
std::shared_ptr<Expression> elm_ast = this->newEmptyInstance();
|
||||||
|
|
||||||
rt_inst->pushExpressionRule(this->shared_from_this());
|
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());
|
return QString(u8"(%1)").arg(child_store->token_present());
|
||||||
}
|
}
|
||||||
|
|
||||||
MismatchException::MismatchException(std::shared_ptr<const lib_token::Token> inst) :SyntaxException(
|
MismatchException::MismatchException(std::shared_ptr<const lib_token::IWordBase> inst) :SyntaxException(
|
||||||
QString(u8"Syntax[0x00001]语法匹配错误,不能识别token:%1<%2,%3>").arg(inst->content()).arg(inst->row()).arg(inst->column())), target(inst) {}
|
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_ptr<const Token>MismatchException::targetToken() const {
|
std::shared_ptr<const IWordBase>MismatchException::targetWord() const {
|
||||||
return this->target;
|
return this->target;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputTerminal::InputTerminal() :SyntaxException(u8"Syntax[0x0000]token流提前终止") {}
|
InputTerminal::InputTerminal(const QString& file_path)
|
||||||
|
:SyntaxException(QString(u8"Syntax[0x0000]token流(%1)提前终止").arg(file_path)) {}
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace lib_syntax {
|
||||||
/**
|
/**
|
||||||
* @brief 语法异常
|
* @brief 语法异常
|
||||||
*/
|
*/
|
||||||
class SyntaxException {
|
class LIBSYNTAX_EXPORT SyntaxException {
|
||||||
private:
|
private:
|
||||||
QString msg_store;
|
QString msg_store;
|
||||||
|
|
||||||
|
@ -35,6 +35,9 @@ namespace lib_syntax {
|
||||||
public:
|
public:
|
||||||
virtual ~ParseContext() = default;
|
virtual ~ParseContext() = default;
|
||||||
|
|
||||||
|
virtual void setCurrentFile(const QString &path) = 0;
|
||||||
|
virtual QString currentFile() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief 当前表达式元素.
|
* \brief 当前表达式元素.
|
||||||
*
|
*
|
||||||
|
@ -70,20 +73,14 @@ namespace lib_syntax {
|
||||||
Fail // 从第一个词起完全不匹配
|
Fail // 从第一个词起完全不匹配
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief token流匹配
|
|
||||||
* @return 首部对齐,匹配token集合<匹配结果,匹配长度,剩余列表头指针>
|
|
||||||
*/
|
|
||||||
virtual std::tuple<MatchResult, uint, std::shared_ptr<const lib_token::Token>> match(std::shared_ptr<const lib_token::Token> remains_head) const = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 解析
|
* @brief 解析
|
||||||
* @param rt_inst 解析上下文
|
* @param rt_inst 解析上下文
|
||||||
* @param head 列表头
|
* @param head 列表头
|
||||||
* @return 返回结果<匹配完成新列表头,匹配长度>
|
* @return 返回结果<匹配完成新列表头,匹配长度>
|
||||||
*/
|
*/
|
||||||
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::Token>>
|
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::IWordBase>>
|
||||||
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::Token> head) const = 0;
|
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回匹配语法规则的词法序列表达
|
* 返回匹配语法规则的词法序列表达
|
||||||
|
@ -99,17 +96,16 @@ namespace lib_syntax {
|
||||||
*/
|
*/
|
||||||
class LIBSYNTAX_EXPORT TokenMatch : public BaseRule, public std::enable_shared_from_this<TokenMatch> {
|
class LIBSYNTAX_EXPORT TokenMatch : public BaseRule, public std::enable_shared_from_this<TokenMatch> {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<const lib_token::TokenDefine> define_peer;
|
std::shared_ptr<const lib_token::ITokenDefine> define_peer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TokenMatch(std::shared_ptr<const lib_token::TokenDefine> define);
|
TokenMatch(std::shared_ptr<const lib_token::ITokenDefine> define);
|
||||||
|
|
||||||
// BaseRule interface
|
// BaseRule interface
|
||||||
public:
|
public:
|
||||||
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
|
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
|
||||||
virtual std::tuple<MatchResult, uint, std::shared_ptr<const lib_token::Token>> match(std::shared_ptr<const lib_token::Token> head) const override;
|
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::IWordBase>>
|
||||||
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::Token>>
|
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head) const override;
|
||||||
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::Token> head) const override;
|
|
||||||
virtual QString token_present() const override;
|
virtual QString token_present() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -120,7 +116,7 @@ namespace lib_syntax {
|
||||||
private:
|
private:
|
||||||
QList<std::shared_ptr<const BaseRule>> mbrs_store;
|
QList<std::shared_ptr<const BaseRule>> mbrs_store;
|
||||||
|
|
||||||
std::tuple<MatchResult, uint, std::shared_ptr<const BaseRule>, std::shared_ptr<const lib_token::Token>> rule_select(std::shared_ptr<const lib_token::Token> head) const;
|
std::tuple<MatchResult, uint, std::shared_ptr<const BaseRule>, std::shared_ptr<const lib_token::IWordBase>> rule_select(std::shared_ptr<const lib_token::IWordBase> head) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Any(const QList<std::shared_ptr<const BaseRule>> mbrs);
|
Any(const QList<std::shared_ptr<const BaseRule>> mbrs);
|
||||||
|
@ -128,9 +124,8 @@ namespace lib_syntax {
|
||||||
// BaseRule interface
|
// BaseRule interface
|
||||||
public:
|
public:
|
||||||
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
|
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
|
||||||
virtual std::tuple<MatchResult, uint, std::shared_ptr<const lib_token::Token>> match(std::shared_ptr<const lib_token::Token> list_head) const override;
|
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::IWordBase>>
|
||||||
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::Token>>
|
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head) const override;
|
||||||
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::Token> head) const override;
|
|
||||||
virtual QString token_present() const override;
|
virtual QString token_present() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -147,9 +142,8 @@ namespace lib_syntax {
|
||||||
// BaseRule interface
|
// BaseRule interface
|
||||||
public:
|
public:
|
||||||
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
|
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
|
||||||
virtual std::tuple<MatchResult, uint, std::shared_ptr<const lib_token::Token>> match(std::shared_ptr<const lib_token::Token> list_head) const override;
|
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::IWordBase>>
|
||||||
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::Token>>
|
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head) const override;
|
||||||
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::Token> head) const override;
|
|
||||||
virtual QString token_present() const override;
|
virtual QString token_present() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,9 +161,8 @@ namespace lib_syntax {
|
||||||
// BaseRule interface
|
// BaseRule interface
|
||||||
public:
|
public:
|
||||||
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
|
virtual QList<std::shared_ptr<const BaseRule>> children() const override;
|
||||||
virtual std::tuple<MatchResult, uint, std::shared_ptr<const lib_token::Token>> match(std::shared_ptr<const lib_token::Token> list_head) const override;
|
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::IWordBase>>
|
||||||
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::Token>>
|
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head) const override;
|
||||||
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::Token> head) const override;
|
|
||||||
virtual QString token_present() const override;
|
virtual QString token_present() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,7 +172,7 @@ namespace lib_syntax {
|
||||||
*/
|
*/
|
||||||
class LIBSYNTAX_EXPORT ExpressionRule : public lib_syntax::BaseRule, public std::enable_shared_from_this<ExpressionRule> {
|
class LIBSYNTAX_EXPORT ExpressionRule : public lib_syntax::BaseRule, public std::enable_shared_from_this<ExpressionRule> {
|
||||||
public:
|
public:
|
||||||
typedef QList<std::shared_ptr<const lib_token::Token>> TokenSeqs;
|
typedef QList<std::shared_ptr<const lib_token::IToken>> TokenSeqs;
|
||||||
ExpressionRule(const QString& rule_name, int expr_mark);
|
ExpressionRule(const QString& rule_name, int expr_mark);
|
||||||
|
|
||||||
virtual std::shared_ptr<const ExpressionRule> reloadRule(std::function<TokenSeqs(const TokenSeqs&)> filter, std::shared_ptr<const BaseRule> rule);
|
virtual std::shared_ptr<const ExpressionRule> reloadRule(std::function<TokenSeqs(const TokenSeqs&)> filter, std::shared_ptr<const BaseRule> rule);
|
||||||
|
@ -192,9 +185,8 @@ namespace lib_syntax {
|
||||||
// BaseRule interface
|
// BaseRule interface
|
||||||
public:
|
public:
|
||||||
virtual QList<std::shared_ptr<const lib_syntax::BaseRule>> children() const override;
|
virtual QList<std::shared_ptr<const lib_syntax::BaseRule>> children() const override;
|
||||||
virtual std::tuple<MatchResult, uint, std::shared_ptr<const lib_token::Token>> match(std::shared_ptr<const lib_token::Token> remains_head) const override;
|
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::IWordBase>>
|
||||||
virtual std::tuple<std::shared_ptr<const ast_basic::Expression>, std::shared_ptr<const lib_token::Token>>
|
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head) const override;
|
||||||
parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const lib_token::Token> head) const override;
|
|
||||||
virtual QString token_present() const override;
|
virtual QString token_present() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -226,17 +218,17 @@ namespace lib_syntax {
|
||||||
|
|
||||||
class MismatchException : public SyntaxException {
|
class MismatchException : public SyntaxException {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<const lib_token::Token> target;
|
std::shared_ptr<const lib_token::IWordBase> target;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MismatchException(std::shared_ptr<const lib_token::Token> inst);
|
MismatchException(std::shared_ptr<const lib_token::IWordBase> inst);
|
||||||
virtual ~MismatchException() = default;
|
virtual ~MismatchException() = default;
|
||||||
|
|
||||||
virtual std::shared_ptr<const lib_token::Token> targetToken() const;
|
virtual std::shared_ptr<const lib_token::IWordBase> targetWord() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InputTerminal : public SyntaxException {
|
class InputTerminal : public SyntaxException {
|
||||||
public:
|
public:
|
||||||
InputTerminal();
|
InputTerminal(const QString &file_path);
|
||||||
};
|
};
|
||||||
} // namespace lib_syntax
|
} // namespace lib_syntax
|
|
@ -11,7 +11,9 @@ using namespace ast_basic;
|
||||||
auto leftb = std::make_shared<LeftBracket>(); // {
|
auto leftb = std::make_shared<LeftBracket>(); // {
|
||||||
auto rightb = std::make_shared<RightBracket>(); // }
|
auto rightb = std::make_shared<RightBracket>(); // }
|
||||||
auto refers = std::make_shared<ReferMark>(); // @
|
auto refers = std::make_shared<ReferMark>(); // @
|
||||||
|
auto declare = std::make_shared<DeclareSymbo>(); // #
|
||||||
|
|
||||||
|
auto rank_key = std::make_shared<Keywords>(u8"排序", u8"rank-symbol", 0xAEu); // 排序
|
||||||
auto story_key = std::make_shared<Keywords>(u8"¹ÊÊÂ", u8"story-mark", 0xAAu); // ¹ÊÊÂ
|
auto story_key = std::make_shared<Keywords>(u8"¹ÊÊÂ", u8"story-mark", 0xAAu); // ¹ÊÊÂ
|
||||||
auto numbers = std::make_shared<Numbers>(); // [0-9]+
|
auto numbers = std::make_shared<Numbers>(); // [0-9]+
|
||||||
auto frag_key = std::make_shared<Keywords>(u8"Çé½Ú", u8"fragment-mark", 0xABu); // Çé½Ú
|
auto frag_key = std::make_shared<Keywords>(u8"Çé½Ú", u8"fragment-mark", 0xABu); // Çé½Ú
|
||||||
|
@ -96,21 +98,25 @@ auto volume_decl = ElementRule<VolumeDefine>(u8"volume_define", (int)NovelExprs:
|
||||||
LinesMerge(MR(rightb))
|
LinesMerge(MR(rightb))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
auto rank_define = ElementRule<RankDeclare>(u8"rank_define", (int)NovelNode::RankDeclaration).reloadRule(remove_nl, std::make_shared<const Seqs>(
|
||||||
|
Rules{ MR(declare), MR(rank_key), MR(numbers), OptMulT(newl)}
|
||||||
|
));
|
||||||
|
|
||||||
auto document_define = ElementRule<Document>(u8"decls-doc", (int)NovelExprs::DOC_DEFINES).reloadRule(remove_nl, std::make_shared<const Seqs>(
|
auto document_define = ElementRule<Document>(u8"decls-doc", (int)NovelExprs::DOC_DEFINES).reloadRule(remove_nl, std::make_shared<const Seqs>(
|
||||||
Rules{
|
Rules{
|
||||||
OptMulT(newl),
|
std::make_shared<const Rept>(rank_define, 0, 1),
|
||||||
MultiR(std::make_shared<const Any>(Rules{story_define, volume_decl}))
|
MultiR(std::make_shared<const Any>(Rules{story_define, volume_decl}))
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
std::shared_ptr<const ExpressionRule> NovalSyntax::getParseTree() { return document_define; }
|
std::shared_ptr<const ExpressionRule> NovalSyntax::getParseTree() { return document_define; }
|
||||||
std::shared_ptr<const ast_gen::SyntaxElement> example_novel::NovalSyntax::tidy(std::shared_ptr<ast_gen::SyntaxElement> root, QList<std::shared_ptr<ast_gen::SyntaxElement>> children)
|
std::shared_ptr<const ast_gen::SyntaxElement> NovalSyntax::tidy(std::shared_ptr<ast_gen::SyntaxElement> root, QList<std::shared_ptr<ast_gen::SyntaxElement>> children)
|
||||||
{
|
{
|
||||||
cache_load(root, children);
|
cache_load(root, children);
|
||||||
node_register(root, children);
|
node_register(root, children);
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
void example_novel::NovalSyntax::cache_load(std::shared_ptr<ast_gen::SyntaxElement> root, QList<std::shared_ptr<ast_gen::SyntaxElement>> children)
|
void NovalSyntax::cache_load(std::shared_ptr<ast_gen::SyntaxElement> root, QList<std::shared_ptr<ast_gen::SyntaxElement>> children)
|
||||||
{
|
{
|
||||||
root->cacheLoad();
|
root->cacheLoad();
|
||||||
for (auto& cinst : children) {
|
for (auto& cinst : children) {
|
||||||
|
@ -125,11 +131,15 @@ void example_novel::NovalSyntax::cache_load(std::shared_ptr<ast_gen::SyntaxEleme
|
||||||
cache_load(cinst, child_items);
|
cache_load(cinst, child_items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void example_novel::NovalSyntax::node_register(std::shared_ptr<const ast_gen::SyntaxElement> root, QList<std::shared_ptr<ast_gen::SyntaxElement>> children)
|
void NovalSyntax::node_register(std::shared_ptr<const ast_gen::SyntaxElement> root, QList<std::shared_ptr<ast_gen::SyntaxElement>> children)
|
||||||
{
|
{
|
||||||
for (auto& child : children) {
|
for (auto& child : children) {
|
||||||
if (!child->isAnonymous())
|
if (!child->isAnonymous()) {
|
||||||
ast_gen::GlobalElement::UniquePtr->appendToCache(child);
|
auto check_result = ast_gen::GlobalElement::UniquePtr->appendToCache(child);
|
||||||
|
if(check_result)
|
||||||
|
throw new lib_syntax::SyntaxException(QString(u8"Parse[0x0004]系统中包含同类型重名命名节点:%1<type:%2>(%3,%4)")
|
||||||
|
.arg(child->signature()).arg(child->typeMark()).arg(child->path()).arg(check_result->path()));
|
||||||
|
}
|
||||||
|
|
||||||
QList<std::shared_ptr<ast_gen::SyntaxElement>> next_child_items;
|
QList<std::shared_ptr<ast_gen::SyntaxElement>> next_child_items;
|
||||||
for (auto& it : child->bindExpression()->children()) {
|
for (auto& it : child->bindExpression()->children()) {
|
||||||
|
@ -140,10 +150,3 @@ void example_novel::NovalSyntax::node_register(std::shared_ptr<const ast_gen::Sy
|
||||||
node_register(child, next_child_items);
|
node_register(child, next_child_items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::shared_ptr<const TokenReader> NovalSyntax::getLexReader()
|
|
||||||
{
|
|
||||||
auto inst = std::make_shared<lib_token::TokenReader>(QList<std::shared_ptr<const lib_token::TokenDefine>>()
|
|
||||||
<< leftb << rightb << refers << split_mark << story_key << frag_key << volume_key << article_key << numbers << name_text << vtext << newl);
|
|
||||||
return inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -24,14 +24,6 @@ namespace example_novel {
|
||||||
|
|
||||||
class LIBSYNTAX_EXPORT NovalSyntax {
|
class LIBSYNTAX_EXPORT NovalSyntax {
|
||||||
public:
|
public:
|
||||||
/**
|
|
||||||
* @brief 获取novel词法解析器
|
|
||||||
* @param path 文件路径
|
|
||||||
* @param name 文件名称
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static std::shared_ptr<const lib_token::TokenReader> getLexReader();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 获取novel语法解析树
|
* @brief 获取novel语法解析树
|
||||||
* @return
|
* @return
|
||||||
|
|
Loading…
Reference in New Issue