WsParser_VS/libSyntax/libsyntax.cpp

252 lines
8.7 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);
}
QList<std::shared_ptr<const TokenNode>> TokenMatch::parse(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())
return QList<std::shared_ptr<const ast_basic::TokenNode>>() << std::make_shared<const TokenNodeImpl>(stream.first());
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);
}
QList<std::shared_ptr<const TokenNode>> Rept::parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
QList<std::shared_ptr<const TokenNode>> list_retvs;
auto token_offset = 0;
// min-match
for (auto idx = 0; idx < min_match; ++idx) {
auto result = rule_peer->match(stream.mid(token_offset));
list_retvs.append(rule_peer->parse(stream.mid(token_offset)));
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 list_retvs;
default:
break;
}
list_retvs.append(rule_peer->parse(stream.mid(token_offset)));
token_offset += std::get<1>(result);
}
return list_retvs;
}
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);
}
QList<std::shared_ptr<const TokenNode>> Seqs::parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
QList<std::shared_ptr<const TokenNode>> list_retv;
auto token_offset = 0;
for (auto& r : mbrs_store) {
list_retv.append(r->parse(stream.mid(token_offset)));
auto result = r->match(stream.mid(token_offset));
token_offset += std::get<1>(result);
}
return list_retv;
}
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));
}
QList<std::shared_ptr<const TokenNode>> Any::parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto temp = rule_select(stream);
return std::get<2>(temp)->parse(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")";
}
ExprRule::ExprRule(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 ExprRule> ExprRule::reloadRule(std::function<TokenSeqs(const TokenSeqs&)> filter, std::shared_ptr<const BaseRule> rule) {
auto ninst = std::make_shared<ExprRule>(this->name(), this->typeMark());
ninst->child_store = rule;
ninst->filter_proc = filter;
return ninst;
}
QString ExprRule::name() const { return name_store; }
int ExprRule::typeMark() const { return this->mark_store; }
QList<std::shared_ptr<const BaseRule>> ExprRule::children() const { return QList<std::shared_ptr<const BaseRule>>() << this->child_store; }
std::tuple<BaseRule::MatchResult, uint> ExprRule::match(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
return child_store->match(stream);
}
QList<std::shared_ptr<const TokenNode>> ExprRule::parse(const QList<std::shared_ptr<const lib_token::Token>>& stream) const {
auto primary_tokens = child_store->parse(stream);
auto remains_tokens = this->filter_proc(primary_tokens);
return QList<std::shared_ptr<const TokenNode>>() << ExprNodeImpl(shared_from_this()).filledWith(remains_tokens);
}
QString ExprRule::token_present() const
{
return QString(u8"(%1)").arg(child_store->token_present());
}
SyntaxException::SyntaxException(const QString& message) { this->msg_store = message; }
QString SyntaxException::message() const { return msg_store; }
ExprsChecker::ExprsChecker(std::shared_ptr<const ExprRule> parse_tree) : syntax_tree_root(parse_tree) {}
QList<std::shared_ptr<const TokenNode>> ExprsChecker::parseFrom(const QList<std::shared_ptr<const lib_token::Token>>& all_tokens) {
if (!all_tokens.size())
return QList<std::shared_ptr<const TokenNode>>();
return this->syntax_tree_root->parse(all_tokens);
}