#include "syntax_foundation.h" #include "lex_foundation.h" using namespace SyntaxX; using namespace Ast; void *TokenRule::operator new(size_t s) { auto ins = ::operator new(s); static_cast(ins)->build_within_heap = true; return ins; } TokenRule::TokenRule(const Lex::TokenDef &def) : token_type(def) {} BaseRule *TokenRule::toHeap() && { auto ins = new TokenRule(this->token_type); return ins; } bool TokenRule::heapMark() const { return build_within_heap; } QPair TokenRule::match(Lex::TokenReader *port, uint start, uint count) const noexcept { auto target = port->tokenPeak(start); if (target->def()->typeName() == this->token_type.typeName()) return qMakePair(1, Result::All); return qMakePair(0, Result::Fail); } void TokenRule::parse(Lex::TokenReader *port, Ast::ASTList *parent) { auto token = port->read(); auto leaf = new ASTLeaf(parent, token); parent->insert(parent->count(), leaf); } Repeat::Repeat(BaseRule *item, uint min, uint max) : item_store(*item), match_max(max), match_min(min) { if (match_min < 1 || match_min >= match_max) throw new Lex::WsBaseException("匹配参数错误:匹配次数参数设置错误"); } Repeat::Repeat(BaseRule &&item, uint min, uint max) : Repeat(&item, min, max) {} void *Repeat::operator new(size_t s) { auto ins = ::operator new(s); static_cast(ins)->build_within_heap = true; return ins; } BaseRule *Repeat::toHeap() && { return new Repeat(&this->item_store, match_max); } bool Repeat::heapMark() const { return this->build_within_heap; } QPair Repeat::match(Lex::TokenReader *port, uint start, uint count) const noexcept { return item_store.match(port, start, count); } void Repeat::parse(Lex::TokenReader *port, Ast::ASTList *parent) { auto repeat_times = 0; while (item_store.match(port, 0, UINT_MAX).second == Result::All) { item_store.parse(port, parent); repeat_times++; if (repeat_times == match_max) break; } if (repeat_times < match_min) throw new SyntaxException(*port->tokenPeak(0), "指定Token不符合Repeat语法定义"); } using namespace Lex; ElmRule::ElmRule() : item_store(nullptr) {} ElmRule::~ElmRule() { delete item_store; } void ElmRule::resetProcess(std::function exec) { this->exec_store = exec; } void ElmRule::parse(Lex::TokenReader *port, Ast::ASTList *parent) { auto result = this->exec_store(port, parent); parent->insert(parent->count(), result); this->item_store->parse(port, result); } BaseRule *ElmRule::toHeap() && { throw new WsBaseException("不允许ElmRule构建堆实例"); } bool ElmRule::heapMark() const { return false; } void ElmRule::setRule(BaseRule &&item) { this->item_store = std::move(item).toHeap(); } QPair ElmRule::match(Lex::TokenReader *port, uint start, uint count) const noexcept { return item_store->match(port, start, count); } Seqs::Seqs() {} Seqs::Seqs(Seqs &&other) { this->items_rule.append(other.items_rule); other.items_rule.clear(); } Seqs::~Seqs() { for (auto &it : items_rule) if (it->heapMark()) delete it; items_rule.clear(); } void *Seqs::operator new(size_t s) { auto ins = ::operator new(s); static_cast(ins)->build_within_heap = true; return ins; } BaseRule *Seqs::toHeap() && { auto ins = new Seqs(); ins->items_rule.append(this->items_rule); this->items_rule.clear(); return ins; } bool Seqs::heapMark() const { return this->build_within_heap; } QPair Seqs::match(Lex::TokenReader *port, uint start, uint count) const noexcept { auto m_len = 0; for (auto &it : items_rule) { auto next_count = count - m_len; if (next_count <= 0) return qMakePair(count, Result::Part); auto m_rst = it->match(port, start + m_len, next_count); if (m_rst.second == Result::All) { m_len += m_rst.first; } else { if (m_len + m_rst.first == 0) return qMakePair(0, Result::Fail); else return qMakePair(m_len + m_rst.first, Result::Part); } } return qMakePair(m_len, Result::All); } void Seqs::parse(Lex::TokenReader *port, Ast::ASTList *parent) { for (auto &it : items_rule) { if (it->match(port, 0, UINT32_MAX).second == Result::All) { it->parse(port, parent); } else { } } } Any::Any() {} Any::Any(Any &&other) { items_rule.append(other.items_rule); other.items_rule.clear(); } Any::~Any() { for (auto &it : items_rule) if (it->heapMark()) delete it; items_rule.clear(); } void *Any::operator new(size_t s) { auto ins = ::operator new(s); static_cast(ins)->build_within_heap = true; return ins; } BaseRule *Any::toHeap() && { auto ins = new Any(); ins->items_rule.append(this->items_rule); this->items_rule.clear(); return ins; } bool Any::heapMark() const { return this->build_within_heap; } QPair Any::match(Lex::TokenReader *port, uint start, uint count) const noexcept { auto match_rst = qMakePair(0, Result::Fail); for (auto &it : items_rule) { auto rst = it->match(port, start, count); if (rst.second == Result::All) return rst; if (rst.first > match_rst.first) { match_rst = rst; } } return match_rst; } void Any::parse(Lex::TokenReader *port, Ast::ASTList *parent) { auto match_rst = qMakePair(-1, items_rule.first()); for (auto &it : items_rule) { auto rst = it->match(port, 0, UINT32_MAX); if (rst.second == Result::All) { match_rst = qMakePair(rst.first, it); break; } if (rst.first > match_rst.first) { match_rst = qMakePair(rst.first, it); } } match_rst.second->parse(port, parent); } SyntaxException::SyntaxException(const Lex::Token &tins, const QString &simple) : Lex::WsBaseException(simple), target(tins) {} const Token &SyntaxException::targetToken() const { return this->target; } void *Optional::operator new(size_t s) { auto ins = ::operator new(s); static_cast(ins)->build_within_heap = true; return ins; } Optional::Optional(BaseRule *item) : item_store(*item) {} Optional::Optional(BaseRule &&item) : item_store(item) {} BaseRule *Optional::toHeap() && { return new Optional(&item_store); } bool Optional::heapMark() const { return build_within_heap; } QPair Optional::match(Lex::TokenReader *port, uint start, uint count) const noexcept { auto rst = item_store.match(port, start, count); if (rst.second != Result::All) return qMakePair(0, Result::All); return rst; } void Optional::parse(Lex::TokenReader *port, Ast::ASTList *parent) { if (this->match(port, 0, UINT32_MAX).second == Result::All) item_store.parse(port, parent); }