fmt tests; properly define string literals; work on scanner

This commit is contained in:
mhoffm
2021-06-17 19:39:46 +02:00
parent 4801d16825
commit 88401e3bf3
20 changed files with 8036 additions and 5094 deletions

10
.editorconfig Normal file
View File

@@ -0,0 +1,10 @@
root = true
[*.{c,txt,js}]
indent_style = space
indent_size = 2
tab_width = 8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8

View File

@@ -6,7 +6,7 @@ tree-sitter grammar for the [HCL](https://github.com/hashicorp/hcl/blob/main/hcl
Highlighting `example/example.hcl`: Highlighting `example/example.hcl`:
![Highlighting Example](https://i.imgur.com/M1PZkqL.png) ![Highlighting Example](https://i.imgur.com/sgFcxLK.png)
## Developing ## Developing
@@ -16,17 +16,6 @@ It is recommended to use `nix` to fulfill all development dependencies. To activ
To run tests simply run `nix-shell --run 'tree-sitter test'`. To run tests simply run `nix-shell --run 'tree-sitter test'`.
## Quoted Template Expressions
In principle it is allowed to contain arbitary expressions in quoted template interpolations. Consider for example:
```hcl
foo = "prefix-${func(\"bar\")}"
```
To make parsing a little easier, this parser only checks for valid escape sequences and template chars.
When using this parser one would have to take the content of a template interpolation, unescape it and parse it again to get the syntax tree. The same applies to template directives.
## Todo ## Todo
* [ ] use [Unicode® Standard Annex #31](https://www.unicode.org/reports/tr31/) (augmented with '-') for identifiers * [ ] use [Unicode® Standard Annex #31](https://www.unicode.org/reports/tr31/) (augmented with '-') for identifiers

View File

@@ -26,7 +26,8 @@ resource_1 "strlit1" "strlit2" {
esc1 = "\" \t \UFF11FF22 \uFFFF \n" esc1 = "\" \t \UFF11FF22 \uFFFF \n"
esc2 = "$${} %%{}" esc2 = "$${} %%{}"
tpl1 = "prefix-${var.bar}" tpl1 = "prefix-${var.bar}"
tpl2 = "prefix-${func(\"bar\")}" tpl2 = "prefix-${func("bar")}"
tpl3 = "prefix-${func("nested-${var.bar}")}"
nested_resource_1 { nested_resource_1 {
attr1 = 2 attr1 = 2

View File

@@ -25,9 +25,11 @@ module.exports = grammar({
], ],
externals: $ => [ externals: $ => [
$._template_char, $._quoted_template_start,
$._template_char_in_interpolation, $._quoted_template_end,
$.escape_sequence, $._template_literal_chunk,
$._template_interpolation_start,
$._template_interpolation_end,
], ],
extras: $ => [ extras: $ => [
@@ -54,11 +56,14 @@ module.exports = grammar({
block: $ => seq( block: $ => seq(
field('name', $.identifier), field('name', $.identifier),
repeat(choice($.string_lit, $.identifier)), repeat(choice($.string_lit, $.identifier)),
'{', $._block_start,
optional($.body), optional($.body),
'}', $._block_end,
), ),
_block_start: $ => '{',
_block_end: $ => '}',
// TODO: not to spec but good enough for now // TODO: not to spec but good enough for now
identifier: $ => token(seq( identifier: $ => token(seq(
unicodeLetter, unicodeLetter,
@@ -66,21 +71,21 @@ module.exports = grammar({
)), )),
expression: $ => choice( expression: $ => choice(
$.expr_term, $._expr_term,
$.operation, $.operation,
$.conditional, $.conditional,
), ),
expr_term: $ => choice( _expr_term: $ => choice(
$.literal_value, $.literal_value,
$.template_expr, $.template_expr,
$.collection_value, $.collection_value,
$.variable_expr, $.variable_expr,
$.function_call, $.function_call,
$.for_expr, $.for_expr,
seq($.expr_term, $.index), seq($._expr_term, $.index),
seq($.expr_term, $.get_attr), seq($._expr_term, $.get_attr),
seq($.expr_term, $.splat), seq($._expr_term, $.splat),
seq('(', $.expression, ')'), seq('(', $.expression, ')'),
), ),
@@ -88,6 +93,7 @@ module.exports = grammar({
$.numeric_lit, $.numeric_lit,
$.bool_lit, $.bool_lit,
$.null_lit, $.null_lit,
$.string_lit,
), ),
numeric_lit: $ => /[0-9]+(\.[0-9]+([eE][-+]?[0-9]+)?)?/, numeric_lit: $ => /[0-9]+(\.[0-9]+([eE][-+]?[0-9]+)?)?/,
@@ -96,7 +102,12 @@ module.exports = grammar({
null_lit: $ => 'null', null_lit: $ => 'null',
// string_lit is defined as quoted template string_lit: $ => seq(
$._quoted_template_start,
$.template_literal,
$._quoted_template_end,
),
collection_value: $ => choice( collection_value: $ => choice(
$.tuple, $.tuple,
@@ -113,14 +124,17 @@ module.exports = grammar({
), ),
object: $ => seq( object: $ => seq(
'{', $._object_start,
optional(seq( optional(seq(
$.object_elem, $.object_elem,
repeat(seq(',', $.object_elem)), repeat(seq(',', $.object_elem)),
)), )),
'}', $._object_end,
), ),
_object_start: $ => '{',
_object_end: $ => '}',
object_elem: $ => seq( object_elem: $ => seq(
choice($.identifier, $.expression), choice($.identifier, $.expression),
choice('=', ':'), choice('=', ':'),
@@ -157,14 +171,14 @@ module.exports = grammar({
), ),
for_object_expr: $ => seq( for_object_expr: $ => seq(
'{', $._object_start,
$.for_intro, $.for_intro,
$.expression, $.expression,
'=>', '=>',
$.expression, $.expression,
optional($.ellipsis), optional($.ellipsis),
optional($.for_cond), optional($.for_cond),
'}', $._object_end,
), ),
for_intro: $ => seq( for_intro: $ => seq(
@@ -185,11 +199,14 @@ module.exports = grammar({
function_call: $ => seq( function_call: $ => seq(
field('name', $.identifier), field('name', $.identifier),
'(', $._function_call_start,
optional($.function_arguments), optional($.function_arguments),
')' $._function_call_end,
), ),
_function_call_start: $ => '(',
_function_call_end: $ => ')',
function_arguments: $ => seq( function_arguments: $ => seq(
$.expression, $.expression,
repeat(seq(',', $.expression)), repeat(seq(',', $.expression)),
@@ -208,7 +225,7 @@ module.exports = grammar({
operation: $ => choice($.unary_operation, $.binary_operation), operation: $ => choice($.unary_operation, $.binary_operation),
unary_operation: $ => prec.left(PREC.unary, seq(choice('-', '!'), $.expr_term)), unary_operation: $ => prec.left(PREC.unary, seq(choice('-', '!'), $._expr_term)),
binary_operation: $ => { binary_operation: $ => {
const table = [ const table = [
@@ -221,7 +238,7 @@ module.exports = grammar({
]; ];
return choice(...table.map(([precedence, operator]) => return choice(...table.map(([precedence, operator]) =>
prec.left(precedence, seq($.expr_term, operator, $.expr_term), prec.left(precedence, seq($._expr_term, operator, $._expr_term),
)) ))
); );
}, },
@@ -231,31 +248,37 @@ module.exports = grammar({
// $.heredoc_template, // $.heredoc_template,
), ),
string_lit: $ => seq( quoted_template: $ => seq(
'"', $._quoted_template_start,
repeat(choice( repeat(choice(
$._template_char, $.template_literal,
$.escape_sequence, $.template_interpolation,
$.template_directive,
)), )),
'"', $._quoted_template_end,
), ),
quoted_template: $ => seq( strip_marker: $ => '~',
'"',
repeat(choice( template_literal: $ => prec.right(repeat1(
$._template_char, $._template_literal_chunk,
$.escape_sequence, )),
$.template_interpolation,
)),
'"',
),
template_interpolation: $ => seq( template_interpolation: $ => seq(
choice('${', '${~'), $._template_interpolation_start,
repeat(choice($._template_char_in_interpolation, $.escape_sequence)), optional($.strip_marker),
choice('}', '~}'), $.expression,
optional($.strip_marker),
$._template_interpolation_end,
), ),
// TODO
template_directive: $ => choice(
//$.template_for,
//$.template_if,
),
// http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890 // http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890
comment: $ => token(choice( comment: $ => token(choice(
seq('#', /.*/), seq('#', /.*/),

View File

@@ -13,7 +13,7 @@ in
]; ];
shellHook = '' shellHook = ''
PATH=./node_modules/.bin:$PATH PATH=./node_modules/.bin:$PATH
command -v tree-sitter >/dev/null 2>&1 || npm install tree-sitter-cli command -v tree-sitter >/dev/null 2>&1 || npm install tree-sitter-cli@0.19.5
''; '';
} }

View File

@@ -75,8 +75,8 @@
} }
}, },
{ {
"type": "STRING", "type": "SYMBOL",
"value": "{" "name": "_block_start"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@@ -91,11 +91,19 @@
] ]
}, },
{ {
"type": "STRING", "type": "SYMBOL",
"value": "}" "name": "_block_end"
} }
] ]
}, },
"_block_start": {
"type": "STRING",
"value": "{"
},
"_block_end": {
"type": "STRING",
"value": "}"
},
"identifier": { "identifier": {
"type": "TOKEN", "type": "TOKEN",
"content": { "content": {
@@ -133,7 +141,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@@ -145,7 +153,7 @@
} }
] ]
}, },
"expr_term": { "_expr_term": {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
{ {
@@ -177,7 +185,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@@ -190,7 +198,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@@ -203,7 +211,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@@ -244,6 +252,10 @@
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "null_lit" "name": "null_lit"
},
{
"type": "SYMBOL",
"name": "string_lit"
} }
] ]
}, },
@@ -268,6 +280,23 @@
"type": "STRING", "type": "STRING",
"value": "null" "value": "null"
}, },
"string_lit": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_quoted_template_start"
},
{
"type": "SYMBOL",
"name": "template_literal"
},
{
"type": "SYMBOL",
"name": "_quoted_template_end"
}
]
},
"collection_value": { "collection_value": {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
@@ -331,8 +360,8 @@
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "STRING", "type": "SYMBOL",
"value": "{" "name": "_object_start"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@@ -368,11 +397,19 @@
] ]
}, },
{ {
"type": "STRING", "type": "SYMBOL",
"value": "}" "name": "_object_end"
} }
] ]
}, },
"_object_start": {
"type": "STRING",
"value": "{"
},
"_object_end": {
"type": "STRING",
"value": "}"
},
"object_elem": { "object_elem": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
@@ -554,8 +591,8 @@
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "STRING", "type": "SYMBOL",
"value": "{" "name": "_object_start"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@@ -598,8 +635,8 @@
] ]
}, },
{ {
"type": "STRING", "type": "SYMBOL",
"value": "}" "name": "_object_end"
} }
] ]
}, },
@@ -678,8 +715,8 @@
} }
}, },
{ {
"type": "STRING", "type": "SYMBOL",
"value": "(" "name": "_function_call_start"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@@ -694,11 +731,19 @@
] ]
}, },
{ {
"type": "STRING", "type": "SYMBOL",
"value": ")" "name": "_function_call_end"
} }
] ]
}, },
"_function_call_start": {
"type": "STRING",
"value": "("
},
"_function_call_end": {
"type": "STRING",
"value": ")"
},
"function_arguments": { "function_arguments": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
@@ -811,7 +856,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
} }
] ]
} }
@@ -827,7 +872,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@@ -848,7 +893,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
} }
] ]
} }
@@ -861,7 +906,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@@ -878,7 +923,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
} }
] ]
} }
@@ -891,7 +936,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@@ -916,7 +961,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
} }
] ]
} }
@@ -929,7 +974,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@@ -946,7 +991,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
} }
] ]
} }
@@ -959,7 +1004,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@@ -972,7 +1017,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
} }
] ]
} }
@@ -985,7 +1030,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@@ -998,7 +1043,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expr_term" "name": "_expr_term"
} }
] ]
} }
@@ -1014,41 +1059,12 @@
} }
] ]
}, },
"string_lit": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "\""
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_template_char"
},
{
"type": "SYMBOL",
"name": "escape_sequence"
}
]
}
},
{
"type": "STRING",
"value": "\""
}
]
},
"quoted_template": { "quoted_template": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "STRING", "type": "SYMBOL",
"value": "\"" "name": "_quoted_template_start"
}, },
{ {
"type": "REPEAT", "type": "REPEAT",
@@ -1057,72 +1073,85 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "_template_char" "name": "template_literal"
},
{
"type": "SYMBOL",
"name": "escape_sequence"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "template_interpolation" "name": "template_interpolation"
},
{
"type": "SYMBOL",
"name": "template_directive"
} }
] ]
} }
}, },
{ {
"type": "STRING", "type": "SYMBOL",
"value": "\"" "name": "_quoted_template_end"
} }
] ]
}, },
"strip_marker": {
"type": "STRING",
"value": "~"
},
"template_literal": {
"type": "PREC_RIGHT",
"value": 0,
"content": {
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "_template_literal_chunk"
}
}
},
"template_interpolation": { "template_interpolation": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "CHOICE", "type": "SYMBOL",
"members": [ "name": "_template_interpolation_start"
{
"type": "STRING",
"value": "${"
},
{
"type": "STRING",
"value": "${~"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_template_char_in_interpolation"
},
{
"type": "SYMBOL",
"name": "escape_sequence"
}
]
}
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
{ {
"type": "STRING", "type": "SYMBOL",
"value": "}" "name": "strip_marker"
}, },
{ {
"type": "STRING", "type": "BLANK"
"value": "~}"
} }
] ]
},
{
"type": "SYMBOL",
"name": "expression"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "strip_marker"
},
{
"type": "BLANK"
}
]
},
{
"type": "SYMBOL",
"name": "_template_interpolation_end"
} }
] ]
}, },
"template_directive": {
"type": "CHOICE",
"members": []
},
"comment": { "comment": {
"type": "TOKEN", "type": "TOKEN",
"content": { "content": {
@@ -1211,15 +1240,23 @@
"externals": [ "externals": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "_template_char" "name": "_quoted_template_start"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "_template_char_in_interpolation" "name": "_quoted_template_end"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "escape_sequence" "name": "_template_literal_chunk"
},
{
"type": "SYMBOL",
"name": "_template_interpolation_start"
},
{
"type": "SYMBOL",
"name": "_template_interpolation_end"
} }
], ],
"inline": [], "inline": [],

View File

@@ -49,7 +49,43 @@
"required": true, "required": true,
"types": [ "types": [
{ {
"type": "expr_term", "type": "collection_value",
"named": true
},
{
"type": "expression",
"named": true
},
{
"type": "for_expr",
"named": true
},
{
"type": "function_call",
"named": true
},
{
"type": "get_attr",
"named": true
},
{
"type": "index",
"named": true
},
{
"type": "literal_value",
"named": true
},
{
"type": "splat",
"named": true
},
{
"type": "template_expr",
"named": true
},
{
"type": "variable_expr",
"named": true "named": true
} }
] ]
@@ -163,7 +199,7 @@
} }
}, },
{ {
"type": "expr_term", "type": "expression",
"named": true, "named": true,
"fields": {}, "fields": {},
"children": { "children": {
@@ -175,7 +211,7 @@
"named": true "named": true
}, },
{ {
"type": "expr_term", "type": "conditional",
"named": true "named": true
}, },
{ {
@@ -202,6 +238,10 @@
"type": "literal_value", "type": "literal_value",
"named": true "named": true
}, },
{
"type": "operation",
"named": true
},
{ {
"type": "splat", "type": "splat",
"named": true "named": true
@@ -217,29 +257,6 @@
] ]
} }
}, },
{
"type": "expression",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "conditional",
"named": true
},
{
"type": "expr_term",
"named": true
},
{
"type": "operation",
"named": true
}
]
}
},
{ {
"type": "for_cond", "type": "for_cond",
"named": true, "named": true,
@@ -456,6 +473,10 @@
{ {
"type": "numeric_lit", "type": "numeric_lit",
"named": true "named": true
},
{
"type": "string_lit",
"named": true
} }
] ]
} }
@@ -522,12 +543,16 @@
"required": false, "required": false,
"types": [ "types": [
{ {
"type": "escape_sequence", "type": "template_directive",
"named": true "named": true
}, },
{ {
"type": "template_interpolation", "type": "template_interpolation",
"named": true "named": true
},
{
"type": "template_literal",
"named": true
} }
] ]
} }
@@ -556,16 +581,21 @@
"named": true, "named": true,
"fields": {}, "fields": {},
"children": { "children": {
"multiple": true, "multiple": false,
"required": false, "required": true,
"types": [ "types": [
{ {
"type": "escape_sequence", "type": "template_literal",
"named": true "named": true
} }
] ]
} }
}, },
{
"type": "template_directive",
"named": true,
"fields": {}
},
{ {
"type": "template_expr", "type": "template_expr",
"named": true, "named": true,
@@ -587,15 +617,24 @@
"fields": {}, "fields": {},
"children": { "children": {
"multiple": true, "multiple": true,
"required": false, "required": true,
"types": [ "types": [
{ {
"type": "escape_sequence", "type": "expression",
"named": true
},
{
"type": "strip_marker",
"named": true "named": true
} }
] ]
} }
}, },
{
"type": "template_literal",
"named": true,
"fields": {}
},
{ {
"type": "tuple", "type": "tuple",
"named": true, "named": true,
@@ -616,11 +655,47 @@
"named": true, "named": true,
"fields": {}, "fields": {},
"children": { "children": {
"multiple": false, "multiple": true,
"required": true, "required": true,
"types": [ "types": [
{ {
"type": "expr_term", "type": "collection_value",
"named": true
},
{
"type": "expression",
"named": true
},
{
"type": "for_expr",
"named": true
},
{
"type": "function_call",
"named": true
},
{
"type": "get_attr",
"named": true
},
{
"type": "index",
"named": true
},
{
"type": "literal_value",
"named": true
},
{
"type": "splat",
"named": true
},
{
"type": "template_expr",
"named": true
},
{
"type": "variable_expr",
"named": true "named": true
} }
] ]
@@ -649,18 +724,6 @@
"type": "!=", "type": "!=",
"named": false "named": false
}, },
{
"type": "\"",
"named": false
},
{
"type": "${",
"named": false
},
{
"type": "${~",
"named": false
},
{ {
"type": "%", "type": "%",
"named": false "named": false
@@ -753,10 +816,6 @@
"type": "ellipsis", "type": "ellipsis",
"named": true "named": true
}, },
{
"type": "escape_sequence",
"named": true
},
{ {
"type": "false", "type": "false",
"named": false "named": false
@@ -785,6 +844,10 @@
"type": "numeric_lit", "type": "numeric_lit",
"named": true "named": true
}, },
{
"type": "strip_marker",
"named": true
},
{ {
"type": "true", "type": "true",
"named": false "named": false
@@ -800,9 +863,5 @@
{ {
"type": "}", "type": "}",
"named": false "named": false
},
{
"type": "~}",
"named": false
} }
] ]

11254
src/parser.c

File diff suppressed because it is too large Load Diff

View File

@@ -1,144 +1,204 @@
#include <tree_sitter/parser.h> #include <tree_sitter/parser.h>
#include <wctype.h> #include <wctype.h>
#include <string.h>
#include <stdio.h>
enum TokenType { enum TokenType {
TEMPLATE_CHAR, QUOTED_TEMPLATE_START,
TEMPLATE_CHAR_IN_INTERPOLATION, QUOTED_TEMPLATE_END,
ESCAPE_SEQUENCE TEMPLATE_LITERAL_CHUNK,
TEMPLATE_INTERPOLATION_START,
TEMPLATE_INTERPOLATION_END,
}; };
static void advance(TSLexer *lexer) { lexer->advance(lexer, false); } static void advance(TSLexer *lexer) { lexer->advance(lexer, false); }
static bool accept_template_char_inplace(TSLexer *lexer) { static void skip(TSLexer *lexer) { lexer->advance(lexer, true); }
lexer->result_symbol = TEMPLATE_CHAR;
return true; static bool accept_inplace(TSLexer *lexer, enum TokenType token) {
lexer->result_symbol = token;
return true;
} }
static bool advance_and_accept_template_char(TSLexer *lexer) { static bool accept_and_advance(TSLexer *lexer, enum TokenType token) {
advance(lexer); advance(lexer);
return accept_template_char_inplace(lexer); return accept_inplace(lexer, token);
}
static bool advance_and_accept_escape_sequence(TSLexer *lexer) {
advance(lexer);
lexer->result_symbol = ESCAPE_SEQUENCE;
return true;
}
static bool advance_and_accept_template_char_in_interpolation(TSLexer *lexer) {
advance(lexer);
lexer->result_symbol = TEMPLATE_CHAR_IN_INTERPOLATION;
return true;
} }
static bool consume_wxdigit(TSLexer *lexer) { static bool consume_wxdigit(TSLexer *lexer) {
advance(lexer); advance(lexer);
return iswxdigit(lexer->lookahead); return iswxdigit(lexer->lookahead);
} }
// scan escape sequences \n \t \r \\ \" \uHHHH or \UHHHHHHHHA where H is a hex digit typedef struct Scanner {
// assumes that the leading character is '\' bool in_template_interpolation;
static bool scan_backslash_escape_sequence(TSLexer *lexer) { bool in_quoted_context;
advance(lexer); int template_interpolation_depth;
switch (lexer->lookahead) { int quoted_context_depth;
case '"': } Scanner;
case 'n':
case 'r': void print_debug_info(Scanner *scanner, TSLexer *lexer, const bool *valid_symbols) {
case 't': printf("\nDEBUG INFO START\n\n");
case '\\': printf("currently at: '%c'\n\n", lexer->lookahead);
return advance_and_accept_escape_sequence(lexer); printf("could be one of\n");
case 'u': printf("quoted_template_start: %x\n", valid_symbols[QUOTED_TEMPLATE_START]);
for (int i = 0; i < 4; i++) { printf("quoted_template_end: %x\n", valid_symbols[QUOTED_TEMPLATE_END]);
if (!consume_wxdigit(lexer)) return false; printf("template_literal_chunk: %x", valid_symbols[TEMPLATE_LITERAL_CHUNK]);
} printf("template_interpolation_start: %x\n", valid_symbols[TEMPLATE_INTERPOLATION_START]);
return advance_and_accept_escape_sequence(lexer); printf("template_interpolation_end: %x\n", valid_symbols[TEMPLATE_INTERPOLATION_END]);
case 'U': printf("\n");
for (int i = 0; i < 8; i++) { printf("scanner state:\n");
if (!consume_wxdigit(lexer)) return false; printf("in_template_interpolation %x\n", scanner->in_template_interpolation);
} printf("in_quoted_context %x\n", scanner->in_quoted_context);
return advance_and_accept_escape_sequence(lexer); printf("template_interpolation_depth %x\n", scanner->template_interpolation_depth);
default: printf("quoted_context_depth %x\n", scanner->quoted_context_depth);
return false; printf("\nDEBUG INFO END\n\n");
}
// some helpers to keep track of template depth
void scanner_enter_interpolation_context(Scanner *scanner) {
scanner->template_interpolation_depth++;
scanner->in_template_interpolation = true;
scanner->in_quoted_context = false;
}
void scanner_exit_interpolation_context(Scanner *scanner) {
scanner->template_interpolation_depth--;
scanner->in_template_interpolation = false;
scanner->in_quoted_context = true;
}
void scanner_enter_quoted_context(Scanner *scanner) {
scanner->quoted_context_depth++;
scanner->in_quoted_context = true;
scanner->in_template_interpolation = false;
}
void scanner_exit_quoted_context(Scanner *scanner) {
scanner->quoted_context_depth--;
scanner->in_quoted_context = false;
// check if we are reentering a nested template interpolation
if (scanner->template_interpolation_depth > 0) {
scanner->in_template_interpolation = true;
} }
} }
// may accept multiple characters like %% as a 'template literal chunk' bool must_escape_in_nested_quoted_context(char c) {
// assumes that the leading character is '%' or '$' switch (c) {
static bool scan_template_literal_chunk_or_template_escape_sequence(TSLexer *lexer) {
const leading_char = lexer->lookahead;
advance(lexer);
// reject %{ because its the start of template directives
if (lexer->lookahead == '{') return false;
if (lexer->lookahead == leading_char) {
advance(lexer);
// accept %%{ as escape sequence
if (lexer->lookahead == '{') return advance_and_accept_escape_sequence(lexer);
}
// accept % and %% as template chars
return accept_template_char_inplace(lexer);
}
static bool scan_template_char_or_escape_sequence(TSLexer *lexer) {
switch (lexer->lookahead) {
case '"':
case '\n': case '\n':
case '\r': case '\r':
case '\t': case '\t':
return false; return true;
case '\\':
return scan_backslash_escape_sequence(lexer);
case '$':
case '%':
return scan_template_literal_chunk_or_template_escape_sequence(lexer);
default: default:
return advance_and_accept_template_char(lexer); return false;
} }
} }
static bool scan_template_char_in_interpolation_or_escape_sequence(TSLexer *lexer) { bool scanner_scan(Scanner *scanner, TSLexer *lexer, const bool *valid_symbols) {
switch (lexer->lookahead) { // literal newlines are not allowed inside a quoted context
case '"': if (must_escape_in_nested_quoted_context(lexer->lookahead) && scanner->quoted_context_depth > 0) {
case '\n': return false;
case '\r':
case '\t':
// no template interpolation chars are allowed in template interpolations ( even escaped )
case '$':
case '%':
case '~':
return false;
// '}' ends the template interpolation
case '}':
return false;
case '\\':
return scan_backslash_escape_sequence(lexer);
default:
return advance_and_accept_template_char_in_interpolation(lexer);
} }
} while (iswspace(lexer->lookahead) && !scanner->in_quoted_context) skip(lexer);
// scanner // manage quoted context
if (valid_symbols[QUOTED_TEMPLATE_START] && lexer->lookahead == '"') {
void *tree_sitter_hcl_external_scanner_create() { return NULL; } scanner_enter_quoted_context(scanner);
void tree_sitter_hcl_external_scanner_destroy(void *p) {} return accept_and_advance(lexer, QUOTED_TEMPLATE_START);
void tree_sitter_hcl_external_scanner_reset(void *p) {}
unsigned tree_sitter_hcl_external_scanner_serialize(void *p, char *b) { return 0; }
void tree_sitter_hcl_external_scanner_deserialize(void *p, const char *b, unsigned n) {}
bool tree_sitter_hcl_external_scanner_scan(
void *p,
TSLexer *lexer,
const bool *valid_symbols
) {
// when scanning string literals or quoted template literals that are not in an template directive
if (valid_symbols[TEMPLATE_CHAR] && valid_symbols[ESCAPE_SEQUENCE]) {
return scan_template_char_or_escape_sequence(lexer);
} }
// quoted template literals currently inside a template directive if (valid_symbols[QUOTED_TEMPLATE_END] && lexer->lookahead == '"') {
if (valid_symbols[TEMPLATE_CHAR_IN_INTERPOLATION] && valid_symbols[ESCAPE_SEQUENCE]) { scanner_exit_quoted_context(scanner);
return scan_template_char_in_interpolation_or_escape_sequence(lexer); return accept_and_advance(lexer, QUOTED_TEMPLATE_END);
}
if (valid_symbols[TEMPLATE_INTERPOLATION_START] && lexer->lookahead == '$') {
advance(lexer);
if (lexer->lookahead == '{') {
scanner_enter_interpolation_context(scanner);
return accept_and_advance(lexer, TEMPLATE_INTERPOLATION_START);
}
if (valid_symbols[TEMPLATE_LITERAL_CHUNK]) {
// try to scan escape sequence
if (lexer->lookahead == '$') {
advance(lexer);
if (lexer->lookahead == '{') {
// $${
return accept_and_advance(lexer, TEMPLATE_LITERAL_CHUNK);
}
}
return accept_inplace(lexer, TEMPLATE_LITERAL_CHUNK);
}
}
if (valid_symbols[TEMPLATE_INTERPOLATION_END] && lexer->lookahead == '}') {
scanner_exit_interpolation_context(scanner);
return accept_and_advance(lexer, TEMPLATE_INTERPOLATION_END);
}
// handle escape sequences in direct surrounding quoted contexts
if (valid_symbols[TEMPLATE_LITERAL_CHUNK] && scanner->quoted_context_depth > 0) {
switch (lexer->lookahead) {
case '"':
case '\n':
case '\r':
case '\t':
return false;
case '\\':
advance(lexer);
switch (lexer->lookahead) {
case '"':
case 'n':
case 'r':
case 't':
case '\\':
return accept_and_advance(lexer, TEMPLATE_LITERAL_CHUNK);
case 'u':
for (int i = 0; i < 4; i++) {
if (!consume_wxdigit(lexer)) return false;
}
return accept_and_advance(lexer, TEMPLATE_LITERAL_CHUNK);
case 'U':
for (int i = 0; i < 8; i++) {
if (!consume_wxdigit(lexer)) return false;
}
return accept_and_advance(lexer, TEMPLATE_LITERAL_CHUNK);
default:
return false;
}
case '$':
// handled above
default:
return accept_and_advance(lexer, TEMPLATE_LITERAL_CHUNK);
}
} }
return false; return false;
} }
void *tree_sitter_hcl_external_scanner_create() {
Scanner *scanner = (Scanner*)malloc(sizeof(Scanner));
if (scanner) {
scanner->in_template_interpolation = false;
scanner->in_quoted_context = false;
scanner->template_interpolation_depth = 0;
scanner->quoted_context_depth = 0;
}
return scanner;
}
void tree_sitter_hcl_external_scanner_destroy(void *p) {
free(p);
}
unsigned tree_sitter_hcl_external_scanner_serialize(void *p, char *b) {
memcpy(b, p, sizeof(Scanner)); return sizeof(Scanner);
}
void tree_sitter_hcl_external_scanner_deserialize(void *p, const char *b, unsigned n) {
memcpy(p, b, n);
}
bool tree_sitter_hcl_external_scanner_scan(void *p, TSLexer *lexer, const bool *valid_symbols) {
return scanner_scan((Scanner*)p, lexer, valid_symbols);
}

View File

@@ -1,28 +1,32 @@
================== ================================================================================
attribute with literal attribute with literal
================== ================================================================================
foo = "bar" foo = "bar"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template))))))) (expression
(literal_value
(string_lit
(template_literal)))))))
================== ================================================================================
attribute with variable attribute with variable
================== ================================================================================
foo = bar foo = bar
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (variable_expr (identifier))))))) (expression
(variable_expr
(identifier))))))

View File

@@ -1,61 +1,66 @@
================== ================================================================================
basic block basic block
================== ================================================================================
block_1 { block_1 {
} }
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(block (block
(identifier)))) (identifier))))
================== ================================================================================
basic block on one line basic block on one line
================== ================================================================================
block_1 {} block_1 {}
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(block (block
(identifier)))) (identifier))))
================== ================================================================================
block with attribute block with attribute
================== ================================================================================
block_1 "strlit1" "strlit2" { block_1 "strlit1" "strlit2" {
attr1 = "val1" attr1 = "val1"
} }
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(block (block
(identifier) (identifier)
(string_lit) (string_lit
(string_lit) (template_literal))
(string_lit
(template_literal))
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template))))))))) (expression
(literal_value
(string_lit
(template_literal)))))))))
================== ================================================================================
nested block nested block
================== ================================================================================
block_1 { block_1 {
block_2 { block_2 {
} }
} }
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
@@ -65,15 +70,15 @@ block_1 {
(block (block
(identifier)))))) (identifier))))))
================== ================================================================================
nested block on one line nested block on one line
================== ================================================================================
block_1 { block_1 {
block_2 {} block_2 {}
} }
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
@@ -83,16 +88,16 @@ block_1 {
(block (block
(identifier)))))) (identifier))))))
================== ================================================================================
nested blocks nested blocks
================== ================================================================================
block_1 { block_1 {
block_2 {} block_2 {}
block_3 {} block_3 {}
} }
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body

View File

@@ -1,43 +1,57 @@
================== ================================================================================
collection value tuple collection value tuple
================== ================================================================================
foo = [1, 2, "foo"] foo = [1, 2, "foo"]
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (collection_value
(collection_value (tuple
(tuple (expression
(expression (expr_term (literal_value (numeric_lit)))) (literal_value
(expression (expr_term (literal_value (numeric_lit)))) (numeric_lit)))
(expression (expr_term (template_expr (quoted_template))))))))))) (expression
(literal_value
(numeric_lit)))
(expression
(literal_value
(string_lit
(template_literal))))))))))
================== ================================================================================
collection value object collection value object
================== ================================================================================
foo = {1: 2, "foo"="bar"} foo = {1: 2, "foo"="bar"}
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (collection_value
(collection_value (object
(object (object_elem
(object_elem (expression
(expression (expr_term (literal_value (numeric_lit)))) (literal_value
(expression (expr_term (literal_value (numeric_lit))))) (numeric_lit)))
(object_elem (expression
(expression (expr_term (template_expr (quoted_template)))) (literal_value
(expression (expr_term (template_expr (quoted_template)))))))))))) (numeric_lit))))
(object_elem
(expression
(literal_value
(string_lit
(template_literal))))
(expression
(literal_value
(string_lit
(template_literal)))))))))))

View File

@@ -1,10 +1,10 @@
================== ================================================================================
simple conditional expression simple conditional expression
================== ================================================================================
foo = predicate() ? 1: 2 foo = predicate() ? 1: 2
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
@@ -12,7 +12,12 @@ foo = predicate() ? 1: 2
(identifier) (identifier)
(expression (expression
(conditional (conditional
(expression (expr_term (function_call (identifier)))) (expression
(expression (expr_term (literal_value (numeric_lit)))) (function_call
(expression (expr_term (literal_value (numeric_lit))))))))) (identifier)))
(expression
(literal_value
(numeric_lit)))
(expression
(literal_value
(numeric_lit))))))))

View File

@@ -1,143 +1,182 @@
================== ================================================================================
for tuple expression for tuple expression
================== ================================================================================
foo = [for v in ["a", "b"]: v] foo = [for v in ["a", "b"]: v]
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (for_expr
(for_expr (for_tuple_expr
(for_tuple_expr (for_intro
(for_intro
(identifier) (identifier)
(expression (expression
(expr_term (collection_value
(collection_value (tuple
(tuple (expression
(expression (expr_term (template_expr (quoted_template)))) (literal_value
(expression (expr_term (template_expr (quoted_template))))))))) (string_lit
(expression (expr_term (variable_expr (identifier))))))))))) (template_literal))))
(expression
(literal_value
(string_lit
(template_literal))))))))
(expression
(variable_expr
(identifier)))))))))
================== ================================================================================
for tuple expression with index for tuple expression with index
================== ================================================================================
foo = [for i, v in ["a", "b"]: i] foo = [for i, v in ["a", "b"]: i]
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (for_expr
(for_expr (for_tuple_expr
(for_tuple_expr (for_intro
(for_intro
(identifier) (identifier)
(identifier) (identifier)
(expression (expression
(expr_term (collection_value
(collection_value (tuple
(tuple (expression
(expression (expr_term (template_expr (quoted_template)))) (literal_value
(expression (expr_term (template_expr (quoted_template))))))))) (string_lit
(expression (expr_term (variable_expr (identifier))))))))))) (template_literal))))
(expression
(literal_value
(string_lit
(template_literal))))))))
(expression
(variable_expr
(identifier)))))))))
================== ================================================================================
for tuple expression with predicate for tuple expression with predicate
================== ================================================================================
foo = [for i, v in ["a", "b", "c"]: v if pred(i)] foo = [for i, v in ["a", "b", "c"]: v if pred(i)]
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (for_expr
(for_expr (for_tuple_expr
(for_tuple_expr (for_intro
(for_intro (identifier)
(identifier) (identifier)
(identifier) (expression
(collection_value
(tuple
(expression (expression
(expr_term (literal_value
(collection_value (string_lit
(tuple (template_literal))))
(expression (expr_term (template_expr (quoted_template)))) (expression
(expression (expr_term (template_expr (quoted_template)))) (literal_value
(expression (expr_term (template_expr (quoted_template))))))))) (string_lit
(expression (expr_term (variable_expr (identifier)))) (template_literal))))
(for_cond (expression
(expression (literal_value
(expr_term (string_lit
(function_call (template_literal))))))))
(identifier) (expression
(function_arguments (expression (expr_term (variable_expr (identifier)))))))))))))))) (variable_expr
(identifier)))
(for_cond
(expression
(function_call
(identifier)
(function_arguments
(expression
(variable_expr
(identifier)))))))))))))
================================================================================
==================
for object expression for object expression
================== ================================================================================
foo = {for i, v in ["a", "b"]: v => i} foo = {for i, v in ["a", "b"]: v => i}
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (for_expr
(for_expr (for_object_expr
(for_object_expr (for_intro
(for_intro (identifier)
(identifier) (identifier)
(identifier) (expression
(expression (collection_value
(expr_term (tuple
(collection_value (expression
(tuple (literal_value
(expression (expr_term (template_expr (quoted_template)))) (string_lit
(expression (expr_term (template_expr (quoted_template))))))))) (template_literal))))
(expression (expr_term (variable_expr (identifier)))) (expression
(expression (expr_term (variable_expr (identifier))))))))))) (literal_value
(string_lit
(template_literal))))))))
(expression
(variable_expr
(identifier)))
(expression
(variable_expr
(identifier)))))))))
================== ================================================================================
for object expression 2 for object expression 2
================== ================================================================================
foo = {for i, v in ["a", "b"]: v => i...} foo = {for i, v in ["a", "b"]: v => i...}
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (for_expr
(for_expr (for_object_expr
(for_object_expr (for_intro
(for_intro (identifier)
(identifier) (identifier)
(identifier) (expression
(expression (collection_value
(expr_term (tuple
(collection_value (expression
(tuple (literal_value
(expression (expr_term (template_expr (quoted_template)))) (string_lit
(expression (expr_term (template_expr (quoted_template))))))))) (template_literal))))
(expression (expr_term (variable_expr (identifier)))) (expression
(expression (expr_term (variable_expr (identifier)))) (ellipsis)))))))) (literal_value
(string_lit
(template_literal))))))))
(expression
(variable_expr
(identifier)))
(expression
(variable_expr
(identifier)))
(ellipsis)))))))

View File

@@ -1,58 +1,64 @@
================== ================================================================================
nonary function call nonary function call
================== ================================================================================
foo = bar() foo = bar()
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (function_call (identifier))))))) (expression
(function_call
(identifier))))))
================== ================================================================================
unary function call unary function call
================== ================================================================================
foo = bar("foo") foo = bar("foo")
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (function_call
(function_call (identifier)
(identifier) (function_arguments
(function_arguments (expression
(expression (expr_term (template_expr (quoted_template))))))))))) (literal_value
(string_lit
(template_literal))))))))))
================== ================================================================================
variadic function call variadic function call
================== ================================================================================
foo = bar(x...) foo = bar(x...)
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (function_call
(function_call (identifier)
(identifier) (function_arguments
(function_arguments (expression
(expression (expr_term (variable_expr (identifier)))) (ellipsis)))))))) (variable_expr
(identifier)))
(ellipsis)))))))
================== ================================================================================
multiline function call multiline function call
================== ================================================================================
foo = bar( foo = bar(
"a", "a",
@@ -60,18 +66,25 @@ foo = bar(
"c" "c"
) )
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (function_call
(function_call (identifier)
(identifier) (function_arguments
(function_arguments (expression
(expression (expr_term (template_expr (quoted_template)))) (literal_value
(expression (expr_term (template_expr (quoted_template)))) (string_lit
(expression (expr_term (template_expr (quoted_template))))))))))) (template_literal))))
(expression
(literal_value
(string_lit
(template_literal))))
(expression
(literal_value
(string_lit
(template_literal))))))))))

View File

@@ -1,128 +1,143 @@
================== ================================================================================
numeric literal scientific notation 1 numeric literal scientific notation 1
================== ================================================================================
pi = 3 pi = 3
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (literal_value (numeric_lit))))))) (expression
(literal_value
(numeric_lit))))))
================== ================================================================================
numeric literal scientific notation 2 numeric literal scientific notation 2
================== ================================================================================
pi = 3.14 pi = 3.14
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (literal_value (numeric_lit))))))) (expression
(literal_value
(numeric_lit))))))
================== ================================================================================
numeric literal scientific notation 3 numeric literal scientific notation 3
================== ================================================================================
big_pi = 3.14e+10 big_pi = 3.14e+10
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (literal_value (numeric_lit))))))) (expression
(literal_value
(numeric_lit))))))
================== ================================================================================
numeric literal scientific notation 4 numeric literal scientific notation 4
================== ================================================================================
big_pi = 3.14E+10 big_pi = 3.14E+10
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (literal_value (numeric_lit))))))) (expression
(literal_value
(numeric_lit))))))
================== ================================================================================
numeric literal scientific notation 5 numeric literal scientific notation 5
================== ================================================================================
small_pi = 3.14e-10 small_pi = 3.14e-10
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (literal_value (numeric_lit))))))) (expression
(literal_value
(numeric_lit))))))
================================================================================
==================
numeric literal scientific notation 6 numeric literal scientific notation 6
================== ================================================================================
small_pi = 3.14E-10 small_pi = 3.14E-10
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (literal_value (numeric_lit))))))) (expression
(literal_value
(numeric_lit))))))
================== ================================================================================
bool literal true bool literal true
================== ================================================================================
foo = true foo = true
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (literal_value (bool_lit))))))) (expression
(literal_value
(bool_lit))))))
================== ================================================================================
bool literal false bool literal false
================== ================================================================================
foo = false foo = false
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (literal_value (bool_lit))))))) (expression
(literal_value
(bool_lit))))))
================== ================================================================================
null literal null literal
================== ================================================================================
foo = null foo = null
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (literal_value (null_lit))))))) (expression
(literal_value
(null_lit))))))

View File

@@ -1,10 +1,10 @@
================== ================================================================================
unary operator - unary operator -
================== ================================================================================
foo = -3 foo = -3
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
@@ -12,39 +12,44 @@ foo = -3
(identifier) (identifier)
(expression (expression
(operation (operation
(unary_operation (expr_term (literal_value (numeric_lit))))))))) (unary_operation
(literal_value
(numeric_lit))))))))
================== ================================================================================
unary operator ! unary operator !
================== ================================================================================
foo = !true foo = !true
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(operation (operation
(unary_operation (expr_term (literal_value (bool_lit))))))))) (unary_operation
(literal_value
(bool_lit))))))))
================== ================================================================================
binary operators + binary operators +
================== ================================================================================
foo = 1+2 foo = 1+2
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(operation (operation
(binary_operation (binary_operation
(expr_term (literal_value (numeric_lit))) (literal_value
(expr_term (literal_value (numeric_lit))))))))) (numeric_lit))
(literal_value
(numeric_lit))))))))

View File

@@ -1,86 +1,77 @@
================== ================================================================================
get attr get attr
================== ================================================================================
foo = bar.baz foo = bar.baz
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (variable_expr
(expr_term (identifier))
(variable_expr (get_attr
(identifier))) (identifier))))))
(get_attr
(identifier)))))))
================== ================================================================================
get index get index
================== ================================================================================
foo = bar[1] foo = bar[1]
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (variable_expr
(expr_term (identifier))
(variable_expr (index
(identifier))) (expression
(index (literal_value
(expression (numeric_lit))))))))
(expr_term
(literal_value
(numeric_lit))))))))))
================== ================================================================================
attr splat attr splat
================== ================================================================================
foo = bar.*.foo foo = bar.*.foo
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (variable_expr
(expr_term (identifier))
(variable_expr
(identifier)))
(splat (splat
(attr_splat (attr_splat))
(get_attr (get_attr
(identifier))))))))) (identifier))))))
================== ================================================================================
full splat full splat
================== ================================================================================
foo = bar[*].foo foo = bar[*].foo
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expression
(expr_term (variable_expr
(expr_term (identifier))
(variable_expr
(identifier)))
(splat (splat
(full_splat (full_splat))
(get_attr (get_attr
(identifier))))))))) (identifier))))))

View File

@@ -1,303 +1,229 @@
================== ================================================================================
string literal one line
==================
foo = "bar"
---
(config_file
(body
(attribute
(identifier)
(expression (expr_term (template_expr (quoted_template)))))))
==================
string literal escaped newline
==================
foo = "bar\nbaz"
---
(config_file
(body
(attribute
(identifier)
(expression (expr_term (template_expr (quoted_template (escape_sequence))))))))
==================
string literal escaped tab
==================
foo = "bar\tbaz"
---
(config_file
(body
(attribute
(identifier)
(expression (expr_term (template_expr (quoted_template (escape_sequence))))))))
==================
string literal escaped "
==================
foo = "bar\"baz"
---
(config_file
(body
(attribute
(identifier)
(expression (expr_term (template_expr (quoted_template (escape_sequence))))))))
==================
string literal escaped \
==================
foo = "bar\\baz"
---
(config_file
(body
(attribute
(identifier)
(expression (expr_term (template_expr (quoted_template (escape_sequence))))))))
==================
string literal escaped \uFFFF
==================
foo = "bar\uFFFFbaz"
---
(config_file
(body
(attribute
(identifier)
(expression (expr_term (template_expr (quoted_template (escape_sequence))))))))
==================
string bad escape sequence
==================
foo = "bar\pbaz"
---
(config_file
(body
(attribute
(identifier)
(expression (expr_term (template_expr (quoted_template (ERROR (UNEXPECTED '\')))))))))
==================
string bad escape sequence 2 string bad escape sequence 2
================== ================================================================================
foo = "bar\uZZ" foo = "bar\uZZ"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template (ERROR (UNEXPECTED '\'))))))))) (expression
(template_expr
(quoted_template
(template_literal
(ERROR
(UNEXPECTED '\')))))))))
================== ================================================================================
string literal multi line error string literal multi line error
================== ================================================================================
foo = " foo = "
bar" bar"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template (ERROR (UNEXPECTED 'b'))))))))) (expression
(template_expr
(quoted_template
(ERROR
(UNEXPECTED 'b'))
(template_literal)))))))
================== ================================================================================
string literal unescaped tab string literal unescaped tab
================== ================================================================================
foo = "foo bar" foo = "foo bar"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template (ERROR (UNEXPECTED 'b'))))))))) (expression
(template_expr
(quoted_template
(template_literal
(ERROR
(UNEXPECTED 'b')))))))))
================== ================================================================================
string literal unescaped backslash string literal unescaped backslash
================== ================================================================================
foo = "foo\bar" foo = "foo\bar"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template (ERROR (UNEXPECTED '\'))))))))) (expression
(template_expr
(quoted_template
(template_literal
(ERROR
(UNEXPECTED '\')))))))))
================== ================================================================================
string literal escaped backslash at end string literal escaped backslash at end
================== ================================================================================
foo = "foo\\" foo = "foo\\"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template (escape_sequence)))))))) (expression
(literal_value
(string_lit
(template_literal)))))))
================================================================================
==================
string literal escaped template interpolation string literal escaped template interpolation
================== ================================================================================
foo = "$${foo.bar}" foo = "$${foo.bar}"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template (escape_sequence)))))))) (expression
(literal_value
(string_lit
(template_literal)))))))
================== ================================================================================
string literal template chars but no template 1 string literal template chars but no template 1
================== ================================================================================
foo = "$$$" foo = "$$$"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template))))))) (expression
(literal_value
(string_lit
(template_literal)))))))
================== ================================================================================
string literal template chars but no template 2 string literal template chars but no template 2
================== ================================================================================
foo = "100%" foo = "100%"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template))))))) (expression
(literal_value
(string_lit
(template_literal)))))))
================== ================================================================================
string literal template chars but no template 3 string literal template chars but no template 3
================== ================================================================================
foo = "%\n\t" foo = "%\n\t"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template (expression
(escape_sequence) (literal_value
(escape_sequence)))))))) (string_lit
(template_literal)))))))
================== ================================================================================
string literal template chars but no template 4 string literal template chars but no template 4
================== ================================================================================
foo = "%%\n\t" foo = "%%\n\t"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template (expression
(escape_sequence) (literal_value
(escape_sequence)))))))) (string_lit
(template_literal)))))))
================== ================================================================================
string literal template chars but no template 5 string literal template chars but no template 5
================== ================================================================================
foo = "$$" foo = "$$"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template))))))) (expression
(literal_value
(string_lit
(template_literal)))))))
================== ================================================================================
string literal template chars but no template 6 string literal template chars but no template 6
================== ================================================================================
foo = "%%{\n\t" foo = "%%{\n\t"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template (expression
(escape_sequence) (literal_value
(escape_sequence) (string_lit
(escape_sequence)))))))) (template_literal)))))))
================== ================================================================================
string literal escaped template string literal escaped template
================== ================================================================================
foo = "$${ var.bar }" foo = "$${ var.bar }"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template (escape_sequence)))))))) (expression
(literal_value
================== (string_lit
proper quoted template in string literal position errors (template_literal)))))))
==================
resource "${var.bar}" {
}
---
(config_file
(body
(block
(identifier)
(string_lit (ERROR)))))

View File

@@ -1,13 +1,145 @@
================== ================================================================================
quoted template expression simple quoted template expression
================== ================================================================================
foo = "${ var.bar }" foo = "${ var.bar }"
--- --------------------------------------------------------------------------------
(config_file (config_file
(body (body
(attribute (attribute
(identifier) (identifier)
(expression (expr_term (template_expr (quoted_template (template_interpolation)))))))) (expression
(template_expr
(quoted_template
(template_interpolation
(expression
(variable_expr
(identifier))
(get_attr
(identifier))))))))))
================================================================================
quoted template expression with escaped strings and fake strip marker
================================================================================
foo = "${ " ~ " }"
--------------------------------------------------------------------------------
(config_file
(body
(attribute
(identifier)
(expression
(template_expr
(quoted_template
(template_interpolation
(expression
(literal_value
(string_lit
(template_literal)))))))))))
================================================================================
quoted template with nested quoted template
================================================================================
foo = "p-${ foo("v-${a.b}") }"
--------------------------------------------------------------------------------
(config_file
(body
(attribute
(identifier)
(expression
(template_expr
(quoted_template
(template_literal)
(template_interpolation
(expression
(function_call
(identifier)
(function_arguments
(expression
(template_expr
(quoted_template
(template_literal)
(template_interpolation
(expression
(variable_expr
(identifier))
(get_attr
(identifier)))))))))))))))))
================================================================================
quoted template interpolation with strip markers
================================================================================
foo = "hello ${~ "world" ~} hello"
--------------------------------------------------------------------------------
(config_file
(body
(attribute
(identifier)
(expression
(template_expr
(quoted_template
(template_literal)
(template_interpolation
(strip_marker)
(expression
(literal_value
(string_lit
(template_literal))))
(strip_marker))
(template_literal)))))))
================================================================================
quoted template object expression in template
================================================================================
foo = "${ {a=b}[a] }"
--------------------------------------------------------------------------------
(config_file
(body
(attribute
(identifier)
(expression
(template_expr
(quoted_template
(template_interpolation
(expression
(collection_value
(object
(object_elem
(identifier)
(expression
(variable_expr
(identifier))))))
(index
(expression
(variable_expr
(identifier))))))))))))
================================================================================
escaped template interpolation start
================================================================================
foo = "hello $${ world"
--------------------------------------------------------------------------------
(config_file
(body
(attribute
(identifier)
(expression
(literal_value
(string_lit
(template_literal)))))))