Skip to content
Snippets Groups Projects
Select Git revision
  • 71f4827ca8f4955b899505b65b8d170c26ae90f0
  • develop default protected
  • feature/variational-hydro
  • origin/stage/bouguettaia
  • feature/gmsh-reader
  • feature/reconstruction
  • save_clemence
  • feature/kinetic-schemes
  • feature/local-dt-fsi
  • feature/composite-scheme-sources
  • feature/composite-scheme-other-fluxes
  • feature/serraille
  • feature/composite-scheme
  • hyperplastic
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • master protected
  • v0.5.0 protected
  • v0.4.1 protected
  • v0.4.0 protected
  • v0.3.0 protected
  • v0.2.0 protected
  • v0.1.0 protected
  • Kidder
  • v0.0.4 protected
  • v0.0.3 protected
  • v0.0.2 protected
  • v0 protected
  • v0.0.1 protected
33 results

ConnectivityDispatcher.cpp

Blame
  • test_ASTBuilder.cpp 16.36 KiB
    #include <catch2/catch.hpp>
    
    #include <language/ast/ASTBuilder.hpp>
    #include <language/utils/ASTPrinter.hpp>
    
    #include <pegtl/string_input.hpp>
    
    #include <sstream>
    
    #define CHECK_AST(data, expected_output)                                                       \
      {                                                                                            \
        static_assert(std::is_same_v<std::decay_t<decltype(data)>, std::string_view>);             \
        static_assert(std::is_same_v<std::decay_t<decltype(expected_output)>, std::string_view>);  \
                                                                                                   \
        string_input input{data, "test.pgs"};                                                      \
        auto ast = ASTBuilder::build(input);                                                       \
                                                                                                   \
        std::stringstream ast_output;                                                              \
        ast_output << '\n' << ASTPrinter{*ast, ASTPrinter::Format::raw, {ASTPrinter::Info::none}}; \
                                                                                                   \
        REQUIRE(ast_output.str() == expected_output);                                              \
      }
    
    // clazy:excludeall=non-pod-global-static
    
    TEST_CASE("ASTBuilder", "[language]")
    {
      rang::setControlMode(rang::control::Off);
      SECTION("AST parsing")
      {
        SECTION("declarations with init")
        {
          std::string_view data = R"(
    let n:N, n = 2;
    let z:Z, z = 3;
    let r :R,r= 2.3e-5;
    let b: B ,b = false;
    let s : string, s = "foo";
    )";
    
          std::string_view result = R"(
    (root)
     +-(language::var_declaration)
     |   +-(language::name:n)
     |   +-(language::N_set)
     |   +-(language::name:n)
     |   `-(language::integer:2)
     +-(language::var_declaration)
     |   +-(language::name:z)
     |   +-(language::Z_set)
     |   +-(language::name:z)
     |   `-(language::integer:3)
     +-(language::var_declaration)
     |   +-(language::name:r)
     |   +-(language::R_set)
     |   +-(language::name:r)
     |   `-(language::real:2.3e-5)
     +-(language::var_declaration)
     |   +-(language::name:b)
     |   +-(language::B_set)
     |   +-(language::name:b)
     |   `-(language::false_kw)
     `-(language::var_declaration)
         +-(language::name:s)
         +-(language::string_type)
         +-(language::name:s)
         `-(language::literal:"foo")
    )";
          CHECK_AST(data, result);
        }
    
        SECTION("affectations")
        {
          std::string_view data = R"(
    let n:N; n = 2;
    let z:Z; z = 3;
    let r:R; r = 2.3e-5;
    let b:B; b = false;
    let s:string; s = "foo";
    )";
    
          std::string_view result = R"(
    (root)
     +-(language::var_declaration)
     |   +-(language::name:n)
     |   `-(language::N_set)
     +-(language::eq_op)
     |   +-(language::name:n)
     |   `-(language::integer:2)
     +-(language::var_declaration)
     |   +-(language::name:z)
     |   `-(language::Z_set)
     +-(language::eq_op)
     |   +-(language::name:z)
     |   `-(language::integer:3)
     +-(language::var_declaration)
     |   +-(language::name:r)
     |   `-(language::R_set)
     +-(language::eq_op)
     |   +-(language::name:r)
     |   `-(language::real:2.3e-5)
     +-(language::var_declaration)
     |   +-(language::name:b)
     |   `-(language::B_set)
     +-(language::eq_op)
     |   +-(language::name:b)
     |   `-(language::false_kw)
     +-(language::var_declaration)
     |   +-(language::name:s)
     |   `-(language::string_type)
     `-(language::eq_op)
         +-(language::name:s)
         `-(language::literal:"foo")
    )";
          CHECK_AST(data, result);
        }
    
        SECTION("empty blocks simplification")
        {
          std::string_view data = R"(
    {
      /* nothing but a block */
      {
        ; // 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 xor 7 and 2 or 2 <3 >7 xor -2 + true - not false;
    )";
    
            std::string_view result = R"(
    (root)
     `-(language::or_op)
         +-(language::or_op)
         |   +-(language::and_op)
         |   |   +-(language::plus_op)
         |   |   |   +-(language::integer:1)
         |   |   |   `-(language::integer:2)
         |   |   `-(language::eqeq_op)
         |   |       +-(language::lesser_or_eq_op)
         |   |       |   +-(language::integer:3)
         |   |       |   `-(language::minus_op)
         |   |       |       +-(language::multiply_op)
         |   |       |       |   +-(language::integer:2)
         |   |       |       |   `-(language::integer:4)
         |   |       |       `-(language::integer:1)
         |   |       `-(language::integer:2)
         |   `-(language::and_op)
         |       +-(language::xor_op)
         |       |   +-(language::greater_or_eq_op)
         |       |   |   +-(language::integer:2)
         |       |   |   `-(language::divide_op)
         |       |   |       +-(language::integer:1)
         |       |   |       `-(language::integer:5)
         |       |   `-(language::integer:7)
         |       `-(language::integer:2)
         `-(language::xor_op)
             +-(language::greater_op)
             |   +-(language::lesser_op)
             |   |   +-(language::integer:2)
             |   |   `-(language::integer:3)
             |   `-(language::integer:7)
             `-(language::minus_op)
                 +-(language::plus_op)
                 |   +-(language::unary_minus)
                 |   |   `-(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("subscript handling")
        {
          std::string_view data = R"(
    u[a];
    u[f(c)];
    u[u[b]];
    )";
    
          std::string_view result = R"(
    (root)
     +-(language::subscript_expression)
     |   +-(language::name:u)
     |   `-(language::name:a)
     +-(language::subscript_expression)
     |   +-(language::name:u)
     |   `-(language::function_evaluation)
     |       +-(language::name:f)
     |       `-(language::name:c)
     `-(language::subscript_expression)
         +-(language::name:u)
         `-(language::subscript_expression)
             +-(language::name:u)
             `-(language::name:b)
    )";
          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);
        }
    
        SECTION("statement block simplification (one instruction per block)")
        {
          std::string_view data = R"(
    if (a > 0) {
      a = 0;
    } else {
      a =-1;
    }
    )";
    
          std::string_view result = R"(
    (root)
     `-(language::if_statement)
         +-(language::greater_op)
         |   +-(language::name:a)
         |   `-(language::integer:0)
         +-(language::eq_op)
         |   +-(language::name:a)
         |   `-(language::integer:0)
         `-(language::eq_op)
             +-(language::name:a)
             `-(language::unary_minus)
                 `-(language::integer:1)
    )";
          CHECK_AST(data, result);
        }
    
        SECTION("statement block simplification (one instruction in first block)")
        {
          std::string_view data = R"(
    if (a > 0) {
      a = 0;
    } else {
      a = 3;
      a = a++;
    }
    )";
    
          std::string_view result = R"(
    (root)
     `-(language::if_statement)
         +-(language::greater_op)
         |   +-(language::name:a)
         |   `-(language::integer:0)
         +-(language::eq_op)
         |   +-(language::name:a)
         |   `-(language::integer:0)
         `-(language::block)
             +-(language::eq_op)
             |   +-(language::name:a)
             |   `-(language::integer:3)
             `-(language::eq_op)
                 +-(language::name:a)
                 `-(language::post_plusplus)
                     `-(language::name:a)
    )";
          CHECK_AST(data, result);
        }
    
        SECTION("statement block simplification (one instruction in second block)")
        {
          std::string_view data = R"(
    if (a > 0) {
      a = 0;
      a++;
    } else {
      a = 3;
    }
    )";
    
          std::string_view result = R"(
    (root)
     `-(language::if_statement)
         +-(language::greater_op)
         |   +-(language::name:a)
         |   `-(language::integer:0)
         +-(language::block)
         |   +-(language::eq_op)
         |   |   +-(language::name:a)
         |   |   `-(language::integer:0)
         |   `-(language::post_plusplus)
         |       `-(language::name:a)
         `-(language::eq_op)
             +-(language::name:a)
             `-(language::integer:3)
    )";
          CHECK_AST(data, result);
        }
    
        SECTION("statement block non-simplification (one declaration in each block)")
        {
          std::string_view data = R"(
    if (a > 0) {
      let b:R, b = a;
    } else {
      let c:R, c = 2*a;
    }
    )";
    
          std::string_view result = R"(
    (root)
     `-(language::if_statement)
         +-(language::greater_op)
         |   +-(language::name:a)
         |   `-(language::integer:0)
         +-(language::block)
         |   `-(language::var_declaration)
         |       +-(language::name:b)
         |       +-(language::R_set)
         |       +-(language::name:b)
         |       `-(language::name:a)
         `-(language::block)
             `-(language::var_declaration)
                 +-(language::name:c)
                 +-(language::R_set)
                 +-(language::name:c)
                 `-(language::multiply_op)
                     +-(language::integer:2)
                     `-(language::name:a)
    )";
          CHECK_AST(data, result);
        }
    
        SECTION("statement block simplification (one declaration in first block)")
        {
          std::string_view data = R"(
    if (a > 0) {
      let b:R, b = a;
    } else {
      let c:R, c = 2*a;
      ++a;
    }
    )";
    
          std::string_view result = R"(
    (root)
     `-(language::if_statement)
         +-(language::greater_op)
         |   +-(language::name:a)
         |   `-(language::integer:0)
         +-(language::block)
         |   `-(language::var_declaration)
         |       +-(language::name:b)
         |       +-(language::R_set)
         |       +-(language::name:b)
         |       `-(language::name:a)
         `-(language::block)
             +-(language::var_declaration)
             |   +-(language::name:c)
             |   +-(language::R_set)
             |   +-(language::name:c)
             |   `-(language::multiply_op)
             |       +-(language::integer:2)
             |       `-(language::name:a)
             `-(language::unary_plusplus)
                 `-(language::name:a)
    )";
          CHECK_AST(data, result);
        }
    
        SECTION("statement block simplification (one declaration in second block)")
        {
          std::string_view data = R"(
    if (a > 0) {
      let b:R, b = a;
      ++b;
    } else {
      let c:R, c = 2*a;
    }
    )";
    
          std::string_view result = R"(
    (root)
     `-(language::if_statement)
         +-(language::greater_op)
         |   +-(language::name:a)
         |   `-(language::integer:0)
         +-(language::block)
         |   +-(language::var_declaration)
         |   |   +-(language::name:b)
         |   |   +-(language::R_set)
         |   |   +-(language::name:b)
         |   |   `-(language::name:a)
         |   `-(language::unary_plusplus)
         |       `-(language::name:b)
         `-(language::block)
             `-(language::var_declaration)
                 +-(language::name:c)
                 +-(language::R_set)
                 +-(language::name:c)
                 `-(language::multiply_op)
                     +-(language::integer:2)
                     `-(language::name:a)
    )";
          CHECK_AST(data, result);
        }
    
        SECTION("for-statements simplification")
        {
          std::string_view data = R"(
    for(let i:N, i=0; i<10; ++i) {
      i += 3;
    }
    )";
    
          std::string_view result = R"(
    (root)
     `-(language::for_statement)
         +-(language::var_declaration)
         |   +-(language::name:i)
         |   +-(language::N_set)
         |   +-(language::name:i)
         |   `-(language::integer:0)
         +-(language::lesser_op)
         |   +-(language::name:i)
         |   `-(language::integer:10)
         +-(language::unary_plusplus)
         |   `-(language::name:i)
         `-(language::pluseq_op)
             +-(language::name:i)
             `-(language::integer:3)
    )";
          CHECK_AST(data, result);
        }
    
        SECTION("for-statements simplification (complex block)")
        {
          std::string_view data = R"(
    for(let i:N, i=0; i<10; ++i) {
      i += 3;
      let j:R, j=i/5.;
    }
    )";
    
          std::string_view result = R"(
    (root)
     `-(language::for_statement)
         +-(language::var_declaration)
         |   +-(language::name:i)
         |   +-(language::N_set)
         |   +-(language::name:i)
         |   `-(language::integer:0)
         +-(language::lesser_op)
         |   +-(language::name:i)
         |   `-(language::integer:10)
         +-(language::unary_plusplus)
         |   `-(language::name:i)
         `-(language::for_statement_block)
             +-(language::pluseq_op)
             |   +-(language::name:i)
             |   `-(language::integer:3)
             `-(language::var_declaration)
                 +-(language::name:j)
                 +-(language::R_set)
                 +-(language::name:j)
                 `-(language::divide_op)
                     +-(language::name:i)
                     `-(language::real:5.)
    )";
          CHECK_AST(data, result);
        }
    
        SECTION("ostream simplifications")
        {
          std::string_view data = R"(
    cout << 1+2 << "\n";
    cerr << "error?\n";
    clog << "log " << l << "\n";
    )";
    
          std::string_view result = R"(
    (root)
     +-(language::cout_kw)
     |   +-(language::plus_op)
     |   |   +-(language::integer:1)
     |   |   `-(language::integer:2)
     |   `-(language::literal:"\n")
     +-(language::cerr_kw)
     |   `-(language::literal:"error?\n")
     `-(language::clog_kw)
         +-(language::literal:"log ")
         +-(language::name:l)
         `-(language::literal:"\n")
    )";
          CHECK_AST(data, result);
        }
    
        SECTION("tuple list simplification")
        {
          std::string_view data = R"(
    let x:(R^2), x=((0,0),(2,3));
    let y:(R^2), y=((0));
    )";
    
          std::string_view result = R"(
    (root)
     +-(language::var_declaration)
     |   +-(language::name:x)
     |   +-(language::tuple_type_specifier)
     |   |   `-(language::vector_type)
     |   |       +-(language::R_set)
     |   |       `-(language::integer:2)
     |   +-(language::name:x)
     |   `-(language::expression_list)
     |       +-(language::tuple_expression)
     |       |   +-(language::integer:0)
     |       |   `-(language::integer:0)
     |       `-(language::tuple_expression)
     |           +-(language::integer:2)
     |           `-(language::integer:3)
     `-(language::var_declaration)
         +-(language::name:y)
         +-(language::tuple_type_specifier)
         |   `-(language::vector_type)
         |       +-(language::R_set)
         |       `-(language::integer:2)
         +-(language::name:y)
         `-(language::integer:0)
    )";
          CHECK_AST(data, result);
        }
      }
    
      SECTION("errors")
      {
        SECTION("syntax error")
        {
          std::string_view data = R"(
    1+; // syntax error
    )";
    
          string_input input{data, "test.pgs"};
    
          REQUIRE_THROWS_WITH(ASTBuilder::build(input), "parse error, missing expression");
        }
      }
    }