fix: template expression precedence
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## 1.0.0 - 2022-12-02
|
||||
|
||||
breaking:
|
||||
* remove `template_if_branch` and `template_else_branch`
|
||||
|
||||
fix:
|
||||
* fix precedence in template expressions
|
||||
|
||||
## 0.7.0 - 2022-06-02
|
||||
|
||||
housekeeping:
|
||||
|
||||
Binary file not shown.
29
grammar.js
29
grammar.js
@@ -16,9 +16,6 @@ const
|
||||
module.exports = grammar({
|
||||
name: 'hcl',
|
||||
|
||||
conflicts: $ => [
|
||||
],
|
||||
|
||||
externals: $ => [
|
||||
$.quoted_template_start,
|
||||
$.quoted_template_end,
|
||||
@@ -269,12 +266,6 @@ module.exports = grammar({
|
||||
$.heredoc_template,
|
||||
),
|
||||
|
||||
_template: $ => prec.left(repeat1(choice(
|
||||
$.template_literal,
|
||||
$.template_interpolation,
|
||||
$.template_directive,
|
||||
))),
|
||||
|
||||
quoted_template: $ => prec(PREC.quoted_template, seq(
|
||||
$.quoted_template_start,
|
||||
optional($._template),
|
||||
@@ -292,6 +283,12 @@ module.exports = grammar({
|
||||
|
||||
strip_marker: $ => '~',
|
||||
|
||||
_template: $ => repeat1(choice(
|
||||
$.template_interpolation,
|
||||
$.template_directive,
|
||||
$.template_literal,
|
||||
)),
|
||||
|
||||
template_literal: $ => prec.right(repeat1(
|
||||
$._template_literal_chunk,
|
||||
)),
|
||||
@@ -304,7 +301,6 @@ module.exports = grammar({
|
||||
$.template_interpolation_end,
|
||||
),
|
||||
|
||||
// TODO
|
||||
template_directive: $ => choice(
|
||||
$.template_for,
|
||||
$.template_if,
|
||||
@@ -337,15 +333,12 @@ module.exports = grammar({
|
||||
),
|
||||
|
||||
template_if: $ => seq(
|
||||
$.template_if_branch,
|
||||
optional($.template_else_branch),
|
||||
$.template_if_intro,
|
||||
optional($._template),
|
||||
optional(seq($.template_else_intro, optional($._template))),
|
||||
$.template_if_end,
|
||||
),
|
||||
|
||||
template_if_branch: $ => seq(
|
||||
$.template_if_intro, $._template
|
||||
),
|
||||
|
||||
template_if_intro: $ => seq(
|
||||
$.template_directive_start,
|
||||
optional($.strip_marker),
|
||||
@@ -355,10 +348,6 @@ module.exports = grammar({
|
||||
$.template_directive_end
|
||||
),
|
||||
|
||||
template_else_branch: $ => seq(
|
||||
$.template_else_intro, $._template
|
||||
),
|
||||
|
||||
template_else_intro: $ => seq(
|
||||
$.template_directive_start,
|
||||
optional($.strip_marker),
|
||||
|
||||
103
src/grammar.json
103
src/grammar.json
@@ -1187,30 +1187,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"_template": {
|
||||
"type": "PREC_LEFT",
|
||||
"value": 0,
|
||||
"content": {
|
||||
"type": "REPEAT1",
|
||||
"content": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "template_literal"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "template_interpolation"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "template_directive"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"quoted_template": {
|
||||
"type": "PREC",
|
||||
"value": 1,
|
||||
@@ -1286,6 +1262,26 @@
|
||||
"type": "STRING",
|
||||
"value": "~"
|
||||
},
|
||||
"_template": {
|
||||
"type": "REPEAT1",
|
||||
"content": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "template_interpolation"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "template_directive"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "template_literal"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"template_literal": {
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 0,
|
||||
@@ -1504,14 +1500,43 @@
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "template_if_branch"
|
||||
"name": "template_if_intro"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "template_else_branch"
|
||||
"name": "_template"
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "template_else_intro"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_template"
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
@@ -1524,19 +1549,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"template_if_branch": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "template_if_intro"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_template"
|
||||
}
|
||||
]
|
||||
},
|
||||
"template_if_intro": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
@@ -1582,19 +1594,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"template_else_branch": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "template_else_intro"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_template"
|
||||
}
|
||||
]
|
||||
},
|
||||
"template_else_intro": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
|
||||
@@ -737,33 +737,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "template_else_branch",
|
||||
"named": true,
|
||||
"fields": {},
|
||||
"children": {
|
||||
"multiple": true,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "template_directive",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "template_else_intro",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "template_interpolation",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "template_literal",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "template_else_intro",
|
||||
"named": true,
|
||||
@@ -900,31 +873,16 @@
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "template_else_branch",
|
||||
"type": "template_directive",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "template_if_branch",
|
||||
"type": "template_else_intro",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "template_if_end",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "template_if_branch",
|
||||
"named": true,
|
||||
"fields": {},
|
||||
"children": {
|
||||
"multiple": true,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "template_directive",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "template_if_intro",
|
||||
|
||||
19727
src/parser.c
19727
src/parser.c
File diff suppressed because it is too large
Load Diff
@@ -466,20 +466,304 @@ foo = "%{if cond } foo %{else} bar %{endif}"
|
||||
(quoted_template_start)
|
||||
(template_directive
|
||||
(template_if
|
||||
(template_if_branch
|
||||
(template_if_intro
|
||||
(template_directive_start)
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier)))
|
||||
(template_directive_end))
|
||||
(template_literal))
|
||||
(template_else_branch
|
||||
(template_literal)
|
||||
(template_else_intro
|
||||
(template_directive_start)
|
||||
(template_directive_end))
|
||||
(template_literal))
|
||||
(template_literal)
|
||||
(template_if_end
|
||||
(template_directive_start)
|
||||
(template_directive_end))))
|
||||
(quoted_template_end)))))))
|
||||
|
||||
================================================================================
|
||||
template nested for directives with interlaced chunks
|
||||
================================================================================
|
||||
|
||||
foo = "%{for a in b} x %{for c in a} ${c} %{endfor} %{endfor}"
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(config_file
|
||||
(body
|
||||
(attribute
|
||||
(identifier)
|
||||
(expression
|
||||
(template_expr
|
||||
(quoted_template
|
||||
(quoted_template_start)
|
||||
(template_directive
|
||||
(template_for
|
||||
(template_for_start
|
||||
(template_directive_start)
|
||||
(identifier)
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier)))
|
||||
(template_directive_end))
|
||||
(template_literal)
|
||||
(template_directive
|
||||
(template_for
|
||||
(template_for_start
|
||||
(template_directive_start)
|
||||
(identifier)
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier)))
|
||||
(template_directive_end))
|
||||
(template_interpolation
|
||||
(template_interpolation_start)
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier)))
|
||||
(template_interpolation_end))
|
||||
(template_for_end
|
||||
(template_directive_start)
|
||||
(template_directive_end))))
|
||||
(template_for_end
|
||||
(template_directive_start)
|
||||
(template_directive_end))))
|
||||
(quoted_template_end)))))))
|
||||
|
||||
================================================================================
|
||||
template nested if directives with interlaced chunks
|
||||
================================================================================
|
||||
|
||||
foo = "%{if a} %{if b} y %{else} x %{endif} %{endif}"
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(config_file
|
||||
(body
|
||||
(attribute
|
||||
(identifier)
|
||||
(expression
|
||||
(template_expr
|
||||
(quoted_template
|
||||
(quoted_template_start)
|
||||
(template_directive
|
||||
(template_if
|
||||
(template_if_intro
|
||||
(template_directive_start)
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier)))
|
||||
(template_directive_end))
|
||||
(template_directive
|
||||
(template_if
|
||||
(template_if_intro
|
||||
(template_directive_start)
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier)))
|
||||
(template_directive_end))
|
||||
(template_literal)
|
||||
(template_else_intro
|
||||
(template_directive_start)
|
||||
(template_directive_end))
|
||||
(template_literal)
|
||||
(template_if_end
|
||||
(template_directive_start)
|
||||
(template_directive_end))))
|
||||
(template_if_end
|
||||
(template_directive_start)
|
||||
(template_directive_end))))
|
||||
(quoted_template_end)))))))
|
||||
|
||||
================================================================================
|
||||
template empty if else statement
|
||||
================================================================================
|
||||
|
||||
foo = "%{if a} %{else} %{endif}"
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(config_file
|
||||
(body
|
||||
(attribute
|
||||
(identifier)
|
||||
(expression
|
||||
(template_expr
|
||||
(quoted_template
|
||||
(quoted_template_start)
|
||||
(template_directive
|
||||
(template_if
|
||||
(template_if_intro
|
||||
(template_directive_start)
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier)))
|
||||
(template_directive_end))
|
||||
(template_else_intro
|
||||
(template_directive_start)
|
||||
(template_directive_end))
|
||||
(template_if_end
|
||||
(template_directive_start)
|
||||
(template_directive_end))))
|
||||
(quoted_template_end)))))))
|
||||
|
||||
================================================================================
|
||||
template empty for statement
|
||||
================================================================================
|
||||
|
||||
foo = "%{for a in b} %{endfor}"
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(config_file
|
||||
(body
|
||||
(attribute
|
||||
(identifier)
|
||||
(expression
|
||||
(template_expr
|
||||
(quoted_template
|
||||
(quoted_template_start)
|
||||
(template_directive
|
||||
(template_for
|
||||
(template_for_start
|
||||
(template_directive_start)
|
||||
(identifier)
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier)))
|
||||
(template_directive_end))
|
||||
(template_for_end
|
||||
(template_directive_start)
|
||||
(template_directive_end))))
|
||||
(quoted_template_end)))))))
|
||||
|
||||
================================================================================
|
||||
template parenthesis in heredoc for directive with nested if 1
|
||||
================================================================================
|
||||
|
||||
tpl6 = <<-EOF
|
||||
%{ for a in f(b) ~}
|
||||
( %{~if a~} "true" %{~else~} "false" %{~endif~} )
|
||||
%{ endfor ~}
|
||||
EOF
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(config_file
|
||||
(body
|
||||
(attribute
|
||||
(identifier)
|
||||
(expression
|
||||
(template_expr
|
||||
(heredoc_template
|
||||
(heredoc_start)
|
||||
(heredoc_identifier)
|
||||
(template_directive
|
||||
(template_for
|
||||
(template_for_start
|
||||
(template_directive_start)
|
||||
(identifier)
|
||||
(expression
|
||||
(function_call
|
||||
(identifier)
|
||||
(function_arguments
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier))))))
|
||||
(strip_marker)
|
||||
(template_directive_end))
|
||||
(template_literal)
|
||||
(template_directive
|
||||
(template_if
|
||||
(template_if_intro
|
||||
(template_directive_start)
|
||||
(strip_marker)
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier)))
|
||||
(strip_marker)
|
||||
(template_directive_end))
|
||||
(template_literal)
|
||||
(template_else_intro
|
||||
(template_directive_start)
|
||||
(strip_marker)
|
||||
(strip_marker)
|
||||
(template_directive_end))
|
||||
(template_literal)
|
||||
(template_if_end
|
||||
(template_directive_start)
|
||||
(strip_marker)
|
||||
(strip_marker)
|
||||
(template_directive_end))))
|
||||
(template_literal)
|
||||
(template_for_end
|
||||
(template_directive_start)
|
||||
(strip_marker)
|
||||
(template_directive_end))))
|
||||
(heredoc_identifier)))))))
|
||||
|
||||
================================================================================
|
||||
template parenthesis in heredoc for directive with nested if 2
|
||||
================================================================================
|
||||
|
||||
tpl6 = <<-EOF
|
||||
%{ for a in f(b) ~}
|
||||
("foo")
|
||||
%{~if a~} "true" %{~else~} "false" %{~endif~}
|
||||
%{ endfor ~}
|
||||
EOF
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(config_file
|
||||
(body
|
||||
(attribute
|
||||
(identifier)
|
||||
(expression
|
||||
(template_expr
|
||||
(heredoc_template
|
||||
(heredoc_start)
|
||||
(heredoc_identifier)
|
||||
(template_directive
|
||||
(template_for
|
||||
(template_for_start
|
||||
(template_directive_start)
|
||||
(identifier)
|
||||
(expression
|
||||
(function_call
|
||||
(identifier)
|
||||
(function_arguments
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier))))))
|
||||
(strip_marker)
|
||||
(template_directive_end))
|
||||
(template_literal)
|
||||
(template_directive
|
||||
(template_if
|
||||
(template_if_intro
|
||||
(template_directive_start)
|
||||
(strip_marker)
|
||||
(expression
|
||||
(variable_expr
|
||||
(identifier)))
|
||||
(strip_marker)
|
||||
(template_directive_end))
|
||||
(template_literal)
|
||||
(template_else_intro
|
||||
(template_directive_start)
|
||||
(strip_marker)
|
||||
(strip_marker)
|
||||
(template_directive_end))
|
||||
(template_literal)
|
||||
(template_if_end
|
||||
(template_directive_start)
|
||||
(strip_marker)
|
||||
(strip_marker)
|
||||
(template_directive_end))))
|
||||
(template_for_end
|
||||
(template_directive_start)
|
||||
(strip_marker)
|
||||
(template_directive_end))))
|
||||
(heredoc_identifier)))))))
|
||||
|
||||
Reference in New Issue
Block a user