summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin <kevin@kevin-brown.com>2020-05-14 11:21:20 -0400
committerKevin <kevin@kevin-brown.com>2020-05-14 11:21:20 -0400
commit67e082fdf31da71760dddafb4d8a3ab5cca8321b (patch)
treeffe66e48ef4f8335b899c257683fc01d63710e5a
parent7a34fa03b4e065f9237645eef34192772e63992b (diff)
downloadjinja2-67e082fdf31da71760dddafb4d8a3ab5cca8321b.tar.gz
Add support for math expressions to grammar/parser
-rw-r--r--grammar.ebnf40
-rw-r--r--src/jinja2/new_parser.py23
2 files changed, 60 insertions, 3 deletions
diff --git a/grammar.ebnf b/grammar.ebnf
index 3c034ef..2d1406a 100644
--- a/grammar.ebnf
+++ b/grammar.ebnf
@@ -163,7 +163,7 @@ variable_identifier
variable_identifier_parentheses
=
- "(" @:variable_identifier ")"
+ "(" @:conditional_expression ")"
;
variable_identifier_raw
@@ -239,16 +239,52 @@ variable_accessor_call_parameter_value
conditional_expression
=
+ | complex_expression_powers
+ | complex_expression_math2
+ | concatenate_expression
+ | complex_expression_math1
| conditional_expression_parentheses
| conditional_expression_not
| conditional_expression_if
| conditional_expression_logical
| conditional_expression_operator
| conditional_expression_test
- | concatenate_expression
| variable_identifier
;
+complex_expression_powers
+ =
+ left:variable_identifier {SP}* operator:"**" {SP}* right:variable_identifier
+ ;
+
+complex_expression_math2
+ =
+ left:variable_identifier
+ {SP}* math_operator:complex_expression_math2_operations {SP}*
+ right:variable_identifier
+ ;
+
+complex_expression_math2_operations
+ =
+ | "*"
+ | "/"
+ | "//"
+ | "%"
+ ;
+
+complex_expression_math1
+ =
+ left:variable_identifier
+ {SP}* math_operator:complex_expression_math1_operations {SP}*
+ right:variable_identifier
+ ;
+
+complex_expression_math1_operations
+ =
+ | "+"
+ | "-"
+ ;
+
conditional_expression_parentheses
=
"(" {SP}* @:conditional_expression {SP}* ")"
diff --git a/src/jinja2/new_parser.py b/src/jinja2/new_parser.py
index 5ef1a43..5503d1e 100644
--- a/src/jinja2/new_parser.py
+++ b/src/jinja2/new_parser.py
@@ -449,6 +449,9 @@ def parse_conditional_expression(ast):
if 'logical_operator' in ast:
return parse_conditional_expression_logical(ast)
+ if 'math_operator' in ast:
+ return parse_conditional_expression_math(ast)
+
if 'not' in ast:
return parse_conditional_expression_not(ast)
@@ -492,6 +495,24 @@ def parse_conditional_expression_logical(ast):
lineno=lineno_from_parseinfo(ast['parseinfo'])
)
+def parse_conditional_expression_math(ast):
+ node_class_map = {
+ '+': nodes.Add,
+ '-': nodes.Sub,
+ '*': nodes.Mul,
+ '/': nodes.Div,
+ '//': nodes.FloorDiv,
+ '%': nodes.Mod,
+ }
+
+ node_class = node_class_map[ast['math_operator']]
+
+ return node_class(
+ parse_conditional_expression(ast['left']),
+ parse_conditional_expression(ast['right']),
+ lineno=lineno_from_parseinfo(ast['parseinfo'])
+ )
+
def parse_conditional_expression_not(ast):
return nodes.Not(
parse_conditional_expression(ast['not']),
@@ -542,7 +563,7 @@ def parse_conditional_expression_test(ast):
if ast['test_function_parameter']:
args = [
- parse_variable(ast['test_function_parameter'])
+ parse_conditional_expression(ast['test_function_parameter'])
]
test_node = nodes.Test(