WsParser_VS/libSyntax/libsyntax.cpp

384 lines
11 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"
#include <QDebug>
using namespace lib_syntax;
using namespace std;
using namespace lib_token;
using namespace ast_basic;
TokenMatch::TokenMatch(shared_ptr<const ITokenDefine> define) : define_peer(define) {}
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
{
if (!head) {
rt_inst->appendParseError(rt_inst->currentFile(), -1, QString(u8"Syntax[0x0000]token流%1提前终止").arg(rt_inst->currentFile()));
return ParseResult();
}
ParseResult result_ret;
auto match_result = define_peer->analysis(head);
if (get<0>(match_result)) {
rt_inst->currentExprInst()->addToken(get<0>(match_result));
decltype(result_ret.result_repair) v_result;
if (get<1>(match_result)) {
v_result = make_tuple(MatchResult::Success, make_shared<WordImpl>(get<1>(match_result), head->nextWord()));
}
else {
v_result = make_tuple(MatchResult::Success, head->nextWord());
}
if (fx_type == ErrDeals::None)
result_ret.result_straight = v_result;
else
result_ret.result_repair = v_result;
}
else {
switch (fx_type) {
case lib_syntax::ErrDeals::Replace:
fx_type = ErrDeals::None;
result_ret.result_repair = make_tuple(MatchResult::Success, head->nextWord());
rt_inst->appendParseError(rt_inst->currentFile(), head->position(), QString(u8"指定Token<row:%3,col:%4>“%1”匹配错误应为“%2”。")
.arg(head->content()).arg(this->define_peer->reviseWords()).arg(head->row()).arg(head->column()));
break;
case lib_syntax::ErrDeals::Absence:
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”。")
.arg(this->define_peer->reviseWords()).arg(head->row()).arg(head->column()));
break;
case lib_syntax::ErrDeals::Surplus:
fx_type = ErrDeals::None;
{
auto temp_head = head->nextWord();
auto match_result = define_peer->analysis(temp_head);
if (get<0>(match_result)) {
rt_inst->appendParseError(rt_inst->currentFile(), head->position(), QString(u8"发现冗余Token<row:%2,col:%3>,内容为“%1”。")
.arg(head->content()).arg(head->row()).arg(head->column()));
rt_inst->currentExprInst()->addToken(get<0>(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()));
else
result_ret.result_repair = make_tuple(MatchResult::Success, temp_head->nextWord());
}
else {
result_ret.result_repair = make_tuple(MatchResult::Part, head);
}
}
break;
default:
result_ret.result_straight = make_tuple(MatchResult::Part, head);
break;
}
}
return result_ret;
}
QString TokenMatch::token_present() const {
return QString(u8"%1 ").arg(this->define_peer->reviseWords());
}
Rept::Rept(shared_ptr<const IBasicRule> rule, int min, int max) : rule_peer(rule), min_match(min), max_match(max) {}
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 {
ParseResult fnl_result;
auto temp_head = head;
auto initial_fxtype = ErrDeals::None;
retry_entry:
switch (initial_fxtype) {
case lib_syntax::ErrDeals::Surplus:
case lib_syntax::ErrDeals::Absence:
case lib_syntax::ErrDeals::Replace:
break;
case lib_syntax::ErrDeals::None:
// 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
for (auto idx = min_match; idx < max_match; ++idx) {
if (!temp_head)
break;
auto result_genx = rule_peer->parse(rt_inst, temp_head, initial_fxtype);
auto v_result = result_genx.result_straight;
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;
}
}
break;
default:
break;
}
if(straight_flags)
fnl_result.result_straight = make_tuple(MatchResult::Success, temp_head);
else
fnl_result.result_repair = make_tuple(MatchResult::Success, temp_head);
fx_type = initial_fxtype;
return fnl_result;
}
QString Rept::token_present() const
{
return u8"(" + this->rule_peer->token_present() + QString(u8"){%1, %2}").arg(min_match).arg(max_match);
}
Seqs::Seqs(const QList<shared_ptr<const IBasicRule>> mbrs) : mbrs_store(mbrs) {}
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 {
ParseResult result_final;
auto temp_head = head;
bool straight_mark = fx_type == ErrDeals::None;
for (auto& r : mbrs_store) {
auto rule_present = r->token_present();
auto rst_gene = r->parse(rt_inst, temp_head, fx_type);
auto v_result = rst_gene.result_straight;
if (std::get<0>(v_result) == MatchResult::None)
v_result = rst_gene.result_repair;
switch (get<0>(v_result)) {
case MatchResult::Part:
if (straight_mark)
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;
default:
break;
}
}
if (straight_mark)
result_final.result_straight = make_tuple(MatchResult::Success, temp_head);
else
result_final.result_repair = make_tuple(MatchResult::Success, temp_head);
return result_final;
}
QString Seqs::token_present() const
{
QString content;
for (auto& it : children())
content += it->token_present();
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) {}
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 {
auto rule_present = this->token_present();
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) {
auto xgen = fork->parse(rt_inst, head, fx_type);
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:
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;
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 members_content;
for (auto& it : children()) {
members_content += it->token_present() + u8"|";
}
return members_content.mid(0, members_content.size() - 1);
}
SyntaxException::SyntaxException(const QString& message) { this->msg_store = message; }
QString SyntaxException::message() const { return msg_store; }
ExprRule::ExprRule(const QString& rule_name, int expr_mark) : name_store(rule_name) {
this->mark_store = expr_mark;
}
shared_ptr<const ExprRule> ExprRule::reloadRule(shared_ptr<const IBasicRule> rule) {
auto ninst = makeCopy();
ninst->child_store = rule;
return ninst;
}
QString ExprRule::name() const { return name_store; }
int ExprRule::typeMark() const { return this->mark_store; }
QList<shared_ptr<const IBasicRule>> ExprRule::children() const {
return QList<shared_ptr<const IBasicRule>>() << this->child_store;
}
#include <ast_novel.h>
tuple<MatchResult, shared_ptr<const IWordBase>>
ExprRule::parse(shared_ptr<IContext> rt_inst, shared_ptr<const IWordBase> head, ErrDeals& fx_type) const {
auto text_present = this->token_present();
shared_ptr<IExprInst> elm_ast = this->newEmptyInstance();
rt_inst->pushExprRule(this->shared_from_this());
rt_inst->pushExprInst(elm_ast);
auto ret_tuple = child_store->parse(rt_inst, head, fx_type);
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();
rt_inst->popExprRule();
if (rt_inst->currentExprInst()) {
rt_inst->currentExprInst()->addChild(elm_ast);
}
else {
rt_inst->appendDocInst(elm_ast);
}
break;
case MatchResult::Part:
case MatchResult::Fail:
rt_inst->popExprInst();
rt_inst->popExprRule();
break;
default:
break;
}
return ret_tuple;
}
QString ExprRule::token_present() const {
return child_store->token_present();
}