diff --git a/src/language/ASTNodeDeclarationCleaner.cpp b/src/language/ASTNodeDeclarationCleaner.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..05a6822fd9938e3ce03cd8abfc627a46d97d47f0
--- /dev/null
+++ b/src/language/ASTNodeDeclarationCleaner.cpp
@@ -0,0 +1,36 @@
+#include <ASTNodeDeclarationCleaner.hpp>
+
+#include <PEGGrammar.hpp>
+#include <PugsAssert.hpp>
+
+#include <stack>
+
+void
+ASTNodeDeclarationCleaner::_removeDeclarationNode(ASTNode& n)
+{
+  std::stack<size_t> declaration_ids;
+  for (size_t i_child = 0; i_child < n.children.size(); ++i_child) {
+    if (n.children[i_child]->is<language::declaration>()) {
+      declaration_ids.push(i_child);
+    }
+  }
+
+  while (declaration_ids.size() > 0) {
+    size_t i_removed = declaration_ids.top();
+    declaration_ids.pop();
+    for (size_t i = i_removed; i + 1 < n.children.size(); ++i) {
+      n.children[i] = std::move(n.children[i + 1]);
+    }
+    n.children.pop_back();
+  }
+
+  for (auto& child : n.children) {
+    this->_removeDeclarationNode(*child);
+  }
+}
+
+ASTNodeDeclarationCleaner::ASTNodeDeclarationCleaner(ASTNode& n)
+{
+  Assert(n.is_root());
+  this->_removeDeclarationNode(n);
+}
diff --git a/src/language/ASTNodeDeclarationCleaner.hpp b/src/language/ASTNodeDeclarationCleaner.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..422f1e910324763c23e96c65ae26ed4b67c259b8
--- /dev/null
+++ b/src/language/ASTNodeDeclarationCleaner.hpp
@@ -0,0 +1,15 @@
+#ifndef AST_NODE_DECLARATION_CLEANER_HPP
+#define AST_NODE_DECLARATION_CLEANER_HPP
+
+#include <ASTNode.hpp>
+
+class ASTNodeDeclarationCleaner
+{
+ private:
+  void _removeDeclarationNode(ASTNode& node);
+
+ public:
+  ASTNodeDeclarationCleaner(ASTNode& root_node);
+};
+
+#endif   // AST_NODE_DECLARATION_CLEANER_HPP
diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt
index 496f44e92dfc5475de0457a58cd5fd2396247642..3333d9b769e8d2efad96f5335cbdd983a77221d6 100644
--- a/src/language/CMakeLists.txt
+++ b/src/language/CMakeLists.txt
@@ -13,6 +13,7 @@ add_library(
   ASTNodeDataTypeBuilder.cpp
   ASTNodeDataTypeChecker.cpp
   ASTNodeDeclarationToAffectationConverter.cpp
+  ASTNodeDeclarationCleaner.cpp
   ASTNodeExpressionBuilder.cpp
   ASTNodeIncDecExpressionBuilder.cpp
   ASTNodeJumpPlacementChecker.cpp
diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp
index 0972e911759b7123b3e538c614b0042aced59255..f37b16f8a1261382ad4ef893b508be5d7dc66c9f 100644
--- a/src/language/PugsParser.cpp
+++ b/src/language/PugsParser.cpp
@@ -29,6 +29,7 @@
 #include <ASTSymbolInitializationChecker.hpp>
 #include <ASTSymbolTableBuilder.hpp>
 
+#include <ASTNodeDeclarationCleaner.hpp>
 #include <ASTNodeDeclarationToAffectationConverter.hpp>
 
 #include <ASTDotPrinter.hpp>
@@ -72,6 +73,7 @@ parser(const std::string& filename)
 
     // optimizations
     ASTNodeDeclarationToAffectationConverter{*root_node};
+    ASTNodeDeclarationCleaner{*root_node};
 
     language::build_node_type(*root_node);