添加改进措施
This commit is contained in:
parent
26eab5a092
commit
0df0e77df5
|
|
@ -69,15 +69,19 @@ int main(int argc, char* argv[]) {
|
||||||
if (files.size()) {
|
if (files.size()) {
|
||||||
try {
|
try {
|
||||||
auto parser = std::make_shared<NovelParser>();
|
auto parser = std::make_shared<NovelParser>();
|
||||||
auto docs = parser->parse(files);
|
auto result_list = parser->parse(files);
|
||||||
|
|
||||||
auto errors_list = parser->parserContext()->errors();
|
QList<std::shared_ptr<const ast_basic::IExprInst>> docs;
|
||||||
if (errors_list.size()) {
|
bool exit_mark = false;
|
||||||
for (auto& err : errors_list) {
|
for (auto fork : result_list) {
|
||||||
qDebug().noquote() << err;
|
docs << fork.mbrs_list;
|
||||||
|
if(fork.error_messages.size())
|
||||||
|
qDebug().noquote() << fork.error_messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (exit_mark)
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
|
||||||
access_ptr = parser->validsApply(docs);
|
access_ptr = parser->validsApply(docs);
|
||||||
}
|
}
|
||||||
catch (lib_syntax::SyntaxException* e) {
|
catch (lib_syntax::SyntaxException* e) {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
using namespace example_novel;
|
using namespace example_novel;
|
||||||
using namespace lib_parse;
|
using namespace lib_parse;
|
||||||
|
using namespace lib_syntax;
|
||||||
|
|
||||||
NovelParser::NovelParser()
|
NovelParser::NovelParser()
|
||||||
{
|
{
|
||||||
|
|
@ -29,29 +30,29 @@ QString NovelParser::version() const
|
||||||
return "1.0.0";
|
return "1.0.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<lib_syntax::IContext> NovelParser::parserContext() const
|
std::shared_ptr<ast_gen::GlobalElement> NovelParser::parserContext() const
|
||||||
{
|
{
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<std::shared_ptr<const ast_basic::IExprInst>> NovelParser::parse(const QFileInfoList source_list) const {
|
QList<ParseFork> NovelParser::parse(const QFileInfoList source_list) const {
|
||||||
const_cast<NovelParser*>(this)->context = std::make_shared<ast_gen::GlobalElement>(u8"小说");
|
const_cast<NovelParser*>(this)->context = std::make_shared<ast_gen::GlobalElement>(u8"小说");
|
||||||
auto word_reader = std::make_shared<lib_token::WordReader>();
|
auto word_reader = std::make_shared<lib_token::WordReader>();
|
||||||
|
|
||||||
|
QList<ParseFork> parse_result;
|
||||||
auto time_stamp = QTime::currentTime();
|
auto time_stamp = QTime::currentTime();
|
||||||
for (auto& file : source_list) {
|
for (auto& file : source_list) {
|
||||||
context->setCurrentFile(file.canonicalFilePath());
|
|
||||||
auto words = word_reader->wordsFrom(file.canonicalFilePath());
|
auto words = word_reader->wordsFrom(file.canonicalFilePath());
|
||||||
|
|
||||||
lib_syntax::IBasicRule::ErrDeals modify = lib_syntax::IBasicRule::ErrDeals::None;
|
ParseFork start;
|
||||||
this->syntax_defines->parse(context, words, modify);
|
start.next = words;
|
||||||
|
parse_result << this->syntax_defines->parse(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<std::shared_ptr<const ast_basic::IExprInst>> forst_root = context->getDocInsts();
|
|
||||||
auto current_stamp = QTime::currentTime();
|
auto current_stamp = QTime::currentTime();
|
||||||
qDebug().noquote() << QString(u8"%词法解析+语法解析消耗时间:%1 ms。").arg(time_stamp.msecsTo(current_stamp));
|
qDebug().noquote() << QString(u8"%词法解析+语法解析消耗时间:%1 ms。").arg(time_stamp.msecsTo(current_stamp));
|
||||||
|
|
||||||
return forst_root;
|
return parse_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const ast_gen::ElementAccess> NovelParser::validsApply(QList<std::shared_ptr<const ast_basic::IExprInst>> forst_root) const {
|
std::shared_ptr<const ast_gen::ElementAccess> NovelParser::validsApply(QList<std::shared_ptr<const ast_basic::IExprInst>> forst_root) const {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ public:
|
||||||
QList<std::shared_ptr<const example_novel::FragmentGraphHelper>> fragmentsSorted() const;
|
QList<std::shared_ptr<const example_novel::FragmentGraphHelper>> fragmentsSorted() const;
|
||||||
|
|
||||||
virtual QString version() const;
|
virtual QString version() const;
|
||||||
std::shared_ptr<lib_syntax::IContext> parserContext() const;
|
std::shared_ptr<ast_gen::GlobalElement> parserContext() const;
|
||||||
QList<std::shared_ptr<const ast_basic::IExprInst>> parse(const QFileInfoList souurce_list) const;
|
QList<lib_syntax::ParseFork> parse(const QFileInfoList souurce_list) const;
|
||||||
std::shared_ptr<const ast_gen::ElementAccess> validsApply(QList<std::shared_ptr<const ast_basic::IExprInst>> docs_list) const;
|
std::shared_ptr<const ast_gen::ElementAccess> validsApply(QList<std::shared_ptr<const ast_basic::IExprInst>> docs_list) const;
|
||||||
};
|
};
|
||||||
|
|
@ -33,78 +33,3 @@ void ExpressionElement::addChild(std::shared_ptr<const IExprInst> inst) {
|
||||||
QList<std::shared_ptr<const IToken>> ExpressionElement::tokens() const {
|
QList<std::shared_ptr<const IToken>> ExpressionElement::tokens() const {
|
||||||
return this->tokens_bind;
|
return this->tokens_bind;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpressionContext::ExpressionContext() {}
|
|
||||||
|
|
||||||
void ExpressionContext::setCurrentFile(const QString& path) { this->current_file_path = path; }
|
|
||||||
|
|
||||||
QString ExpressionContext::currentFile() const { return this->current_file_path; }
|
|
||||||
|
|
||||||
std::shared_ptr<IExprInst> ExpressionContext::currentExprInst() const
|
|
||||||
{
|
|
||||||
if (expression_stack.size())
|
|
||||||
return expression_stack.last();
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpressionContext::pushExprInst(std::shared_ptr<IExprInst> current_inst)
|
|
||||||
{
|
|
||||||
if (!expression_stack.size() || expression_stack.last() != current_inst)
|
|
||||||
expression_stack.append(current_inst);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<IExprInst> ExpressionContext::popExprInst()
|
|
||||||
{
|
|
||||||
auto lastx = expression_stack.takeLast();
|
|
||||||
return lastx;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<const IBasicRule> ExpressionContext::currentExprRule() const {
|
|
||||||
if (rule_stack.size())
|
|
||||||
return rule_stack.last();
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpressionContext::pushExprRule(std::shared_ptr<const IBasicRule> inst) {
|
|
||||||
if (!rule_stack.size() || rule_stack.last() != inst)
|
|
||||||
rule_stack.append(inst);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<const IBasicRule> ExpressionContext::popExprRule()
|
|
||||||
{
|
|
||||||
return rule_stack.takeLast();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpressionContext::appendParseError(const QString& file_path, int start, const QString& e) {
|
|
||||||
this->errors_storage.append(std::make_tuple(file_path, start, e));
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList ExpressionContext::errors() const {
|
|
||||||
QStringList values;
|
|
||||||
for (auto& tp : this->errors_storage)
|
|
||||||
values.append(QString(u8"Îļþ£º%1\n\t%2").arg(std::get<0>(tp)).arg(std::get<2>(tp)));
|
|
||||||
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ExpressionContext::clearErrors(const QString &file_path, int start) {
|
|
||||||
for (int idx = 0; idx < this->errors_storage.size(); ++idx) {
|
|
||||||
auto &tp = errors_storage[idx];
|
|
||||||
if(std::get<0>(tp) == file_path && std::get<1>(tp) >= start)
|
|
||||||
errors_storage.removeAt(idx--);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<std::shared_ptr<const IBasicRule>> ExpressionContext::currentExprRuleStack() const {
|
|
||||||
return rule_stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ExpressionContext::appendDocInst(std::shared_ptr<ast_basic::IExprInst> inst) {
|
|
||||||
this->document_store.append(inst);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<std::shared_ptr<const ast_basic::IExprInst>> ExpressionContext::getDocInsts() const {
|
|
||||||
return this->document_store;
|
|
||||||
}
|
|
||||||
|
|
@ -77,35 +77,4 @@ namespace ast_basic {
|
||||||
void addChild(std::shared_ptr<const IExprInst> inst) override;
|
void addChild(std::shared_ptr<const IExprInst> inst) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LIBSYNTAX_EXPORT ExpressionContext : public lib_syntax::IContext, public std::enable_shared_from_this<ExpressionContext> {
|
|
||||||
private:
|
|
||||||
QList<std::shared_ptr<const lib_syntax::IBasicRule>> rule_stack;
|
|
||||||
QList<std::shared_ptr<IExprInst>> expression_stack;
|
|
||||||
QList<std::shared_ptr<const ast_basic::IExprInst>> document_store;
|
|
||||||
QString current_file_path;
|
|
||||||
QList<std::tuple<QString, int, QString>> errors_storage;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ExpressionContext();
|
|
||||||
|
|
||||||
// ͨ¹ý IContext ¼Ì³Ð
|
|
||||||
virtual void setCurrentFile(const QString& path);
|
|
||||||
virtual QString currentFile() const;
|
|
||||||
|
|
||||||
std::shared_ptr<ast_basic::IExprInst> currentExprInst() const override;
|
|
||||||
void pushExprInst(std::shared_ptr<ast_basic::IExprInst> current_inst) override;
|
|
||||||
std::shared_ptr<ast_basic::IExprInst> popExprInst() override;
|
|
||||||
|
|
||||||
std::shared_ptr<const lib_syntax::IBasicRule> currentExprRule() const override;
|
|
||||||
void pushExprRule(std::shared_ptr<const lib_syntax::IBasicRule> inst) override;
|
|
||||||
std::shared_ptr<const lib_syntax::IBasicRule> popExprRule() override;
|
|
||||||
virtual QList<std::shared_ptr<const lib_syntax::IBasicRule>> currentExprRuleStack() const;
|
|
||||||
|
|
||||||
virtual void appendDocInst(std::shared_ptr<ast_basic::IExprInst> inst) override;
|
|
||||||
virtual QList<std::shared_ptr<const ast_basic::IExprInst>> getDocInsts() const override;
|
|
||||||
|
|
||||||
void appendParseError(const QString& file_path, int start, const QString& error_msg) override;
|
|
||||||
QStringList errors() const override;
|
|
||||||
void clearErrors(const QString& file_path, int start) override;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +102,7 @@ namespace ast_gen
|
||||||
/**
|
/**
|
||||||
* @brief ¸ùÔªËØ¶¨Òå
|
* @brief ¸ùÔªËØ¶¨Òå
|
||||||
*/
|
*/
|
||||||
class LIBSYNTAX_EXPORT GlobalElement : public SyntaxElement, public ast_basic::ExpressionContext {
|
class LIBSYNTAX_EXPORT GlobalElement : public SyntaxElement {
|
||||||
private:
|
private:
|
||||||
QString names_store;
|
QString names_store;
|
||||||
QHash<QString, std::shared_ptr<const SyntaxElement>> node_cache;
|
QHash<QString, std::shared_ptr<const SyntaxElement>> node_cache;
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ namespace example_novel
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace lib_syntax {
|
namespace lib_syntax {
|
||||||
template<> class ElementRule<example_novel::TextSection> : public ExprRule {
|
template<> class ElementRule<example_novel::TextSection> : public lib_syntax::ExprRule {
|
||||||
public:
|
public:
|
||||||
ElementRule<example_novel::TextSection>(const QString& rule_name, int expr_mark)
|
ElementRule<example_novel::TextSection>(const QString& rule_name, int expr_mark)
|
||||||
:ExprRule(rule_name, expr_mark) {}
|
:ExprRule(rule_name, expr_mark) {}
|
||||||
|
|
@ -179,36 +179,21 @@ namespace lib_syntax {
|
||||||
std::make_shared<example_novel::TextSection>(this->shared_from_this()));
|
std::make_shared<example_novel::TextSection>(this->shared_from_this()));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::shared_ptr<ExprRule> makeCopy() const {
|
virtual std::shared_ptr<lib_syntax::ExprRule> makeCopy() const {
|
||||||
return std::make_shared<ElementRule<example_novel::TextSection>>(name(), typeMark());
|
return std::make_shared<ElementRule<example_novel::TextSection>>(name(), typeMark());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::tuple<IBasicRule::MatchResult, std::shared_ptr<const lib_token::IWordBase>>
|
virtual QList<ParseFork> parse(const ParseFork& context) const override {
|
||||||
parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head, IBasicRule::ErrDeals &fx_type) const override {
|
|
||||||
std::shared_ptr<ast_basic::IExprInst> elm_ast = this->newEmptyInstance();
|
|
||||||
auto text_present = this->token_present();
|
auto text_present = this->token_present();
|
||||||
|
|
||||||
rt_inst->pushExprRule(this->shared_from_this());
|
ParseFork estart;
|
||||||
rt_inst->pushExprInst(elm_ast);
|
estart.next = context.next;
|
||||||
|
auto result_fork = this->child_store->parse(estart);
|
||||||
|
for (auto rst : result_fork) {
|
||||||
|
switch (rst.occurs) {
|
||||||
|
case ErrDeals::None: {
|
||||||
|
auto tokens_decl = result_fork.first().tokens_list;
|
||||||
|
|
||||||
IBasicRule::ErrDeals fixed = IBasicRule::ErrDeals::None;
|
|
||||||
auto rstg = child_store->parse(rt_inst, head, fixed);
|
|
||||||
auto tokens_decl = elm_ast->tokens();
|
|
||||||
|
|
||||||
switch (std::get<0>(rstg)) {
|
|
||||||
case IBasicRule::MatchResult::Fail:
|
|
||||||
case IBasicRule::MatchResult::Part:
|
|
||||||
rt_inst->popExprInst();
|
|
||||||
rt_inst->popExprRule();
|
|
||||||
break;
|
|
||||||
case IBasicRule::MatchResult::Success: {
|
|
||||||
if (!std::dynamic_pointer_cast<example_novel::Document>(elm_ast)) {
|
|
||||||
auto start_pos = head->position();
|
|
||||||
rt_inst->clearErrors(rt_inst->currentFile(), start_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
rt_inst->popExprInst();
|
|
||||||
rt_inst->popExprRule();
|
|
||||||
while (tokens_decl.size()) {
|
while (tokens_decl.size()) {
|
||||||
auto text_paragraph = this->newEmptyInstance();
|
auto text_paragraph = this->newEmptyInstance();
|
||||||
int row_n = tokens_decl.first()->row();
|
int row_n = tokens_decl.first()->row();
|
||||||
|
|
@ -220,23 +205,17 @@ namespace lib_syntax {
|
||||||
tokens_decl.removeAt(idx--);
|
tokens_decl.removeAt(idx--);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rst.mbrs_list << text_paragraph;
|
||||||
if (rt_inst->currentExprInst()) {
|
|
||||||
rt_inst->currentExprInst()->addChild(text_paragraph);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rt_inst->appendDocInst(text_paragraph);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return QList<ParseFork>{ rst };
|
||||||
}break;
|
}break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rstg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result_fork;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,75 +11,74 @@ TokenMatch::TokenMatch(shared_ptr<const ITokenDefine> define) : define_peer(defi
|
||||||
|
|
||||||
QList<shared_ptr<const IBasicRule>> TokenMatch::children() const { return QList<shared_ptr<const IBasicRule>>(); }
|
QList<shared_ptr<const IBasicRule>> TokenMatch::children() const { return QList<shared_ptr<const IBasicRule>>(); }
|
||||||
|
|
||||||
ParseResult TokenMatch::parse(shared_ptr<IContext> rt_inst, shared_ptr<const IWordBase> head, ErrDeals& fx_type) const
|
QList<ParseFork> TokenMatch::parse(const ParseFork& context) const
|
||||||
{
|
{
|
||||||
|
auto head = context.next;
|
||||||
if (!head) {
|
if (!head) {
|
||||||
rt_inst->appendParseError(rt_inst->currentFile(), -1, QString(u8"Syntax[0x0000]token流(%1)提前终止").arg(rt_inst->currentFile()));
|
ParseFork result(context);
|
||||||
return ParseResult();
|
result.error_messages << u8"输入流提前终止";
|
||||||
|
result.next = nullptr;
|
||||||
|
result.occurs = ErrDeals::TerminalAOT;
|
||||||
|
return QList<ParseFork>{result};
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseResult result_ret;
|
QList<ParseFork> result_list;
|
||||||
auto match_result = define_peer->analysis(head);
|
auto match_result = define_peer->analysis(head);
|
||||||
if (get<0>(match_result)) {
|
if (get<0>(match_result)) {
|
||||||
rt_inst->currentExprInst()->addToken(get<0>(match_result));
|
ParseFork success_fork(context);
|
||||||
|
success_fork.tokens_list << get<0>(match_result);
|
||||||
|
|
||||||
decltype(result_ret.result_repair) v_result;
|
|
||||||
if (get<1>(match_result)) {
|
if (get<1>(match_result)) {
|
||||||
v_result = make_tuple(MatchResult::Success, make_shared<WordImpl>(get<1>(match_result), head->nextWord()));
|
success_fork.next = make_shared<WordImpl>(get<1>(match_result), head->nextWord());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v_result = make_tuple(MatchResult::Success, head->nextWord());
|
success_fork.next = head->nextWord();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fx_type == ErrDeals::None)
|
|
||||||
result_ret.result_straight = v_result;
|
|
||||||
else
|
|
||||||
result_ret.result_repair = v_result;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
switch (fx_type) {
|
if (context.occurs != ErrDeals::None) {
|
||||||
case lib_syntax::ErrDeals::Replace:
|
ParseFork fail_fork(context);
|
||||||
fx_type = ErrDeals::None;
|
fail_fork.error_messages << QString(u8"Syntax[0x0001]解析终止,Token匹配失败('%1'<row:%2,col:%3>)。")
|
||||||
result_ret.result_repair = make_tuple(MatchResult::Success, head->nextWord());
|
.arg(head->content()).arg(head->row()).arg(head->column());
|
||||||
rt_inst->appendParseError(rt_inst->currentFile(), head->position(), QString(u8"指定Token<row:%3,col:%4>“%1”匹配错误,应为“%2”。")
|
fail_fork.next = nullptr;
|
||||||
.arg(head->content()).arg(this->define_peer->reviseWords()).arg(head->row()).arg(head->column()));
|
fail_fork.occurs = ErrDeals::Abort;
|
||||||
break;
|
|
||||||
|
|
||||||
case lib_syntax::ErrDeals::Absence:
|
return result_list << fail_fork;
|
||||||
fx_type = ErrDeals::None;
|
}
|
||||||
result_ret.result_repair = make_tuple(MatchResult::Success, head);
|
// 缺一个
|
||||||
rt_inst->appendParseError(rt_inst->currentFile(), head->position(), QString(u8"指定位置缺失Token<row:%2,col:%3>,应为“%1”。")
|
ParseFork absence_fork(context);
|
||||||
.arg(this->define_peer->reviseWords()).arg(head->row()).arg(head->column()));
|
result_list << absence_fork;
|
||||||
break;
|
absence_fork.error_messages << QString(u8"Syntax[0x0002]缺失Token('%1'<row:%2,col:%3>)。")
|
||||||
|
.arg(this->token_present()).arg(head->row()).arg(head->column());
|
||||||
|
absence_fork.next = head;
|
||||||
|
absence_fork.occurs = ErrDeals::Absence;
|
||||||
|
|
||||||
case lib_syntax::ErrDeals::Surplus:
|
// 错一个
|
||||||
fx_type = ErrDeals::None;
|
ParseFork replace_fork(context);
|
||||||
{
|
result_list << replace_fork;
|
||||||
|
replace_fork.error_messages << QString(u8"Syntax[0x0003]纠正Token('%1'<row:%2,col:%3>,应该为'%4')。")
|
||||||
|
.arg(head->content()).arg(head->row()).arg(head->column()).arg(this->token_present());
|
||||||
|
replace_fork.next = head->nextWord();
|
||||||
|
replace_fork.occurs = ErrDeals::Replace;
|
||||||
|
|
||||||
|
// 多一个
|
||||||
auto temp_head = head->nextWord();
|
auto temp_head = head->nextWord();
|
||||||
auto match_result = define_peer->analysis(temp_head);
|
auto match_result = define_peer->analysis(temp_head);
|
||||||
if (get<0>(match_result)) {
|
if (get<0>(match_result)) {
|
||||||
rt_inst->appendParseError(rt_inst->currentFile(), head->position(), QString(u8"发现冗余Token<row:%2,col:%3>,内容为“%1”。")
|
ParseFork surplus_fork(context);
|
||||||
.arg(head->content()).arg(head->row()).arg(head->column()));
|
result_list << surplus_fork;
|
||||||
|
surplus_fork.error_messages << QString(u8"Syntax[0x0004]发现冗余Token('%1'<row:%2,col:%3>)。")
|
||||||
|
.arg(head->content()).arg(head->row()).arg(head->column());
|
||||||
|
surplus_fork.occurs = ErrDeals::Surplus;
|
||||||
|
surplus_fork.tokens_list << get<0>(match_result);
|
||||||
|
|
||||||
rt_inst->currentExprInst()->addToken(get<0>(match_result));
|
|
||||||
if (get<1>(match_result))
|
if (get<1>(match_result))
|
||||||
result_ret.result_repair = make_tuple(MatchResult::Success, make_shared<WordImpl>(get<1>(match_result), temp_head->nextWord()));
|
surplus_fork.next = make_shared<WordImpl>(get<1>(match_result), temp_head->nextWord());
|
||||||
else
|
else
|
||||||
result_ret.result_repair = make_tuple(MatchResult::Success, temp_head->nextWord());
|
surplus_fork.next = temp_head->nextWord();
|
||||||
}
|
|
||||||
else {
|
|
||||||
result_ret.result_repair = make_tuple(MatchResult::Part, head);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
return result_list;
|
||||||
|
|
||||||
default:
|
|
||||||
result_ret.result_straight = make_tuple(MatchResult::Part, head);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result_ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TokenMatch::token_present() const {
|
QString TokenMatch::token_present() const {
|
||||||
|
|
@ -90,78 +89,97 @@ Rept::Rept(shared_ptr<const IBasicRule> rule, int min, int max) : rule_peer(rule
|
||||||
|
|
||||||
QList<shared_ptr<const IBasicRule>> Rept::children() const { return QList<shared_ptr<const IBasicRule>>() << rule_peer; }
|
QList<shared_ptr<const IBasicRule>> Rept::children() const { return QList<shared_ptr<const IBasicRule>>() << rule_peer; }
|
||||||
|
|
||||||
ParseResult Rept::parse(shared_ptr<IContext> rt_inst, shared_ptr<const IWordBase> head, ErrDeals& fx_type) const {
|
QList<ParseFork> tidy_results(QList<ParseFork> temp_results) {
|
||||||
ParseResult fnl_result;
|
QList<ParseFork> ret_forks;
|
||||||
|
std::copy_if(temp_results.begin(), temp_results.end(), std::back_inserter(ret_forks),
|
||||||
|
[](ParseFork elm)->bool {
|
||||||
|
return elm.occurs == ErrDeals::None;
|
||||||
|
});
|
||||||
|
|
||||||
auto temp_head = head;
|
// 成功匹配
|
||||||
auto initial_fxtype = ErrDeals::None;
|
if (ret_forks.size())
|
||||||
|
return ret_forks;
|
||||||
|
|
||||||
retry_entry:
|
std::copy_if(temp_results.begin(), temp_results.end(), std::back_inserter(ret_forks),
|
||||||
switch (initial_fxtype) {
|
[](ParseFork elm)->bool {
|
||||||
case lib_syntax::ErrDeals::Surplus:
|
return elm.occurs == ErrDeals::Absence || elm.occurs == ErrDeals::Surplus || elm.occurs == ErrDeals::Replace;
|
||||||
case lib_syntax::ErrDeals::Absence:
|
});
|
||||||
case lib_syntax::ErrDeals::Replace:
|
|
||||||
|
|
||||||
|
// 修正匹配
|
||||||
|
if (ret_forks.size())
|
||||||
|
return ret_forks;
|
||||||
|
|
||||||
break;
|
// 失败匹配
|
||||||
case lib_syntax::ErrDeals::None:
|
return temp_results;
|
||||||
// min-match
|
|
||||||
for (auto idx = 0; idx < min_match; ++idx) {
|
|
||||||
auto result_genx = rule_peer->parse(rt_inst, temp_head, initial_fxtype);
|
|
||||||
|
|
||||||
switch (std::get<0>(result_genx.result_straight)) {
|
|
||||||
case MatchResult::Part:
|
|
||||||
if(fx_type == ErrDeals::None)
|
|
||||||
return result_genx;
|
|
||||||
|
|
||||||
initial_fxtype = fx_type;
|
|
||||||
temp_head = head;
|
|
||||||
goto retry_entry;
|
|
||||||
|
|
||||||
default:
|
|
||||||
temp_head = std::get<1>(result_genx.result_straight);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// max-match
|
QList<ParseFork> Rept::parse(const ParseFork& context) const {
|
||||||
for (auto idx = min_match; idx < max_match; ++idx) {
|
std::function<QList<ParseFork>(const ParseFork&, int)> min_match_calc =
|
||||||
if (!temp_head)
|
[&](const ParseFork& context, int times_remains)->QList<ParseFork> {
|
||||||
break;
|
QList<ParseFork> retvs;
|
||||||
|
|
||||||
auto result_genx = rule_peer->parse(rt_inst, temp_head, initial_fxtype);
|
if (!times_remains)
|
||||||
auto v_result = result_genx.result_straight;
|
return retvs << context;
|
||||||
if (std::get<0>(v_result) == MatchResult::None) {
|
|
||||||
v_result = result_genx.result_repair;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (get<0>(v_result)) {
|
|
||||||
case MatchResult::Part:
|
|
||||||
if (straight_flags)
|
|
||||||
fnl_result.result_straight = v_result;
|
|
||||||
else
|
|
||||||
fnl_result.result_repair = v_result;
|
|
||||||
return fnl_result;
|
|
||||||
|
|
||||||
default:
|
|
||||||
temp_head = get<1>(v_result);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
auto result_forks = rule_peer->parse(context);
|
||||||
|
for (auto it : result_forks) {
|
||||||
|
switch (it.occurs) {
|
||||||
|
case ErrDeals::Abort:
|
||||||
|
case ErrDeals::TerminalAOT:
|
||||||
|
retvs << it;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
retvs << min_match_calc(it, times_remains - 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retvs;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::function<QList<ParseFork>(const ParseFork&, int)> max_match_calc =
|
||||||
|
[&](const ParseFork& context, int times_remains) -> QList<ParseFork> {
|
||||||
|
QList<ParseFork> retvs;
|
||||||
|
|
||||||
|
if (!times_remains)
|
||||||
|
return retvs << context;
|
||||||
|
|
||||||
|
auto result_forks = rule_peer->parse(context);
|
||||||
|
for (auto rst : result_forks) {
|
||||||
|
switch (rst.occurs) {
|
||||||
|
case ErrDeals::Abort:
|
||||||
|
case ErrDeals::TerminalAOT:
|
||||||
|
retvs << context;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrDeals::Surplus:
|
||||||
|
case ErrDeals::Absence:
|
||||||
|
case ErrDeals::Replace:
|
||||||
|
if (context.occurs == ErrDeals::None)
|
||||||
|
retvs << context;
|
||||||
|
default:
|
||||||
|
retvs << max_match_calc(rst, times_remains - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retvs;;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
if(straight_flags)
|
auto temp_results = min_match_calc(context, min_match);
|
||||||
fnl_result.result_straight = make_tuple(MatchResult::Success, temp_head);
|
auto rst_itor = std::find_if(temp_results.begin(), temp_results.end(), [](ParseFork e) -> bool {
|
||||||
else
|
return QList<ErrDeals>{ ErrDeals::None, ErrDeals::Surplus, ErrDeals::Absence, ErrDeals::Replace }.contains(e.occurs);
|
||||||
fnl_result.result_repair = make_tuple(MatchResult::Success, temp_head);
|
});
|
||||||
|
|
||||||
fx_type = initial_fxtype;
|
if(rst_itor == temp_results.end())
|
||||||
return fnl_result;
|
return temp_results;
|
||||||
|
|
||||||
|
decltype(temp_results) result_x2;
|
||||||
|
for(auto xit : temp_results)
|
||||||
|
result_x2 << max_match_calc(xit, max_match - min_match);
|
||||||
|
|
||||||
|
return tidy_results(result_x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Rept::token_present() const
|
QString Rept::token_present() const
|
||||||
|
|
@ -173,40 +191,35 @@ Seqs::Seqs(const QList<shared_ptr<const IBasicRule>> mbrs) : mbrs_store(mbrs) {}
|
||||||
|
|
||||||
QList<shared_ptr<const IBasicRule>> Seqs::children() const { return mbrs_store; }
|
QList<shared_ptr<const IBasicRule>> Seqs::children() const { return mbrs_store; }
|
||||||
|
|
||||||
ParseResult Seqs::parse(shared_ptr<IContext> rt_inst, shared_ptr<const IWordBase> head, ErrDeals& fx_type) const {
|
QList<ParseFork> Seqs::parse(const ParseFork& context) const {
|
||||||
ParseResult result_final;
|
function<QList<ParseFork>(const ParseFork &, QList<shared_ptr<const IBasicRule>>::const_iterator)> match_seqs =
|
||||||
|
[&](const ParseFork& context, QList<shared_ptr<const IBasicRule>>::const_iterator rule_it) -> QList<ParseFork> {
|
||||||
|
QList<ParseFork> retvs;
|
||||||
|
|
||||||
auto temp_head = head;
|
auto cendx = mbrs_store.cend();
|
||||||
bool straight_mark = fx_type == ErrDeals::None;
|
if(rule_it == mbrs_store.cend())
|
||||||
for (auto& r : mbrs_store) {
|
return retvs << context;
|
||||||
auto rule_present = r->token_present();
|
|
||||||
auto rst_gene = r->parse(rt_inst, temp_head, fx_type);
|
|
||||||
|
|
||||||
auto v_result = rst_gene.result_straight;
|
auto rule_present = (*rule_it)->token_present();
|
||||||
if (std::get<0>(v_result) == MatchResult::None)
|
auto result_forks = (*rule_it)->parse(context);
|
||||||
v_result = rst_gene.result_repair;
|
for (auto fork : result_forks) {
|
||||||
|
switch (fork.occurs) {
|
||||||
switch (get<0>(v_result)) {
|
case ErrDeals::Abort:
|
||||||
case MatchResult::Part:
|
case ErrDeals::TerminalAOT:
|
||||||
if (straight_mark)
|
retvs << fork;
|
||||||
result_final.result_straight = v_result;
|
|
||||||
else
|
|
||||||
result_final.result_repair = v_result;
|
|
||||||
return result_final;
|
|
||||||
|
|
||||||
case MatchResult::Success:
|
|
||||||
temp_head = get<1>(v_result);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
retvs << match_seqs(fork, rule_it + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (straight_mark)
|
return retvs;
|
||||||
result_final.result_straight = make_tuple(MatchResult::Success, temp_head);
|
};
|
||||||
else
|
|
||||||
result_final.result_repair = make_tuple(MatchResult::Success, temp_head);
|
auto temp_results = match_seqs(context, mbrs_store.cbegin());
|
||||||
return result_final;
|
return tidy_results(temp_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Seqs::token_present() const
|
QString Seqs::token_present() const
|
||||||
|
|
@ -217,93 +230,30 @@ QString Seqs::token_present() const
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
//tuple<MatchResult, uint, shared_ptr<const IBasicRule>, shared_ptr<const Token>>
|
|
||||||
Any::Any(const QList<shared_ptr<const IBasicRule>> mbrs) : mbrs_store(mbrs) {}
|
Any::Any(const QList<shared_ptr<const IBasicRule>> mbrs) : mbrs_store(mbrs) {}
|
||||||
|
|
||||||
QList<shared_ptr<const IBasicRule>> Any::children() const { return mbrs_store; }
|
QList<shared_ptr<const IBasicRule>> Any::children() const { return mbrs_store; }
|
||||||
|
|
||||||
ParseResult Any::parse(shared_ptr<IContext> rt_inst, shared_ptr<const IWordBase> head, ErrDeals& fx_type) const {
|
QList<ParseFork> Any::parse(const ParseFork& context) const {
|
||||||
auto rule_present = this->token_present();
|
auto rule_present = this->token_present();
|
||||||
|
QList<ParseFork> temp_results;
|
||||||
|
|
||||||
std::tuple<std::shared_ptr<const IBasicRule>, uint64_t> temp_result = std::make_tuple(nullptr, 0);
|
|
||||||
bool straight_mark = fx_type ==
|
|
||||||
|
|
||||||
switch (fx_type) {
|
|
||||||
case ErrDeals::None: {
|
|
||||||
ParseResult result_final;
|
|
||||||
for (auto& fork : mbrs_store) {
|
for (auto& fork : mbrs_store) {
|
||||||
auto xgen = fork->parse(rt_inst, head, fx_type);
|
auto result_forks = fork->parse(context);
|
||||||
|
for (auto rst_fork : result_forks) {
|
||||||
|
switch (rst_fork.occurs) {
|
||||||
|
case ErrDeals::None:
|
||||||
|
return QList<ParseFork>{ rst_fork };
|
||||||
|
|
||||||
auto v_result = xgen.result_straight;
|
|
||||||
if (std::get<0>(v_result) == MatchResult::None)
|
|
||||||
v_result = xgen.result_repair;
|
|
||||||
|
|
||||||
switch (get<0>(v_result)) {
|
|
||||||
// 遇到成功的直接返回解析结果
|
|
||||||
case MatchResult::Success:
|
|
||||||
return gen;
|
|
||||||
|
|
||||||
case MatchResult::Part: {
|
|
||||||
auto span = get<1>(gen.result_straight)->position() - head->position();
|
|
||||||
if (span >= get<1>(temp_result))
|
|
||||||
temp_result = make_tuple(fork, span);
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
|
temp_results << rst_fork;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& itfx : QList<ErrDeals>{ ErrDeals::Surplus, ErrDeals::Absence, ErrDeals::Replace }) {
|
|
||||||
auto fix_current = itfx;
|
|
||||||
auto repair_result = this->parse(rt_inst, head, fix_current);
|
|
||||||
|
|
||||||
auto v_result = repair_result.result_straight;
|
|
||||||
if (std::get<0>(v_result) == MatchResult::None)
|
|
||||||
v_result = repair_result.result_repair;
|
|
||||||
|
|
||||||
switch (std::get<0>(v_result)) {
|
|
||||||
case MatchResult::Success:
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}break;
|
return tidy_results(temp_results);
|
||||||
|
|
||||||
default: {
|
|
||||||
ParseResult inst;
|
|
||||||
|
|
||||||
for (auto& fork : mbrs_store) {
|
|
||||||
auto fx_init = fx_type;
|
|
||||||
|
|
||||||
auto gen = fork->parse(rt_inst, head, fx_init);
|
|
||||||
auto v_result = gen.result_straight;
|
|
||||||
if (std::get<0>(v_result) == MatchResult::None)
|
|
||||||
v_result = gen.result_repair;
|
|
||||||
|
|
||||||
switch (std::get<0>(v_result)) {
|
|
||||||
case MatchResult::Success:
|
|
||||||
inst.result_repair = v_result;
|
|
||||||
fx_type = fx_init;
|
|
||||||
return inst;
|
|
||||||
|
|
||||||
default: {
|
|
||||||
auto span = std::get<1>(v_result)->position() - head->position();
|
|
||||||
if (span >= std::get<1>(temp_result))
|
|
||||||
temp_result = std::make_tuple(fork, span);
|
|
||||||
}break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分析最匹配的分支
|
|
||||||
rt_inst->clearErrors(rt_inst->currentFile(), head->position());
|
|
||||||
auto temp = get<0>(temp_result)->parse(rt_inst, head, fx_type);
|
|
||||||
return make_tuple(MatchResult::Part, get<1>(temp));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Any::token_present() const
|
QString Any::token_present() const
|
||||||
|
|
@ -339,45 +289,67 @@ QList<shared_ptr<const IBasicRule>> ExprRule::children() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <ast_novel.h>
|
#include <ast_novel.h>
|
||||||
tuple<MatchResult, shared_ptr<const IWordBase>>
|
QList<ParseFork> ExprRule::parse(const ParseFork& context) const {
|
||||||
ExprRule::parse(shared_ptr<IContext> rt_inst, shared_ptr<const IWordBase> head, ErrDeals& fx_type) const {
|
|
||||||
auto text_present = this->token_present();
|
auto text_present = this->token_present();
|
||||||
|
|
||||||
|
ParseFork elm_start;
|
||||||
|
elm_start.next = context.next;
|
||||||
|
|
||||||
|
QList<ParseFork> temp_returns;
|
||||||
|
auto result_forks = child_store->parse(elm_start);
|
||||||
|
for (auto fork : result_forks) {
|
||||||
|
switch (fork.occurs) {
|
||||||
|
case ErrDeals::None: {
|
||||||
|
ParseFork value(context);
|
||||||
shared_ptr<IExprInst> elm_ast = this->newEmptyInstance();
|
shared_ptr<IExprInst> elm_ast = this->newEmptyInstance();
|
||||||
|
for (auto& token : fork.tokens_list)
|
||||||
|
elm_ast->addToken(token);
|
||||||
|
for (auto& child : fork.mbrs_list)
|
||||||
|
elm_ast->addChild(child);
|
||||||
|
|
||||||
rt_inst->pushExprRule(this->shared_from_this());
|
value.mbrs_list << elm_ast;
|
||||||
rt_inst->pushExprInst(elm_ast);
|
value.next = fork.next;
|
||||||
|
|
||||||
auto ret_tuple = child_store->parse(rt_inst, head, fx_type);
|
return QList<ParseFork>{ value };
|
||||||
switch (get<0>(ret_tuple)) {
|
|
||||||
case MatchResult::Success:
|
|
||||||
if (!dynamic_pointer_cast<example_novel::Document>(elm_ast) && fx_type == ErrDeals::None) {
|
|
||||||
rt_inst->clearErrors(rt_inst->currentFile(), head->position());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rt_inst->popExprInst();
|
case ErrDeals::Surplus:
|
||||||
rt_inst->popExprRule();
|
case ErrDeals::Absence:
|
||||||
|
case ErrDeals::Replace: {
|
||||||
|
ParseFork value(context);
|
||||||
|
value.error_messages << fork.error_messages;
|
||||||
|
shared_ptr<IExprInst> elm_ast = this->newEmptyInstance();
|
||||||
|
for (auto& token : fork.tokens_list)
|
||||||
|
elm_ast->addToken(token);
|
||||||
|
for (auto& child : fork.mbrs_list)
|
||||||
|
elm_ast->addChild(child);
|
||||||
|
|
||||||
if (rt_inst->currentExprInst()) {
|
value.mbrs_list << elm_ast;
|
||||||
rt_inst->currentExprInst()->addChild(elm_ast);
|
value.next = fork.next;
|
||||||
}
|
|
||||||
else {
|
|
||||||
rt_inst->appendDocInst(elm_ast);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MatchResult::Part:
|
temp_returns << value;
|
||||||
case MatchResult::Fail:
|
} break;
|
||||||
rt_inst->popExprInst();
|
|
||||||
rt_inst->popExprRule();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret_tuple;
|
// 修正后的完整匹配结果
|
||||||
|
if (temp_returns.size())
|
||||||
|
return temp_returns;
|
||||||
|
|
||||||
|
return result_forks;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ExprRule::token_present() const {
|
QString ExprRule::token_present() const {
|
||||||
return child_store->token_present();
|
return child_store->token_present();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParseFork::ParseFork() : occurs(ErrDeals::None) {}
|
||||||
|
|
||||||
|
ParseFork::ParseFork(const ParseFork& other)
|
||||||
|
: occurs(other.occurs),
|
||||||
|
error_messages(other.error_messages),
|
||||||
|
mbrs_list(other.mbrs_list),
|
||||||
|
tokens_list(other.tokens_list) {}
|
||||||
|
|
|
||||||
|
|
@ -28,63 +28,30 @@ namespace lib_syntax {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 基础语法解析接口 ===================================================================================================
|
// 基础语法解析接口 ===================================================================================================
|
||||||
/**
|
|
||||||
* @brief 解析上下文接口
|
|
||||||
*/
|
|
||||||
class IContext {
|
|
||||||
public:
|
|
||||||
virtual ~IContext() = default;
|
|
||||||
|
|
||||||
virtual void setCurrentFile(const QString& path) = 0;
|
|
||||||
virtual QString currentFile() const = 0;
|
|
||||||
|
|
||||||
virtual void appendParseError(const QString& file_path, int start, const QString& error_msg) = 0;
|
|
||||||
virtual QStringList errors() const = 0;
|
|
||||||
virtual void clearErrors(const QString& file_path, int start) = 0;
|
|
||||||
|
|
||||||
virtual void appendDocInst(std::shared_ptr<ast_basic::IExprInst> inst) = 0;
|
|
||||||
virtual QList<std::shared_ptr<const ast_basic::IExprInst>> getDocInsts() const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief 当前表达式元素.
|
|
||||||
*
|
|
||||||
* \return 返回当前表达式
|
|
||||||
*/
|
|
||||||
virtual std::shared_ptr<ast_basic::IExprInst> currentExprInst() const = 0;
|
|
||||||
virtual void pushExprInst(std::shared_ptr<ast_basic::IExprInst> current_inst) = 0;
|
|
||||||
virtual std::shared_ptr<ast_basic::IExprInst> popExprInst() = 0;
|
|
||||||
|
|
||||||
virtual std::shared_ptr<const IBasicRule> currentExprRule() const = 0;
|
|
||||||
virtual void pushExprRule(std::shared_ptr<const IBasicRule> inst) = 0;
|
|
||||||
virtual std::shared_ptr<const IBasicRule> popExprRule() = 0;
|
|
||||||
virtual QList<std::shared_ptr<const IBasicRule>> currentExprRuleStack() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 匹配结果
|
|
||||||
*/
|
|
||||||
enum class MatchResult {
|
|
||||||
None, // 不适用
|
|
||||||
Success, // 符合匹配条件
|
|
||||||
Part, // 部分匹配
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 修正类型
|
* @brief 修正类型
|
||||||
*/
|
*/
|
||||||
enum class ErrDeals {
|
enum class ErrDeals {
|
||||||
None, // 不修复
|
None, // 无错误
|
||||||
Surplus, // 多一个词
|
Surplus, // 多一个词
|
||||||
Absence, // 少一个词
|
Absence, // 少一个词
|
||||||
Replace, // 错一个词
|
Replace, // 错一个词
|
||||||
|
Abort, // 中断解析过程
|
||||||
|
TerminalAOT, // 输入提前终止
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 匹配结果,返回直接匹配结果和修复匹配结果.
|
* @brief 解析分支
|
||||||
*/
|
*/
|
||||||
struct ParseResult {
|
struct LIBSYNTAX_EXPORT ParseFork {
|
||||||
std::tuple<MatchResult, std::shared_ptr<const lib_token::IWordBase>> result_straight = std::make_tuple(MatchResult::None, nullptr);
|
ErrDeals occurs = ErrDeals::None; // 解析过程中的错误
|
||||||
std::tuple<MatchResult, std::shared_ptr<const lib_token::IWordBase>> result_repair = std::make_tuple(MatchResult::None, nullptr);
|
QList<QString> error_messages; // 累计错误信息
|
||||||
|
QList<std::shared_ptr<const ast_basic::IExprInst>> mbrs_list; // 成员存储
|
||||||
|
QList<std::shared_ptr<const lib_token::IToken>> tokens_list; // token列表
|
||||||
|
std::shared_ptr<const lib_token::IWordBase> next = nullptr; // 下一个解析词
|
||||||
|
|
||||||
|
ParseFork();
|
||||||
|
ParseFork(const ParseFork& other);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -102,12 +69,10 @@ namespace lib_syntax {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 解析
|
* @brief 解析
|
||||||
* @param rt_inst 解析上下文
|
* @param context 累计上下文
|
||||||
* @param head 列表头
|
* @return 返回结果<解析分支>
|
||||||
* @param fx_type 修正措施
|
|
||||||
* @return 返回结果<匹配完成新列表头,匹配长度>
|
|
||||||
*/
|
*/
|
||||||
virtual ParseResult parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head, ErrDeals& fx_type) const = 0;
|
virtual QList<ParseFork> parse(const ParseFork& context) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回匹配语法规则的词法序列表达
|
* 返回匹配语法规则的词法序列表达
|
||||||
|
|
@ -131,7 +96,7 @@ namespace lib_syntax {
|
||||||
// IBasicRule interface
|
// IBasicRule interface
|
||||||
public:
|
public:
|
||||||
virtual QList<std::shared_ptr<const IBasicRule>> children() const override;
|
virtual QList<std::shared_ptr<const IBasicRule>> children() const override;
|
||||||
virtual ParseResult parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head, ErrDeals& fx_type) const override;
|
virtual QList<ParseFork> parse(const ParseFork& context) const override;
|
||||||
virtual QString token_present() const override;
|
virtual QString token_present() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -142,15 +107,13 @@ namespace lib_syntax {
|
||||||
private:
|
private:
|
||||||
QList<std::shared_ptr<const IBasicRule>> mbrs_store;
|
QList<std::shared_ptr<const IBasicRule>> mbrs_store;
|
||||||
|
|
||||||
std::tuple<MatchResult, uint, std::shared_ptr<const IBasicRule>, 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 IBasicRule>> mbrs);
|
Any(const QList<std::shared_ptr<const IBasicRule>> mbrs);
|
||||||
|
|
||||||
// IBasicRule interface
|
// IBasicRule interface
|
||||||
public:
|
public:
|
||||||
virtual QList<std::shared_ptr<const IBasicRule>> children() const override;
|
virtual QList<std::shared_ptr<const IBasicRule>> children() const override;
|
||||||
virtual ParseResult parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head, ErrDeals& fx_type) const override;
|
virtual QList<ParseFork> parse(const ParseFork& context) const override;
|
||||||
virtual QString token_present() const override;
|
virtual QString token_present() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -167,7 +130,7 @@ namespace lib_syntax {
|
||||||
// IBasicRule interface
|
// IBasicRule interface
|
||||||
public:
|
public:
|
||||||
virtual QList<std::shared_ptr<const IBasicRule>> children() const override;
|
virtual QList<std::shared_ptr<const IBasicRule>> children() const override;
|
||||||
virtual ParseResult parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head, ErrDeals& fx_type) const override;
|
virtual QList<ParseFork> parse(const ParseFork& context) const override;
|
||||||
virtual QString token_present() const override;
|
virtual QString token_present() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -185,7 +148,7 @@ namespace lib_syntax {
|
||||||
// IBasicRule interface
|
// IBasicRule interface
|
||||||
public:
|
public:
|
||||||
virtual QList<std::shared_ptr<const IBasicRule>> children() const override;
|
virtual QList<std::shared_ptr<const IBasicRule>> children() const override;
|
||||||
virtual ParseResult parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head, ErrDeals& fx_type) const override;
|
virtual QList<ParseFork> parse(const ParseFork& context) const override;
|
||||||
virtual QString token_present() const override;
|
virtual QString token_present() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -193,7 +156,7 @@ namespace lib_syntax {
|
||||||
/**
|
/**
|
||||||
* @brief 对应语法表达式解析规则
|
* @brief 对应语法表达式解析规则
|
||||||
*/
|
*/
|
||||||
class LIBSYNTAX_EXPORT ExprRule : public lib_syntax::IBasicRule, public std::enable_shared_from_this<ExprRule> {
|
class LIBSYNTAX_EXPORT ExprRule : public IBasicRule, public std::enable_shared_from_this<ExprRule> {
|
||||||
public:
|
public:
|
||||||
typedef QList<std::shared_ptr<const lib_token::IToken>> TokenSeqs;
|
typedef QList<std::shared_ptr<const lib_token::IToken>> TokenSeqs;
|
||||||
ExprRule(const QString& rule_name, int expr_mark);
|
ExprRule(const QString& rule_name, int expr_mark);
|
||||||
|
|
@ -207,12 +170,12 @@ namespace lib_syntax {
|
||||||
|
|
||||||
// IBasicRule interface
|
// IBasicRule interface
|
||||||
public:
|
public:
|
||||||
virtual QList<std::shared_ptr<const lib_syntax::IBasicRule>> children() const override;
|
virtual QList<std::shared_ptr<const IBasicRule>> children() const override;
|
||||||
virtual ParseResult parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const lib_token::IWordBase> head, ErrDeals& fx_type) const override;
|
virtual QList<ParseFork> parse(const ParseFork& context) const override;
|
||||||
virtual QString token_present() const override;
|
virtual QString token_present() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<const lib_syntax::IBasicRule> child_store;
|
std::shared_ptr<const IBasicRule> child_store;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString name_store;
|
QString name_store;
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ void NovalSyntax::node_register(std::shared_ptr<const ast_gen::SyntaxElement> ro
|
||||||
if (!child->isAnonymous()) {
|
if (!child->isAnonymous()) {
|
||||||
auto check_result = ast_gen::GlobalElement::UniquePtr->appendToCache(child);
|
auto check_result = ast_gen::GlobalElement::UniquePtr->appendToCache(child);
|
||||||
if (check_result)
|
if (check_result)
|
||||||
throw new lib_syntax::SyntaxException(QString(u8"SyntaxError[0x0004]系统中包含同类型重名命名节点:%1<type:%2>(%3,%4)")
|
throw new SyntaxException(QString(u8"SyntaxError[0x0004]系统中包含同类型重名命名节点:%1<type:%2>(%3,%4)")
|
||||||
.arg(child->signature()).arg(child->typeMark()).arg(child->path()).arg(check_result->path()));
|
.arg(child->signature()).arg(child->typeMark()).arg(child->path()).arg(check_result->path()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue