diff --git a/tests/test_ASTBuilder.cpp b/tests/test_ASTBuilder.cpp
index 11c2afc9497c2362437c28c9f9fbb9fb4e3616e5..dfbeeaefc9fded484af12c9054d826419c360b40 100644
--- a/tests/test_ASTBuilder.cpp
+++ b/tests/test_ASTBuilder.cpp
@@ -4,46 +4,314 @@
 #include <ASTPrinter.hpp>
 #include <sstream>
 
-TEST_CASE("ASTBuilder", "[language]")
+void
+build_ast(const std::string_view& data)
 {
   using namespace language;
+  string_input input{data, "test.pgs"};
+  buildAST(input);
+}
 
-  SECTION("checking AST simplifications"){}
-  {
-    std::stringstream ss{R"(
-Z a = -3;
-Z b = - - + - 2;
-Z d;
+void
+check_ast(const std::string_view& data, const std::string_view& expected_output)
 {
- Z c=3;
- d = (0 -  -c)/3;
+  using namespace language;
+
+  string_input input{data, "test.pgs"};
+  auto ast = buildAST(input);
+
+  std::stringstream ast_output;
+  ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::none}};
+
+  REQUIRE(ast_output.str() == expected_output);
 }
-Z e = 0 + +3;
-Z f = 0 + -3;
-
-B g = not not true;
-R h = 0;
-R i = h++;
-i--;
-)"};
-
-    istream_input input{ss, ss.str().size(), "test.pgs"};
-    auto ast = buildAST(input);
-    std::stringstream ast_output;
-    ast_output << ASTPrinter{*ast, ASTPrinter::Format::raw};
-    REQUIRE(true);
-  }
 
-  REQUIRE(true);
+TEST_CASE("ASTBuilder", "[language]")
+{
+  rang::setControlMode(rang::control::Off);
+  SECTION("AST parsing")
+  {
+    SECTION("declarations with init")
+    {
+      std::string_view data = R"(
+N n = 2;
+Z z = 3;
+R r = 2.3e-5;
+B b = false;
+string s = "foo";
+)";
 
-  SECTION("checking for copies") {}
+      std::string_view result = R"(
+(root)
+ +-(language::declaration)
+ |   +-(language::N_set)
+ |   +-(language::name:n)
+ |   `-(language::integer:2)
+ +-(language::declaration)
+ |   +-(language::Z_set)
+ |   +-(language::name:z)
+ |   `-(language::integer:3)
+ +-(language::declaration)
+ |   +-(language::R_set)
+ |   +-(language::name:r)
+ |   `-(language::real:2.3e-5)
+ +-(language::declaration)
+ |   +-(language::B_set)
+ |   +-(language::name:b)
+ |   `-(language::false_kw)
+ `-(language::declaration)
+     +-(language::string_type)
+     +-(language::name:s)
+     `-(language::literal:"foo")
+)";
+      check_ast(data, result);
+    }
 
-  SECTION("checking for fill") {}
+    SECTION("affectations")
+    {
+      std::string_view data = R"(
+N n; n = 2;
+Z z; z = 3;
+R r; r = 2.3e-5;
+B b; b = false;
+string s; s = "foo";
+)";
 
-  SECTION("checking for affectations (shallow copy)") {}
+      std::string_view result = R"(
+(root)
+ +-(language::declaration)
+ |   +-(language::N_set)
+ |   `-(language::name:n)
+ +-(language::eq_op)
+ |   +-(language::name:n)
+ |   `-(language::integer:2)
+ +-(language::declaration)
+ |   +-(language::Z_set)
+ |   `-(language::name:z)
+ +-(language::eq_op)
+ |   +-(language::name:z)
+ |   `-(language::integer:3)
+ +-(language::declaration)
+ |   +-(language::R_set)
+ |   `-(language::name:r)
+ +-(language::eq_op)
+ |   +-(language::name:r)
+ |   `-(language::real:2.3e-5)
+ +-(language::declaration)
+ |   +-(language::B_set)
+ |   `-(language::name:b)
+ +-(language::eq_op)
+ |   +-(language::name:b)
+ |   `-(language::false_kw)
+ +-(language::declaration)
+ |   +-(language::string_type)
+ |   `-(language::name:s)
+ `-(language::eq_op)
+     +-(language::name:s)
+     `-(language::literal:"foo")
+)";
+      check_ast(data, result);
+    }
 
-  SECTION("checking for bounds violation")
+    SECTION("empty blocs simplification")
+    {
+      std::string_view data = R"(
+{
+  /* nothing but a bloc */
   {
-    //    REQUIRE_THROWS_AS(a[10], AssertError);
+    ; // nothing
+  }
+}
+)";
+
+      std::string_view result = R"(
+(root)
+)";
+      check_ast(data, result);
+    }
+
+    SECTION("operators precedence")
+    {
+      SECTION("basic operations")
+      {
+        std::string_view data = R"(
+2+3.2*6 - 3.2/4;
+)";
+
+        std::string_view result = R"(
+(root)
+ `-(language::minus_op)
+     +-(language::plus_op)
+     |   +-(language::integer:2)
+     |   `-(language::multiply_op)
+     |       +-(language::real:3.2)
+     |       `-(language::integer:6)
+     `-(language::divide_op)
+         +-(language::real:3.2)
+         `-(language::integer:4)
+)";
+        check_ast(data, result);
+      }
+
+      SECTION("parented expression")
+      {
+        std::string_view data = R"(
+(2+3)*6;
+)";
+
+        std::string_view result = R"(
+(root)
+ `-(language::multiply_op)
+     +-(language::plus_op)
+     |   +-(language::integer:2)
+     |   `-(language::integer:3)
+     `-(language::integer:6)
+)";
+        check_ast(data, result);
+      }
+
+      SECTION("all operators mix")
+      {
+        std::string_view data = R"(
+1+2 and 3<= 2 * 4 - 1 == 2 or 2>=1 / 5 ^ 6 & 7 && 2 || 1 | 2 <3 >7 xor -2 bitand 2 bitor + true - not false;
+)";
+
+        std::string_view result = R"(
+(root)
+ `-(language::minus_op)
+     +-(language::bitor_op)
+     |   +-(language::bitand_op)
+     |   |   +-(language::xor_op)
+     |   |   |   +-(language::greater_op)
+     |   |   |   |   +-(language::lesser_op)
+     |   |   |   |   |   +-(language::bitor_op)
+     |   |   |   |   |   |   +-(language::or_op)
+     |   |   |   |   |   |   |   +-(language::and_op)
+     |   |   |   |   |   |   |   |   +-(language::bitand_op)
+     |   |   |   |   |   |   |   |   |   +-(language::xor_op)
+     |   |   |   |   |   |   |   |   |   |   +-(language::greater_or_eq_op)
+     |   |   |   |   |   |   |   |   |   |   |   +-(language::or_op)
+     |   |   |   |   |   |   |   |   |   |   |   |   +-(language::eqeq_op)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   +-(language::minus_op)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   |   +-(language::lesser_or_eq_op)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   +-(language::and_op)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   +-(language::plus_op)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   +-(language::integer:1)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   `-(language::integer:2)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   `-(language::integer:3)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   `-(language::multiply_op)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   |   |       +-(language::integer:2)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   |   |       `-(language::integer:4)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   |   `-(language::integer:1)
+     |   |   |   |   |   |   |   |   |   |   |   |   |   `-(language::integer:2)
+     |   |   |   |   |   |   |   |   |   |   |   |   `-(language::integer:2)
+     |   |   |   |   |   |   |   |   |   |   |   `-(language::divide_op)
+     |   |   |   |   |   |   |   |   |   |   |       +-(language::integer:1)
+     |   |   |   |   |   |   |   |   |   |   |       `-(language::integer:5)
+     |   |   |   |   |   |   |   |   |   |   `-(language::integer:6)
+     |   |   |   |   |   |   |   |   |   `-(language::integer:7)
+     |   |   |   |   |   |   |   |   `-(language::integer:2)
+     |   |   |   |   |   |   |   `-(language::integer:1)
+     |   |   |   |   |   |   `-(language::integer:2)
+     |   |   |   |   |   `-(language::integer:3)
+     |   |   |   |   `-(language::integer:7)
+     |   |   |   `-(language::unary_minus)
+     |   |   |       `-(language::integer:2)
+     |   |   `-(language::integer:2)
+     |   `-(language::true_kw)
+     `-(language::unary_not)
+         `-(language::false_kw)
+)";
+        check_ast(data, result);
+      }
+    }
+
+    SECTION("unary operator simplification")
+    {
+      SECTION("multiple not")
+      {
+        std::string_view data = R"(
+not not not not true;
+not not not false;
+)";
+
+        std::string_view result = R"(
+(root)
+ +-(language::true_kw)
+ `-(language::unary_not)
+     `-(language::false_kw)
+)";
+        check_ast(data, result);
+      }
+
+      SECTION("multiple unary plus")
+      {
+        std::string_view data = R"(
++ + + 3;
+)";
+
+        std::string_view result = R"(
+(root)
+ `-(language::integer:3)
+)";
+        check_ast(data, result);
+      }
+
+      SECTION("multiple unary minus")
+      {
+        std::string_view data = R"(
+- - + - - 3;
+- + - - 2;
+)";
+
+        std::string_view result = R"(
+(root)
+ +-(language::integer:3)
+ `-(language::unary_minus)
+     `-(language::integer:2)
+)";
+        check_ast(data, result);
+      }
+
+      SECTION("sums and unary plus/minus")
+      {
+        std::string_view data = R"(
+1 - - 3;
+1 + - 2;
+4 - + 3;
+)";
+
+        std::string_view result = R"(
+(root)
+ +-(language::plus_op)
+ |   +-(language::integer:1)
+ |   `-(language::integer:3)
+ +-(language::minus_op)
+ |   +-(language::integer:1)
+ |   `-(language::integer:2)
+ `-(language::minus_op)
+     +-(language::integer:4)
+     `-(language::integer:3)
+)";
+        check_ast(data, result);
+      }
+    }
+
+    SECTION("post incr/decr rearrangements")
+    {
+      std::string_view data = R"(
+1++;
+2--;
+)";
+
+      std::string_view result = R"(
+(root)
+ +-(language::post_plusplus)
+ |   `-(language::integer:1)
+ `-(language::post_minusminus)
+     `-(language::integer:2)
+)";
+      check_ast(data, result);
+    }
   }
 }