WsParser_VS/libSyntax/libsyntax.cpp

259 lines
8.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "libsyntax.h"
#include "ast_basic.h"
using namespace lib_syntax;
using namespace std;
using namespace lib_token;
using namespace ast_basic;
TokenMatch::TokenMatch(shared_ptr<const TokenDefine> define) : define_peer(define) {}
QList<std::shared_ptr<const BaseRule>> TokenMatch::children() const { return QList<std::shared_ptr<const BaseRule>>(); }
std::tuple<BaseRule::MatchResult, uint> TokenMatch::match(const QList<std::shared_ptr<const Token>>& stream) const {
QString token_seqs = this->token_present();
if (stream.size() && define_peer->name() == stream.first()->define()->name())
return std::make_tuple(MatchResult::Success, 1);
// auto mis_match = define_peer->name();
// auto real_match = stream.first()->define()->name();
return std::make_tuple(MatchResult::Fail, 0);
}
std::shared_ptr<const Expression> TokenMatch::parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
if (stream.size()) {
auto current = stream.first();
if (current->define()->name() == define_peer->name()){
rt_inst->currentInst()->addToken(current);
return nullptr;
}
throw new SyntaxException(QString(u8"Syntax[0x00001]语法匹配错误不能识别token%1<%2,%3>")
.arg(current->content()).arg(current->row()).arg(current->column()));
}
throw new SyntaxException(u8"Syntax[0x0000]token流提前终止");
}
QString TokenMatch::token_present() const {
return QString(u8"<%1>").arg(this->define_peer->name());
}
Rept::Rept(std::shared_ptr<const BaseRule> rule, int min, int max) : rule_peer(rule), min_match(min), max_match(max) {}
QList<std::shared_ptr<const BaseRule>> Rept::children() const { return QList<std::shared_ptr<const BaseRule>>() << rule_peer; }
std::tuple<BaseRule::MatchResult, uint> Rept::match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto token_offset = 0;
QString token_seqs = this->token_present();
// min-match
for (auto idx = 0; idx < min_match; ++idx) {
auto result = rule_peer->match(stream.mid(token_offset));
token_offset += std::get<1>(result);
if (std::get<0>(result) != MatchResult::Success) {
return std::make_tuple(token_offset ? MatchResult::Part : MatchResult::Fail, token_offset);
}
}
// max-match
for (auto idx = min_match; idx < max_match; ++idx) {
auto result = rule_peer->match(stream.mid(token_offset));
switch (std::get<0>(result)) {
case MatchResult::Fail:
case MatchResult::Part:
return std::make_tuple(MatchResult::Success, token_offset);
default:
token_offset += std::get<1>(result);
break;
}
}
return std::make_tuple(MatchResult::Success, token_offset);
}
std::shared_ptr<const Expression> Rept::parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto token_offset = 0;
// min-match
for (auto idx = 0; idx < min_match; ++idx) {
auto result = rule_peer->match(stream.mid(token_offset));
auto result_gen = rule_peer->parse(rt_inst, stream.mid(token_offset));
if(result_gen)
rt_inst->currentInst()->addChild(result_gen);
token_offset += std::get<1>(result);
}
// max-match
for (auto idx = min_match; idx < max_match; ++idx) {
auto result = rule_peer->match(stream.mid(token_offset));
switch (std::get<0>(result)) {
case MatchResult::Fail:
case MatchResult::Part:
return nullptr;
default:
break;
}
auto result_gen = rule_peer->parse(rt_inst, stream.mid(token_offset));
if (result_gen)
rt_inst->currentInst()->addChild(result_gen);
token_offset += std::get<1>(result);
}
return nullptr;
}
QString Rept::token_present() const
{
return u8"(" + this->rule_peer->token_present() + QString(u8"{%1, %2}").arg(min_match).arg(max_match) + u8")";
}
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; }
std::tuple<BaseRule::MatchResult, uint> Seqs::match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto token_offset = 0;
QString token_seqs = this->token_present();
for (auto& r : mbrs_store) {
auto v_token_seqs = r->token_present();
auto result = r->match(stream.mid(token_offset));
token_offset += std::get<1>(result);
switch (std::get<0>(result)) {
case MatchResult::Fail:
case MatchResult::Part:
return std::make_tuple(token_offset ? MatchResult::Part : MatchResult::Fail, token_offset);
default:
break;
}
}
return std::make_tuple(MatchResult::Success, token_offset);
}
std::shared_ptr<const Expression> Seqs::parse(std::shared_ptr<ParseContext> rt_inst,const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto token_offset = 0;
for (auto& r : mbrs_store) {
auto rst_gene = r->parse(rt_inst, stream.mid(token_offset));
if(rst_gene)
rt_inst->currentInst()->addChild(rst_gene);
auto result = r->match(stream.mid(token_offset));
token_offset += std::get<1>(result);
}
return nullptr;
}
QString Seqs::token_present() const
{
QString content;
for (auto& it : children())
content += it->token_present();
return QString(u8"(%1)").arg(content);
}
std::tuple<BaseRule::MatchResult, uint, std::shared_ptr<const BaseRule>>
Any::rule_select(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
QString token_seqs = this->token_present();
std::tuple<MatchResult, uint, std::shared_ptr<const BaseRule>> temp = std::make_tuple(MatchResult::Fail, 0, nullptr);
for (auto& r : mbrs_store) {
auto mbr_seqs = r->token_present();
auto result = r->match(stream);
if (std::get<0>(result) == MatchResult::Success)
return std::make_tuple(std::get<0>(result), std::get<1>(result), r);
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);
else
temp = std::make_tuple(MatchResult::Part, std::get<1>(temp), std::get<2>(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);
else
temp = std::make_tuple(MatchResult::Fail, std::get<1>(temp), std::get<2>(temp));
}
}
return temp;
}
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; }
std::tuple<BaseRule::MatchResult, uint> Any::match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto item = rule_select(stream);
return std::make_tuple(std::get<0>(item), std::get<1>(item));
}
std::shared_ptr<const Expression> Any::parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto temp = rule_select(stream);
return std::get<2>(temp)->parse(rt_inst, stream);
}
QString Any::token_present() const
{
QString members_content;
for (auto& it : children()) {
members_content += it->token_present() + u8"|";
}
return u8"(" + members_content.mid(0, members_content.size() - 1) + u8")";
}
SyntaxException::SyntaxException(const QString& message) { this->msg_store = message; }
QString SyntaxException::message() const { return msg_store; }
lib_syntax::ExpressionRule::ExpressionRule(const QString& rule_name, int expr_mark) : name_store(rule_name) {
this->filter_proc = [](const TokenSeqs& seqs) { return seqs; };
this->mark_store = expr_mark;
}
std::shared_ptr<const ExpressionRule> lib_syntax::ExpressionRule::reloadRule(std::function<TokenSeqs(const TokenSeqs&)> filter, std::shared_ptr<const BaseRule> rule) {
auto ninst = makeCopy();
ninst->child_store = rule;
ninst->filter_proc = filter;
return ninst;
}
QString lib_syntax::ExpressionRule::name() const { return name_store; }
int lib_syntax::ExpressionRule::typeMark() const { return this->mark_store; }
QList<std::shared_ptr<const lib_syntax::BaseRule>> lib_syntax::ExpressionRule::children() const {
return QList<std::shared_ptr<const BaseRule>>() << this->child_store;
}
std::tuple<BaseRule::MatchResult, uint> lib_syntax::ExpressionRule::match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
return child_store->match(stream);
}
std::shared_ptr<const ast_basic::Expression> lib_syntax::ExpressionRule::parse(std::shared_ptr<ParseContext> rt_inst, const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
std::shared_ptr<ast_basic::Expression> elm_ast = this->newEmptyInstance();
rt_inst->pushExpressionRule(this->shared_from_this());
rt_inst->pushInst(elm_ast);
child_store->parse(rt_inst, stream);
auto tokens_decl = this->filter_proc(elm_ast->tokens());
elm_ast->tokensReset(tokens_decl);
rt_inst->popExpressionRule();
return rt_inst->popInst();
}
QString lib_syntax::ExpressionRule::token_present() const {
return QString(u8"(%1)").arg(child_store->token_present());
}