WsParser_VS/libSyntax/libsyntax.cpp

244 lines
7.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"
#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<std::shared_ptr<const IBasicRule>> TokenMatch::children() const { return QList<std::shared_ptr<const IBasicRule>>(); }
std::tuple<IBasicRule::MatchResult, std::shared_ptr<const IWordBase>> TokenMatch::parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const IWordBase> head) const {
if (!head) {
rt_inst->appendParseErrors(rt_inst->currentFile(), - 1, QString(u8"Syntax[0x0000]token流%1提前终止").arg(rt_inst->currentFile()));
return std::make_tuple(IBasicRule::MatchResult::Fail, head);
}
auto match_result = define_peer->analysis(head);
if (std::get<0>(match_result)) {
rt_inst->currentExprInst()->addToken(std::get<0>(match_result));
}
else {
rt_inst->appendParseErrors(rt_inst->currentFile(), head->position(),
QString(u8"Syntax[0x00001]语法匹配错误不能识别token\"%1\"<row:%2,col:%3>(应该为:%4)")
.arg(head->content()).arg(head->row()).arg(head->column()).arg(this->define_peer->reviseWords()));
return std::make_tuple(IBasicRule::MatchResult::Part, head);
}
if (std::get<1>(match_result)) {
return std::make_tuple(IBasicRule::MatchResult::Success, std::make_shared<WordImpl>(std::get<1>(match_result), head->nextWord()));
}
else {
return std::make_tuple(IBasicRule::MatchResult::Success, head->nextWord());
}
}
QString TokenMatch::token_present() const {
return QString(u8"<%1>").arg(this->define_peer->reviseWords());
}
Rept::Rept(std::shared_ptr<const IBasicRule> rule, int min, int max) : rule_peer(rule), min_match(min), max_match(max) {}
QList<std::shared_ptr<const IBasicRule>> Rept::children() const { return QList<std::shared_ptr<const IBasicRule>>() << rule_peer; }
std::tuple<IBasicRule::MatchResult, std::shared_ptr<const IWordBase>> Rept::parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const IWordBase> 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);
switch (std::get<0>(result_gen)) {
case IBasicRule::MatchResult::Fail:
return std::make_tuple(IBasicRule::MatchResult::Part, temp_head);
case IBasicRule::MatchResult::Part:
return std::make_tuple(IBasicRule::MatchResult::Part, std::get<1>(result_gen));
default:
temp_head = std::get<1>(result_gen);
break;
}
}
// max-match
for (auto idx = min_match; idx < max_match; ++idx) {
if (!temp_head)
break;
auto result_gen = rule_peer->parse(rt_inst, temp_head);
switch (std::get<0>(result_gen)) {
case IBasicRule::MatchResult::Fail:
case IBasicRule::MatchResult::Part:
return std::make_tuple(IBasicRule::MatchResult::Success, temp_head);
default:
temp_head = std::get<1>(result_gen);
break;
}
}
return std::make_tuple(IBasicRule::MatchResult::Success, 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 IBasicRule>> mbrs) : mbrs_store(mbrs) {}
QList<std::shared_ptr<const IBasicRule>> Seqs::children() const { return mbrs_store; }
std::tuple<IBasicRule::MatchResult, std::shared_ptr<const IWordBase>> Seqs::parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const IWordBase> head) const {
auto temp_head = head;
for (auto& r : mbrs_store) {
auto rst_gene = r->parse(rt_inst, temp_head);
switch (std::get<0>(rst_gene)) {
case IBasicRule::MatchResult::Fail:
return std::make_tuple(IBasicRule::MatchResult::Part, temp_head);
case IBasicRule::MatchResult::Part:
return rst_gene;
case IBasicRule::MatchResult::Success:
temp_head = std::get<1>(rst_gene);
break;
default:
break;
}
}
return std::make_tuple(IBasicRule::MatchResult::Success, 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<IBasicRule::MatchResult, uint, std::shared_ptr<const IBasicRule>, std::shared_ptr<const Token>>
Any::Any(const QList<std::shared_ptr<const IBasicRule>> mbrs) : mbrs_store(mbrs) {}
QList<std::shared_ptr<const IBasicRule>> Any::children() const { return mbrs_store; }
class words_span {
public:
int row_span, column_span;
words_span(int rspan, int cspan) :row_span(rspan), column_span(cspan) {}
bool operator>(const words_span& other) {
if (row_span > other.row_span)
return true;
if (row_span == other.row_span)
return column_span > other.column_span;
return false;
}
};
std::tuple<IBasicRule::MatchResult, std::shared_ptr<const IWordBase>> Any::parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const IWordBase> head) const {
std::tuple<std::shared_ptr<const IBasicRule>, uint64_t> temp_result = std::make_tuple(nullptr, 0);
auto rule_present = this->token_present();
for (auto& fork : mbrs_store) {
auto gen = fork->parse(rt_inst, head);
switch (std::get<0>(gen)) {
// 遇到成功的直接返回解析结果
case IBasicRule::MatchResult::Success:
return gen;
case IBasicRule::MatchResult::Fail: {
if (!std::get<0>(temp_result))
temp_result = std::make_tuple(fork, 0);
}break;
case IBasicRule::MatchResult::Part: {
auto span = std::get<1>(gen)->position() - head->position();
if (span >= std::get<1>(temp_result))
temp_result = std::make_tuple(fork, span);
}
default:
break;
}
}
// 分析最匹配的分支
rt_inst->clearErrors(rt_inst->currentFile(), head->position());
auto temp = std::get<0>(temp_result)->parse(rt_inst, head);
return std::make_tuple(IBasicRule::MatchResult::Part, std::get<1>(temp));
}
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; }
ExprRule::ExprRule(const QString& rule_name, int expr_mark) : name_store(rule_name) {
this->mark_store = expr_mark;
}
std::shared_ptr<const ExprRule> ExprRule::reloadRule(std::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<std::shared_ptr<const IBasicRule>> ExprRule::children() const {
return QList<std::shared_ptr<const IBasicRule>>() << this->child_store;
}
#include <ast_novel.h>
std::tuple<IBasicRule::MatchResult, std::shared_ptr<const IWordBase>>
ExprRule::parse(std::shared_ptr<IContext> rt_inst, std::shared_ptr<const IWordBase> head) const {
std::shared_ptr<IExprInst> elm_ast = this->newEmptyInstance();
auto text_present = this->token_present();
rt_inst->pushExprRule(this->shared_from_this());
rt_inst->pushExprInst(elm_ast);
auto rstg = child_store->parse(rt_inst, head);
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 = tokens_decl.first()->position();
rt_inst->clearErrors(rt_inst->currentFile(), start_pos);
}
rt_inst->popExprInst();
rt_inst->popExprRule();
if (rt_inst->currentExprInst()) {
rt_inst->currentExprInst()->addChild(elm_ast);
}
else {
rt_inst->appendDoc(elm_ast);
}
}break;
default:
break;
}
return rstg;
}
QString ExprRule::token_present() const {
return child_store->token_present();
}