#include <ASTSymbolTableBuilder.hpp> #include <SymbolTable.hpp> #include <PEGGrammar.hpp> void ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>& symbol_table) { if (n.is<language::bloc>() or (n.is<language::for_statement>())) { if (!n.children.empty()) { std::shared_ptr bloc_symbol_table = std::make_shared<SymbolTable>(symbol_table); n.m_symbol_table = bloc_symbol_table; for (auto& child : n.children) { this->buildSymbolTable(*child, bloc_symbol_table); } } } else { n.m_symbol_table = symbol_table; if (n.has_content()) { if (n.is<language::declaration>()) { const std::string& symbol = n.children[1]->string(); auto [i_symbol, success] = symbol_table->add(symbol); if (not success) { std::ostringstream error_message; error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << '\'' << " was already defined!"; throw parse_error(error_message.str(), std::vector{n.begin()}); } } else if (n.is<language::name>()) { auto [i_symbol, found] = symbol_table->find(n.string()); if (not found) { std::ostringstream error_message; error_message << "undefined symbol '" << rang::fg::red << n.string() << rang::fg::reset << '\''; throw parse_error(error_message.str(), std::vector{n.begin()}); } } } for (auto& child : n.children) { this->buildSymbolTable(*child, symbol_table); } } } ASTSymbolTableBuilder::ASTSymbolTableBuilder(ASTNode& node) { Assert(node.is_root()); std::shared_ptr symbol_table = std::make_shared<SymbolTable>(); node.m_symbol_table = symbol_table; this->buildSymbolTable(node, symbol_table); std::cout << " - checked symbols declaration\n"; }