Просмотр исходного кода

jinja : fix lexing of float literals with sign (#18901)

* fix lexing of float literals with sign

* add test

* consume_numeric
Sigbjørn Skjæret 1 неделя назад
Родитель
Сommit
420960ab92
2 измененных файлов с 18 добавлено и 7 удалено
  1. 12 7
      common/jinja/lexer.cpp
  2. 6 0
      tests/test-jinja.cpp

+ 12 - 7
common/jinja/lexer.cpp

@@ -91,6 +91,16 @@ lexer_result lexer::tokenize(const std::string & source) {
         return str;
     };
 
+    auto consume_numeric = [&]() -> std::string {
+        std::string num = consume_while(is_integer);
+        if (pos < src.size() && src[pos] == '.' && pos + 1 < src.size() && is_integer(src[pos + 1])) {
+            ++pos; // Consume '.'
+            std::string frac = consume_while(is_integer);
+            num += "." + frac;
+        }
+        return num;
+    };
+
     auto next_pos_is = [&](std::initializer_list<char> chars, size_t n = 1) -> bool {
         if (pos + n >= src.size()) return false;
         for (char c : chars) {
@@ -258,7 +268,7 @@ lexer_result lexer::tokenize(const std::string & source) {
                     ++pos; // Consume the operator
 
                     // Check for numbers following the unary operator
-                    std::string num = consume_while(is_integer);
+                    std::string num = consume_numeric();
                     std::string value = std::string(1, ch) + num;
                     token::type t = num.empty() ? token::unary_operator : token::numeric_literal;
                     // JJ_DEBUG("consumed unary operator or numeric literal: '%s'", value.c_str());
@@ -307,12 +317,7 @@ lexer_result lexer::tokenize(const std::string & source) {
         // Numbers
         if (is_integer(ch)) {
             start_pos = pos;
-            std::string num = consume_while(is_integer);
-            if (pos < src.size() && src[pos] == '.' && pos + 1 < src.size() && is_integer(src[pos + 1])) {
-                ++pos; // Consume '.'
-                std::string frac = consume_while(is_integer);
-                num += "." + frac;
-            }
+            std::string num = consume_numeric();
             // JJ_DEBUG("consumed numeric literal: '%s'", num.c_str());
             tokens.push_back({token::numeric_literal, num, start_pos});
             continue;

+ 6 - 0
tests/test-jinja.cpp

@@ -247,6 +247,12 @@ static void test_expressions(testing & t) {
         "Bob"
     );
 
+    test_template(t, "negative float (not dot notation)",
+        "{{ -1.0 }}",
+        json::object(),
+        "-1.0"
+    );
+
     test_template(t, "bracket notation",
         "{{ user['name'] }}",
         {{"user", {{"name", "Bob"}}}},