jinja : fix lexing of float literals with sign (#18901)
* fix lexing of float literals with sign * add test * consume_numeric
This commit is contained in:
+12
-7
@@ -91,6 +91,16 @@ lexer_result lexer::tokenize(const std::string & source) {
|
|||||||
return str;
|
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 {
|
auto next_pos_is = [&](std::initializer_list<char> chars, size_t n = 1) -> bool {
|
||||||
if (pos + n >= src.size()) return false;
|
if (pos + n >= src.size()) return false;
|
||||||
for (char c : chars) {
|
for (char c : chars) {
|
||||||
@@ -258,7 +268,7 @@ lexer_result lexer::tokenize(const std::string & source) {
|
|||||||
++pos; // Consume the operator
|
++pos; // Consume the operator
|
||||||
|
|
||||||
// Check for numbers following the unary 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;
|
std::string value = std::string(1, ch) + num;
|
||||||
token::type t = num.empty() ? token::unary_operator : token::numeric_literal;
|
token::type t = num.empty() ? token::unary_operator : token::numeric_literal;
|
||||||
// JJ_DEBUG("consumed unary operator or numeric literal: '%s'", value.c_str());
|
// 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
|
// Numbers
|
||||||
if (is_integer(ch)) {
|
if (is_integer(ch)) {
|
||||||
start_pos = pos;
|
start_pos = pos;
|
||||||
std::string num = consume_while(is_integer);
|
std::string num = consume_numeric();
|
||||||
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;
|
|
||||||
}
|
|
||||||
// JJ_DEBUG("consumed numeric literal: '%s'", num.c_str());
|
// JJ_DEBUG("consumed numeric literal: '%s'", num.c_str());
|
||||||
tokens.push_back({token::numeric_literal, num, start_pos});
|
tokens.push_back({token::numeric_literal, num, start_pos});
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -247,6 +247,12 @@ static void test_expressions(testing & t) {
|
|||||||
"Bob"
|
"Bob"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_template(t, "negative float (not dot notation)",
|
||||||
|
"{{ -1.0 }}",
|
||||||
|
json::object(),
|
||||||
|
"-1.0"
|
||||||
|
);
|
||||||
|
|
||||||
test_template(t, "bracket notation",
|
test_template(t, "bracket notation",
|
||||||
"{{ user['name'] }}",
|
"{{ user['name'] }}",
|
||||||
{{"user", {{"name", "Bob"}}}},
|
{{"user", {{"name", "Bob"}}}},
|
||||||
|
|||||||
Reference in New Issue
Block a user