WsParser_VS/libSyntax/ast_gen.cpp

143 lines
5.1 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 "ast_gen.h"
using namespace ast_gen;
ExprTreeParser::ExprTreeParser(std::shared_ptr<const ExprVisitor> vistor) : visitor_store(vistor) {}
typedef std::shared_ptr<const SyntaxElement> E;
typedef QList<std::shared_ptr<const SyntaxElement>> Es;
typedef std::shared_ptr<const ast_basic::ExprNode> Expr;
QList<std::shared_ptr<const SyntaxElement>> ExprTreeParser::parse(const QString& name,
const QList<std::shared_ptr<const ast_basic::ExprNode>>& forest) const {
std::function<Es(Expr, E)> visit_loop = [&](Expr n, E p) -> Es {
QList<std::shared_ptr<const SyntaxElement>> temp_list;
auto node = this->visitor_store->visit(n, p);
if (node)
temp_list.append(node);
for (auto& it : n->exprNodes()) {
temp_list.append(visit_loop(it, node));
}
return temp_list;
};
QList<std::shared_ptr<const SyntaxElement>> temp_list;
auto root = std::make_shared<GlobalElement>(name);
temp_list << root;
for (auto& tree : forest) {
temp_list.append(visit_loop(tree, root));
}
return temp_list;
}
std::shared_ptr<const ElementAccess> ExprTreeParser::tidy(const QList<std::shared_ptr<const SyntaxElement>>& nodes) const {
auto temp = nodes.first();
while (temp->parent()) {
temp = temp->parent();
}
auto core_cache = std::static_pointer_cast<GlobalElement>(std::const_pointer_cast<SyntaxElement>(temp));
core_cache->clearCache();
for (auto& it : nodes) {
if (!it->isAnonymous()) {
core_cache->appendToCache(it);
}
}
auto root = std::make_shared<ElementAccess>(temp);
for (auto& node : nodes)
tidy_branch(root, node);
return root;
}
void ExprTreeParser::tidy_branch(std::shared_ptr<ElementAccess> root, std::shared_ptr<const SyntaxElement> node) const {
QList<std::shared_ptr<const SyntaxElement>> link;
while (node) {
link.prepend(node);
node = node->parent();
}
std::function<void(std::shared_ptr<ElementAccess> pnode, QList<std::shared_ptr<const SyntaxElement>>)> merge =
[&](std::shared_ptr<ElementAccess> pnode, QList<std::shared_ptr<const SyntaxElement>> remains) {
if (!remains.size())
return;
auto current = remains.first();
for (auto& c_a : pnode->children()) {
if (c_a->element() == current) {
merge(std::const_pointer_cast<ElementAccess>(c_a), remains.mid(1));
return;
}
}
auto new_branch = std::make_shared<ElementAccess>(current);
pnode->appendChild(new_branch);
if (remains.size() > 1)
merge(new_branch, remains.mid(1));
};
merge(root, link.mid(1));
}
GlobalElement::GlobalElement(const QString& name) :names_store(name) {}
void GlobalElement::clearCache() { node_cache.clear(); }
void GlobalElement::appendToCache(std::shared_ptr<const SyntaxElement> named_node) {
auto mixed_key = QString(u8"%1<%2>").arg(named_node->signature()).arg(named_node->typeMark());
if (node_cache.contains(mixed_key))
throw new lib_syntax::SyntaxException(
QString(u8"Parse[0x0004]ϵͳ<CFB5>а<EFBFBD><D0B0><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ㣺%1<type<70><65>%2>").arg(named_node->signature()).arg(named_node->typeMark()));
node_cache[mixed_key] = named_node;
}
std::shared_ptr<const SyntaxElement> GlobalElement::getNamedNodeBy(int type, const QString& signature) const {
auto mixed_key = QString(u8"%1<%2>").arg(signature).arg(type);
if (!node_cache.contains(mixed_key))
throw new lib_syntax::SyntaxException(QString(u8"Parse[0x0005]ϵͳ<CFB5>в<EFBFBD><D0B2><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>ǩ<EFBFBD><C7A9><EFBFBD>Ľڵ㣺%1<type<70><65>%2>").arg(signature).arg(type));
return node_cache[mixed_key];
}
int GlobalElement::typeMark() const { return 0; }
bool ast_gen::GlobalElement::isAnonymous() const { return true; }
QString GlobalElement::signature() const { return u8"::global"; }
QString GlobalElement::path() const { return u8""; }
std::shared_ptr<const SyntaxElement> GlobalElement::parent() const { return nullptr; }
QList<std::shared_ptr<const TokenAccess>> GlobalElement::selfTokens() const { return QList<std::shared_ptr<const TokenAccess>>(); }
ElementAccess::ElementAccess(std::shared_ptr<const SyntaxElement> point) { peers = point; }
std::shared_ptr<const SyntaxElement> ElementAccess::element() const { return peers; }
QList<std::shared_ptr<const ElementAccess>> ElementAccess::children() const { return children_store; }
void ElementAccess::appendChild(std::shared_ptr<const ElementAccess> inst) { children_store.append(inst); }
QList<std::shared_ptr<const TokenAccess>> ElementAccess::tokens() const {
QList<std::shared_ptr<const TokenAccess>> tokens_retv;
tokens_retv.append(element()->selfTokens());
for (auto& it : children()) {
tokens_retv.append(it->tokens());
}
return tokens_retv;
}
TokenAccess::TokenAccess(std::shared_ptr<const SyntaxElement> elm_inst, std::shared_ptr<const lib_token::Token> token_inst)
: element_bind(elm_inst), token_store(token_inst) {}
std::shared_ptr<const SyntaxElement> TokenAccess::bind() const { return element_bind; }
std::shared_ptr<const lib_token::Token> TokenAccess::token() const { return token_store; }