WsParser_VS/libSyntax/libsyntax.cpp

274 lines
7.3 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 <tuple>
#include <QDebug>
using namespace lib_syntax;
using namespace std;
using namespace lib_token;
using namespace lib_words;
using namespace ast_basic;
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;
}
QList<std::shared_ptr<const MatchCursor>> Any::parse(std::shared_ptr<const MatchCursor> cursor) const {
if (cursor->mustStop())
return QList<std::shared_ptr<const MatchCursor>>() << cursor;
QList<std::shared_ptr<const MatchCursor>> result_list;
for (auto rx : this->children())
result_list.append(rx->parse(cursor));
return result_list;
}
QString Any::present() const {
QString members_content;
for (auto& it : children()) {
members_content += it->present() + u8"|";
}
return members_content.mid(0, members_content.size() - 1);
}
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;
}
QList<std::shared_ptr<const MatchCursor>> Seqs::parse(std::shared_ptr<const MatchCursor> cursor) const {
if (cursor->mustStop())
return QList<std::shared_ptr<const MatchCursor>>() << cursor;
QList<std::shared_ptr<const MatchCursor>> results;
QList<std::shared_ptr<const MatchCursor>> bridge_list{ cursor };
for (auto rule : this->children()) {
QList<std::shared_ptr<const MatchCursor>> current_result;
std::for_each(bridge_list.begin(), bridge_list.end(),
[&](std::shared_ptr<const MatchCursor> vcurs) {
if (vcurs->mustStop())
results.push_back(vcurs);
else {
current_result.append(rule->parse(vcurs));
}
});
bridge_list = current_result;
}
results.append(bridge_list);
return results;
}
QString Seqs::present() const {
QString content;
for (auto& it : children())
content += it->present() + " ";
return content.mid(0, content.size() - 1);
}
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;
}
QList<std::shared_ptr<const MatchCursor>> Rept::parse(std::shared_ptr<const MatchCursor> cursor) const {
if (cursor->mustStop())
return QList<std::shared_ptr<const MatchCursor>>() << cursor;
QList<std::shared_ptr<const MatchCursor>> results;
QList<std::shared_ptr<const MatchCursor>> bridge_list{ cursor };
// <20><>С<EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
for (auto idx = 0; idx < min_match; ++idx) {
QList<std::shared_ptr<const MatchCursor>> current_list;
// <20><><EFBFBD><EFBFBD>ÿһ<C3BF>ο<EFBFBD><CEBF><EFBFBD>ƥ<EFBFBD><C6A5>
std::for_each(bridge_list.begin(), bridge_list.end(),
[&](std::shared_ptr<const MatchCursor> curs) {
if (curs->mustStop())
results.push_back(curs);
else {
current_list.append(this->rule_peer->parse(curs));
}
});
bridge_list = current_list;
}
// <20>鲢ʧ<E9B2A2>ܷ<EFBFBD>֧
std::copy_if(bridge_list.begin(), bridge_list.end(), std::back_inserter(results),
[&](std::shared_ptr<const MatchCursor> ins) { return ins->mustStop(); });
// <20><><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>ʧ<EFBFBD>ܷ<EFBFBD>֧
for (auto idx = 0; idx < bridge_list.size(); ++idx)
if (bridge_list.at(idx)->mustStop())
bridge_list.removeAt(idx--);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сƥ<D0A1><C6A5>
if (!bridge_list.size())
return results;
// <20><><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD>ƥ<EFBFBD><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (auto idx = min_match; idx < max_match; ++idx) {
QList<std::shared_ptr<const MatchCursor>> current_list;
// ƥ<><C6A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>
std::for_each(bridge_list.begin(), bridge_list.end(),
[&](std::shared_ptr<const MatchCursor> ins) {
current_list.append(this->rule_peer->parse(ins));
});
// <20>Ƴ<EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD>֧
for (auto idx = 0; idx < current_list.size(); ++idx) {
auto rst_branch = current_list.at(idx);
if (rst_branch->mustStop() && rst_branch->currentWords()) {
results.append(rst_branch->previous());
current_list.removeAt(idx--);
}
if (rst_branch->mustStop() && !rst_branch->currentWords()) {
results.append(rst_branch);
current_list.removeAt(idx--);
}
}
if (!current_list.size())
break;
bridge_list = current_list;
}
results.append(bridge_list);
return results;
}
QString Rept::present() const {
if (min_match == 0 && max_match == INT_MAX)
return u8"(" + this->rule_peer->present() + QString(u8")*");
else if (min_match == 1 && max_match == INT_MAX)
return u8"(" + this->rule_peer->present() + QString(u8")+");
else if (min_match == 0 && max_match == 1)
return u8"(" + this->rule_peer->present() + QString(u8")?");
return u8"(" + this->rule_peer->present() + QString(u8"){%1, %2}").arg(min_match).arg(max_match);
}
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), mark_store(expr_mark) { }
std::shared_ptr<const ExprRule> ExprRule::reloadRule(std::shared_ptr<const IBasicRule> rule) const {
auto ninst = this->make_copy();
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>
QString ExprRule::present() const {
return child_store->present();
}
MatchCursor::MatchCursor(const QString& path) :_file_path(path) { }
MatchCursor::MatchCursor(std::shared_ptr<const MatchCursor> other_ptr)
: _prev_cursor(other_ptr),
_file_path(other_ptr->_file_path),
_total_errors(other_ptr->_total_errors),
_exprs_errors(other_ptr->_exprs_errors),
_current_token(other_ptr->_current_token),
_remains_word(other_ptr->_remains_word) { }
std::shared_ptr<const MatchCursor> MatchCursor::previous() const {
return _prev_cursor;
}
QString MatchCursor::filePath() const {
return _file_path;
}
void MatchCursor::enterExprs() {
auto new_expr = std::make_shared<ErrsPack>();
this->_exprs_errors.push_back(new_expr);
}
void MatchCursor::logExprsError(const QString& msg) {
this->_total_errors.push_back(msg);
this->_exprs_errors.last()->addError(msg);
}
void MatchCursor::quitExprs() {
this->_exprs_errors.pop_back();
}
bool MatchCursor::mustStop() const {
return exprsErrorCount() >= 2 || parse_stop();
}
int MatchCursor::exprsErrorCount() const {
if (this->_exprs_errors.size())
return this->_exprs_errors.last()->errorCount();
return 0;
}
int MatchCursor::totalErrorCount() const {
return this->_total_errors.size();
}
QList<QString> MatchCursor::totalErrors() const {
return this->_total_errors;
}
void MatchCursor::setCurrent(std::shared_ptr<const IActionToken> t, std::shared_ptr<const IPrimitiveWord> remains) {
this->_current_token = t;
this->_remains_word = remains;
}
std::shared_ptr<const IActionToken> MatchCursor::currentToken() const {
return this->_current_token;
}
std::shared_ptr<const IPrimitiveWord> MatchCursor::currentWords() const {
return this->_remains_word;
}
bool lib_syntax::MatchCursor::parse_stop() const {
return !currentWords();
}
void MatchCursor::ErrsPack::addError(const QString& msg) {
this->_error_collection.append(msg);
}
QList<QString> MatchCursor::ErrsPack::errors() const {
return _error_collection;
}
uint64_t MatchCursor::ErrsPack::errorCount() const {
return _error_collection.size();
}