Skip to content
Snippets Groups Projects
Commit 9cb762eb authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Create ASTSymbolTableBuilder

replaces build_symbol_table_and_check_declarations function in view of code clean-up
parent d35b98ed
No related branches found
No related tags found
1 merge request!37Feature/language
#include <ASTSymbolTableBuilder.hpp>
#include <SymbolTable.hpp>
#include <PEGGrammar.hpp>
namespace language
{
void
ASTSymbolTableBuilder::buildSymbolTable(Node& 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(Node& 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";
}
} // namespace language
#ifndef AST_SYMBOL_TABLE_BUILDER_HPP
#define AST_SYMBOL_TABLE_BUILDER_HPP
#include <ASTNode.hpp>
namespace language
{
class SymbolTable;
class ASTSymbolTableBuilder
{
private:
void buildSymbolTable(Node& node, std::shared_ptr<SymbolTable>& symbol_table);
public:
ASTSymbolTableBuilder(Node& root_node);
ASTSymbolTableBuilder(const ASTSymbolTableBuilder&) = delete;
~ASTSymbolTableBuilder() = default;
};
} // namespace language
#endif // AST_SYMBOL_TABLE_BUILDER_HPP
...@@ -13,6 +13,7 @@ add_library( ...@@ -13,6 +13,7 @@ add_library(
ASTNodeIncDecExpressionBuilder.cpp ASTNodeIncDecExpressionBuilder.cpp
ASTNodeUnaryOperatorExpressionBuilder.cpp ASTNodeUnaryOperatorExpressionBuilder.cpp
ASTPrinter.cpp ASTPrinter.cpp
ASTSymbolTableBuilder.cpp
PugsParser.cpp) PugsParser.cpp)
#include_directories(${PUGS_SOURCE_DIR}/utils) #include_directories(${PUGS_SOURCE_DIR}/utils)
......
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include <ASTNodeExpressionBuilder.hpp> #include <ASTNodeExpressionBuilder.hpp>
#include <ASTSymbolTableBuilder.hpp>
#include <ASTPrinter.hpp> #include <ASTPrinter.hpp>
namespace language namespace language
...@@ -65,56 +67,56 @@ print_dot(std::ostream& os, const Node& n) ...@@ -65,56 +67,56 @@ print_dot(std::ostream& os, const Node& n)
os << "}\n"; os << "}\n";
} }
namespace internal // namespace internal
{ // {
void // void
build_symbol_table_and_check_declarations(Node& n, std::shared_ptr<SymbolTable>& symbol_table) // build_symbol_table_and_check_declarations(Node& n, std::shared_ptr<SymbolTable>& symbol_table)
{ // {
if (n.is<language::bloc>() or (n.is<language::for_statement>())) { // if (n.is<language::bloc>() or (n.is<language::for_statement>())) {
if (!n.children.empty()) { // if (!n.children.empty()) {
std::shared_ptr bloc_symbol_table = std::make_shared<SymbolTable>(symbol_table); // std::shared_ptr bloc_symbol_table = std::make_shared<SymbolTable>(symbol_table);
n.m_symbol_table = bloc_symbol_table; // n.m_symbol_table = bloc_symbol_table;
for (auto& child : n.children) { // for (auto& child : n.children) {
build_symbol_table_and_check_declarations(*child, bloc_symbol_table); // build_symbol_table_and_check_declarations(*child, bloc_symbol_table);
} // }
} // }
} else { // } else {
n.m_symbol_table = symbol_table; // n.m_symbol_table = symbol_table;
if (n.has_content()) { // if (n.has_content()) {
if (n.is<language::declaration>()) { // if (n.is<language::declaration>()) {
const std::string& symbol = n.children[1]->string(); // const std::string& symbol = n.children[1]->string();
auto [i_symbol, success] = symbol_table->add(symbol); // auto [i_symbol, success] = symbol_table->add(symbol);
if (not success) { // if (not success) {
std::ostringstream error_message; // std::ostringstream error_message;
error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << '\'' << " was already defined!"; // error_message << "symbol '" << rang::fg::red << symbol << rang::fg::reset << '\'' << " was already
throw parse_error(error_message.str(), std::vector{n.begin()}); // defined!"; throw parse_error(error_message.str(), std::vector{n.begin()});
} // }
} else if (n.is<language::name>()) { // } else if (n.is<language::name>()) {
auto [i_symbol, found] = symbol_table->find(n.string()); // auto [i_symbol, found] = symbol_table->find(n.string());
if (not found) { // if (not found) {
std::ostringstream error_message; // std::ostringstream error_message;
error_message << "undefined symbol '" << rang::fg::red << n.string() << rang::fg::reset << '\''; // error_message << "undefined symbol '" << rang::fg::red << n.string() << rang::fg::reset << '\'';
throw parse_error(error_message.str(), std::vector{n.begin()}); // throw parse_error(error_message.str(), std::vector{n.begin()});
} // }
} // }
} // }
for (auto& child : n.children) { // for (auto& child : n.children) {
build_symbol_table_and_check_declarations(*child, symbol_table); // build_symbol_table_and_check_declarations(*child, symbol_table);
} // }
} // }
} // }
} // namespace internal // } // namespace internal
void // void
build_symbol_table_and_check_declarations(Node& n) // build_symbol_table_and_check_declarations(Node& n)
{ // {
Assert(n.is_root()); // Assert(n.is_root());
std::shared_ptr symbol_table = std::make_shared<SymbolTable>(); // std::shared_ptr symbol_table = std::make_shared<SymbolTable>();
n.m_symbol_table = symbol_table; // n.m_symbol_table = symbol_table;
internal::build_symbol_table_and_check_declarations(n, symbol_table); // internal::build_symbol_table_and_check_declarations(n, symbol_table);
std::cout << " - checked symbols declaration\n"; // std::cout << " - checked symbols declaration\n";
} // }
namespace internal namespace internal
{ {
...@@ -463,7 +465,9 @@ parser(const std::string& filename) ...@@ -463,7 +465,9 @@ parser(const std::string& filename)
root_node = buildAST(input); root_node = buildAST(input);
std::cout << " - AST is built ...... [done]\n"; std::cout << " - AST is built ...... [done]\n";
language::build_symbol_table_and_check_declarations(*root_node); language::ASTSymbolTableBuilder{*root_node};
// language::build_symbol_table_and_check_declarations(*root_node);
language::check_symbol_initialization(*root_node); language::check_symbol_initialization(*root_node);
{ {
std::string dot_filename{"parse_tree.dot"}; std::string dot_filename{"parse_tree.dot"};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment