WsParser_VS/libSyntax/ast_gen.cpp

143 lines
5.1 KiB
C++
Raw Normal View History

2024-03-17 07:58:28 +00:00
#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; }