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

Create class ASTSymbolInitializationChecker

This helper class is not finished, does not handle statements correctly
parent c1d8d089
No related branches found
No related tags found
1 merge request!37Feature/language
#include <ASTSymbolInitializationChecker.hpp>
#include <SymbolTable.hpp>
#include <PEGGrammar.hpp>
void
ASTSymbolInitializationChecker::_checkSymbolInitialization(ASTNode& node)
{
if (node.is<language::declaration>()) {
const std::string& symbol = node.children[1]->string();
auto [i_symbol, found] = node.m_symbol_table->find(symbol);
Assert(found, "unexpected error, should have been detected through declaration checking");
if (node.children.size() == 3) {
this->_checkSymbolInitialization(*node.children[2]);
i_symbol->second.setIsInitialized();
}
} else if (node.is<language::eq_op>()) {
// first checks for right hand side
this->_checkSymbolInitialization(*node.children[1]);
// then marks left hand side as initialized
const std::string& symbol = node.children[0]->string();
auto [i_symbol, found] = node.m_symbol_table->find(symbol);
Assert(found, "unexpected error, should have been detected through declaration checking");
i_symbol->second.setIsInitialized();
} else if (node.is<language::name>()) {
auto [i_symbol, found] = node.m_symbol_table->find(node.string());
Assert(found, "unexpected error, should have been detected through declaration checking");
if (not i_symbol->second.isInitialized()) {
std::ostringstream error_message;
error_message << "uninitialized symbol '" << rang::fg::red << node.string() << rang::fg::reset << '\'';
throw parse_error(error_message.str(), std::vector{node.begin()});
}
}
if ((not node.is<language::declaration>()) and (not node.is<language::eq_op>())) {
for (auto& child : node.children) {
this->_checkSymbolInitialization(*child);
}
}
}
ASTSymbolInitializationChecker::ASTSymbolInitializationChecker(ASTNode& root_node)
{
Assert(root_node.is_root());
this->_checkSymbolInitialization(root_node);
}
#ifndef AST_SYMBOL_INITIALIZATION_CHECKER_HPP
#define AST_SYMBOL_INITIALIZATION_CHECKER_HPP
#include <ASTNode.hpp>
class ASTSymbolInitializationChecker
{
private:
void _checkSymbolInitialization(ASTNode& node);
public:
ASTSymbolInitializationChecker(ASTNode& root_node);
};
#endif // AST_SYMBOL_INITIALIZATION_CHECKER_HPP
...@@ -14,6 +14,7 @@ add_library( ...@@ -14,6 +14,7 @@ add_library(
ASTNodeUnaryOperatorExpressionBuilder.cpp ASTNodeUnaryOperatorExpressionBuilder.cpp
ASTPrinter.cpp ASTPrinter.cpp
ASTSymbolTableBuilder.cpp ASTSymbolTableBuilder.cpp
ASTSymbolInitializationChecker.cpp
PugsParser.cpp) PugsParser.cpp)
#include_directories(${PUGS_SOURCE_DIR}/utils) #include_directories(${PUGS_SOURCE_DIR}/utils)
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <ASTNodeExpressionBuilder.hpp> #include <ASTNodeExpressionBuilder.hpp>
#include <ASTSymbolInitializationChecker.hpp>
#include <ASTSymbolTableBuilder.hpp> #include <ASTSymbolTableBuilder.hpp>
#include <ASTPrinter.hpp> #include <ASTPrinter.hpp>
...@@ -67,66 +68,6 @@ print_dot(std::ostream& os, const ASTNode& n) ...@@ -67,66 +68,6 @@ print_dot(std::ostream& os, const ASTNode& n)
os << "}\n"; os << "}\n";
} }
namespace internal
{
void
check_symbol_initialization(const 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);
for (auto& child : n.children) {
check_symbol_initialization(*child, bloc_symbol_table);
}
}
} else {
if (n.is<language::declaration>()) {
const std::string& symbol = n.children[1]->string();
auto [i_symbol, success] = symbol_table->add(symbol);
Assert(success, "unexpected error, should have been detected through declaration checking");
if (n.children.size() == 3) {
check_symbol_initialization(*n.children[2], symbol_table);
i_symbol->second.setIsInitialized();
}
} else if (n.is<language::eq_op>()) {
// first checks for right hand side
check_symbol_initialization(*n.children[1], symbol_table);
// then marks left hand side as initialized
const std::string& symbol = n.children[0]->string();
auto [i_symbol, found] = symbol_table->find(symbol);
Assert(found, "unexpected error, should have been detected through declaration checking");
i_symbol->second.setIsInitialized();
} else if (n.is<language::name>()) {
auto [i_symbol, found] = symbol_table->find(n.string());
Assert(found, "unexpected error, should have been detected through declaration checking");
if (not i_symbol->second.isInitialized()) {
std::ostringstream error_message;
error_message << "uninitialized symbol '" << rang::fg::red << n.string() << rang::fg::reset << '\'';
throw parse_error(error_message.str(), std::vector{n.begin()});
}
}
if ((not n.is<language::declaration>()) and (not n.is<language::eq_op>())) {
for (auto& child : n.children) {
check_symbol_initialization(*child, symbol_table);
}
}
}
}
} // namespace internal
void
check_symbol_initialization(const ASTNode& n)
{
std::cerr << rang::fgB::yellow << "warning:" << rang::fg::reset
<< " symbol initialization checking not finished"
"if and loops statements are not correctly evaluated\n";
Assert(n.is_root());
std::shared_ptr symbol_table = std::make_shared<SymbolTable>();
internal::check_symbol_initialization(n, symbol_table);
std::cout << " - checked symbols initialization\n";
}
namespace internal namespace internal
{ {
void void
...@@ -418,7 +359,8 @@ parser(const std::string& filename) ...@@ -418,7 +359,8 @@ parser(const std::string& filename)
ASTSymbolTableBuilder{*root_node}; ASTSymbolTableBuilder{*root_node};
language::check_symbol_initialization(*root_node); ASTSymbolInitializationChecker{*root_node};
{ {
std::string dot_filename{"parse_tree.dot"}; std::string dot_filename{"parse_tree.dot"};
std::ofstream fout(dot_filename); std::ofstream fout(dot_filename);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment