WsParser_VS/libSyntax/libsyntax.cpp

259 lines
9.2 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, std::shared_ptr<const Token>> TokenMatch::match(std::shared_ptr<const Token> remains_head) const {
QString token_seqs = this->token_present();
if (remains_head && remains_head->define()->name() == define_peer->name())
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)
throw new SyntaxException(u8"Syntax[0x0000]token流提前终止");
if (head->define()->name() == define_peer->name()) {
rt_inst->currentInst()->addToken(head);
return std::make_tuple(nullptr, head->nextToken());
}
throw new SyntaxException(QString(u8"Syntax[0x00001]语法匹配错误不能识别token%1<%2,%3>")
.arg(head->content()).arg(head->row()).arg(head->column()));
}
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, std::shared_ptr<const Token>> Rept::match(std::shared_ptr<const Token> list_head) const {
auto token_offset = 0;
QString token_seqs = this->token_present();
auto temp_head = list_head;
// min-match
for (auto idx = 0; idx < min_match; ++idx) {
auto result = rule_peer->match(temp_head);
token_offset += std::get<1>(result);
temp_head = std::get<2>(result);
if (std::get<0>(result) != MatchResult::Success) {
return std::make_tuple(token_offset ? MatchResult::Part : MatchResult::Fail, token_offset, temp_head);
}
}
// max-match
for (auto idx = min_match; idx < max_match; ++idx) {
auto result = rule_peer->match(temp_head);
switch (std::get<0>(result)) {
case MatchResult::Fail:
case MatchResult::Part:
return std::make_tuple(MatchResult::Success, token_offset, temp_head);
default:
temp_head = std::get<2>(result);
token_offset += std::get<1>(result);
break;
}
}
return std::make_tuple(MatchResult::Success, token_offset, temp_head);
}
std::tuple<std::shared_ptr<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;
// min-match
for (auto idx = 0; idx < min_match; ++idx) {
auto result_gen = rule_peer->parse(rt_inst, temp_head);
if (std::get<0>(result_gen))
rt_inst->currentInst()->addChild(std::get<0>(result_gen));
temp_head = std::get<1>(result_gen);
}
// max-match
for (auto idx = min_match; idx < max_match; ++idx) {
try {
auto result_gen = rule_peer->parse(rt_inst, temp_head);
if (std::get<0>(result_gen))
rt_inst->currentInst()->addChild(std::get<0>(result_gen));
temp_head = std::get<1>(result_gen);
}
catch (...) {
return std::make_tuple(nullptr, temp_head);
}
}
return std::make_tuple(nullptr, temp_head);
}
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, std::shared_ptr<const Token>> Seqs::match(std::shared_ptr<const Token> list_head) const {
auto token_offset = 0;
QString token_seqs = this->token_present();
auto temp_head = list_head;
for (auto& r : mbrs_store) {
auto v_token_seqs = r->token_present();
auto result = r->match(list_head);
token_offset += std::get<1>(result);
temp_head = std::get<2>(result);
switch (std::get<0>(result)) {
case MatchResult::Fail:
case MatchResult::Part:
return std::make_tuple(token_offset ? MatchResult::Part : MatchResult::Fail, token_offset, temp_head);
default:
break;
}
}
return std::make_tuple(MatchResult::Success, token_offset, temp_head);
}
std::tuple<std::shared_ptr<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;
for (auto& r : mbrs_store) {
auto rst_gene = r->parse(rt_inst, temp_head);
temp_head = std::get<1>(rst_gene);
if (std::get<0>(rst_gene))
rt_inst->currentInst()->addChild(std::get<0>(rst_gene));
}
return std::make_tuple(nullptr, temp_head);
}
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>, 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) {}
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 {
auto item = rule_select(list_head);
return std::make_tuple(std::get<0>(item), std::get<1>(item), std::get<3>(item));
}
std::tuple<std::shared_ptr<const Expression>, std::shared_ptr<const Token>> Any::parse(std::shared_ptr<ParseContext> rt_inst, std::shared_ptr<const Token> head) const {
auto temp = rule_select(head);
return std::get<2>(temp)->parse(rt_inst, head);
}
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; }
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> 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 ExpressionRule::name() const { return name_store; }
int ExpressionRule::typeMark() const { return this->mark_store; }
QList<std::shared_ptr<const BaseRule>> ExpressionRule::children() const {
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 {
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<ast_basic::Expression> elm_ast = this->newEmptyInstance();
rt_inst->pushExpressionRule(this->shared_from_this());
rt_inst->pushInst(elm_ast);
auto rstg = child_store->parse(rt_inst, head);
auto tokens_decl = this->filter_proc(elm_ast->tokens());
elm_ast->tokensReset(tokens_decl);
rt_inst->popExpressionRule();
return std::make_tuple(rt_inst->popInst(), std::get<1>(rstg));
}
QString ExpressionRule::token_present() const {
return QString(u8"(%1)").arg(child_store->token_present());
}