diff --git a/src/language/ASTNodeDeclarationCleaner.cpp b/src/language/ASTNodeDeclarationCleaner.cpp
index 05a6822fd9938e3ce03cd8abfc627a46d97d47f0..7e2f139f92036df30dc7391a4d2681dd94041b6b 100644
--- a/src/language/ASTNodeDeclarationCleaner.cpp
+++ b/src/language/ASTNodeDeclarationCleaner.cpp
@@ -10,7 +10,7 @@ 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>()) {
+    if (n.children[i_child]->is<language::declaration>() or n.children[i_child]->is<language::let_declaration>()) {
       declaration_ids.push(i_child);
     }
   }
diff --git a/src/language/ASTNodeEmptyBlockCleaner.cpp b/src/language/ASTNodeEmptyBlockCleaner.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..eeb71c0878467b45386d7c529db841a9f57bcc6b
--- /dev/null
+++ b/src/language/ASTNodeEmptyBlockCleaner.cpp
@@ -0,0 +1,37 @@
+#include <ASTNodeEmptyBlockCleaner.hpp>
+
+#include <PEGGrammar.hpp>
+#include <PugsAssert.hpp>
+
+#include <stack>
+
+void
+ASTNodeEmptyBlockCleaner::_removeEmptyBlockNode(ASTNode& n)
+{
+  for (auto& child : n.children) {
+    this->_removeEmptyBlockNode(*child);
+  }
+
+  std::stack<size_t> empty_block_ids;
+  for (size_t i_child = 0; i_child < n.children.size(); ++i_child) {
+    if (n.children[i_child]->is<language::block>()) {
+      if (n.children[i_child]->children.size() == 0)
+        empty_block_ids.push(i_child);
+    }
+  }
+
+  while (empty_block_ids.size() > 0) {
+    size_t i_removed = empty_block_ids.top();
+    empty_block_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();
+  }
+}
+
+ASTNodeEmptyBlockCleaner::ASTNodeEmptyBlockCleaner(ASTNode& n)
+{
+  Assert(n.is_root());
+  this->_removeEmptyBlockNode(n);
+}
diff --git a/src/language/ASTNodeEmptyBlockCleaner.hpp b/src/language/ASTNodeEmptyBlockCleaner.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..bfa492ec0adaef2de374569cfa2aa0e2b92eb480
--- /dev/null
+++ b/src/language/ASTNodeEmptyBlockCleaner.hpp
@@ -0,0 +1,15 @@
+#ifndef AST_NODE_EMPTY_BLOCK_CLEANER_HPP
+#define AST_NODE_EMPTY_BLOCK_CLEANER_HPP
+
+#include <ASTNode.hpp>
+
+class ASTNodeEmptyBlockCleaner
+{
+ private:
+  void _removeEmptyBlockNode(ASTNode& node);
+
+ public:
+  ASTNodeEmptyBlockCleaner(ASTNode& root_node);
+};
+
+#endif   // AST_NODE_EMPTY_BLOCK_CLEANER_HPP
diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt
index 9910dd47004d805e153e0bd8a8dcf0c23c057af5..ab42c18cc035467baa7bb3dcccc72d55d53d51a0 100644
--- a/src/language/CMakeLists.txt
+++ b/src/language/CMakeLists.txt
@@ -16,6 +16,7 @@ add_library(
   ASTNodeDataTypeChecker.cpp
   ASTNodeDeclarationToAffectationConverter.cpp
   ASTNodeDeclarationCleaner.cpp
+  ASTNodeEmptyBlockCleaner.cpp
   ASTNodeExpressionBuilder.cpp
   ASTNodeIncDecExpressionBuilder.cpp
   ASTNodeJumpPlacementChecker.cpp
diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp
index 1b40aa888b052f6be4c3c2c004e145abb55726e4..d59d532101504e208d07ae51fd8c445b2ec740d5 100644
--- a/src/language/PugsParser.cpp
+++ b/src/language/PugsParser.cpp
@@ -29,6 +29,8 @@
 #include <ASTSymbolInitializationChecker.hpp>
 #include <ASTSymbolTableBuilder.hpp>
 
+#include <ASTNodeEmptyBlockCleaner.hpp>
+
 #include <ASTNodeDeclarationCleaner.hpp>
 #include <ASTNodeDeclarationToAffectationConverter.hpp>
 
@@ -75,6 +77,7 @@ parser(const std::string& filename)
     // optimizations
     ASTNodeDeclarationToAffectationConverter{*root_node};
     ASTNodeDeclarationCleaner{*root_node};
+    ASTNodeEmptyBlockCleaner{*root_node};
 
     ASTNodeExpressionBuilder{*root_node};