fix: precedence of unary operators and expressions
Signed-off-by: Michael Hoffmann <mhoffm@posteo.de>
This commit is contained in:
7
.github/workflows/ci.yaml
vendored
7
.github/workflows/ci.yaml
vendored
@@ -38,18 +38,11 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Set up tree-sitter
|
- name: Set up tree-sitter
|
||||||
uses: tree-sitter/setup-action/cli@v1
|
uses: tree-sitter/setup-action/cli@v1
|
||||||
- name: Regenerate with ABI 14
|
|
||||||
# TODO: remove when node & swift support ABI 15
|
|
||||||
run: |-
|
|
||||||
tree-sitter generate --abi=14
|
|
||||||
cd dialects/terraform
|
|
||||||
tree-sitter generate --abi=14
|
|
||||||
- name: Run parser and binding tests
|
- name: Run parser and binding tests
|
||||||
uses: tree-sitter/parser-test-action@v2
|
uses: tree-sitter/parser-test-action@v2
|
||||||
with:
|
with:
|
||||||
test-node: true
|
test-node: true
|
||||||
test-rust: ${{runner.os == 'Linux'}}
|
test-rust: ${{runner.os == 'Linux'}}
|
||||||
test-swift: ${{runner.os == 'macOS'}}
|
|
||||||
- name: Parse sample files
|
- name: Parse sample files
|
||||||
uses: tree-sitter/parse-action@v4
|
uses: tree-sitter/parse-action@v4
|
||||||
id: parse-files
|
id: parse-files
|
||||||
|
|||||||
8
Package.resolved
generated
8
Package.resolved
generated
@@ -6,8 +6,8 @@
|
|||||||
"repositoryURL": "https://github.com/tree-sitter/swift-tree-sitter",
|
"repositoryURL": "https://github.com/tree-sitter/swift-tree-sitter",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "36aa61d1b531f744f35229f010efba9c6d6cbbdd",
|
"revision": "08ef81eb8620617b55b08868126707ad72bf754f",
|
||||||
"version": "0.9.0"
|
"version": "0.25.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -15,8 +15,8 @@
|
|||||||
"repositoryURL": "https://github.com/tree-sitter/tree-sitter",
|
"repositoryURL": "https://github.com/tree-sitter/tree-sitter",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "d97db6d63507eb62c536bcb2c4ac7d70c8ec665e",
|
"revision" : "460118b4c82318b083b4d527c9c750426730f9c0",
|
||||||
"version": "0.23.2"
|
"version" : "0.25.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
3
Package.swift
generated
3
Package.swift
generated
@@ -4,11 +4,12 @@ import PackageDescription
|
|||||||
|
|
||||||
let package = Package(
|
let package = Package(
|
||||||
name: "TreeSitterHCL",
|
name: "TreeSitterHCL",
|
||||||
|
platforms: [.macOS(.v10_13), .iOS(.v11)],
|
||||||
products: [
|
products: [
|
||||||
.library(name: "TreeSitterHCL", targets: ["TreeSitterHCL"]),
|
.library(name: "TreeSitterHCL", targets: ["TreeSitterHCL"]),
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.package(name: "SwiftTreeSitter", url: "https://github.com/tree-sitter/swift-tree-sitter", from: "0.9.0"),
|
.package(name: "SwiftTreeSitter", url: "https://github.com/tree-sitter/swift-tree-sitter", from: "0.25.0"),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
|
|||||||
@@ -124,7 +124,8 @@
|
|||||||
"members": [
|
"members": [
|
||||||
{
|
{
|
||||||
"type": "PATTERN",
|
"type": "PATTERN",
|
||||||
"value": "\\p{ID_Start}"
|
"value": "\\p{ID_Start}",
|
||||||
|
"flags": "u"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
@@ -139,7 +140,8 @@
|
|||||||
"members": [
|
"members": [
|
||||||
{
|
{
|
||||||
"type": "PATTERN",
|
"type": "PATTERN",
|
||||||
"value": "\\p{ID_Continue}"
|
"value": "\\p{ID_Continue}",
|
||||||
|
"flags": "u"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
@@ -204,43 +206,55 @@
|
|||||||
"name": "operation"
|
"name": "operation"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "PREC_RIGHT",
|
||||||
"members": [
|
"value": 8,
|
||||||
{
|
"content": {
|
||||||
"type": "SYMBOL",
|
"type": "SEQ",
|
||||||
"name": "_expr_term"
|
"members": [
|
||||||
},
|
{
|
||||||
{
|
"type": "SYMBOL",
|
||||||
"type": "SYMBOL",
|
"name": "_expr_term"
|
||||||
"name": "index"
|
},
|
||||||
}
|
{
|
||||||
]
|
"type": "SYMBOL",
|
||||||
|
"name": "index"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "PREC_RIGHT",
|
||||||
"members": [
|
"value": 8,
|
||||||
{
|
"content": {
|
||||||
"type": "SYMBOL",
|
"type": "SEQ",
|
||||||
"name": "_expr_term"
|
"members": [
|
||||||
},
|
{
|
||||||
{
|
"type": "SYMBOL",
|
||||||
"type": "SYMBOL",
|
"name": "_expr_term"
|
||||||
"name": "get_attr"
|
},
|
||||||
}
|
{
|
||||||
]
|
"type": "SYMBOL",
|
||||||
|
"name": "get_attr"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "PREC_RIGHT",
|
||||||
"members": [
|
"value": 8,
|
||||||
{
|
"content": {
|
||||||
"type": "SYMBOL",
|
"type": "SEQ",
|
||||||
"name": "_expr_term"
|
"members": [
|
||||||
},
|
{
|
||||||
{
|
"type": "SYMBOL",
|
||||||
"type": "SYMBOL",
|
"name": "_expr_term"
|
||||||
"name": "splat"
|
},
|
||||||
}
|
{
|
||||||
]
|
"type": "SYMBOL",
|
||||||
|
"name": "splat"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -129,7 +129,7 @@ static unsigned serialize(Scanner *scanner, char *buf) {
|
|||||||
|
|
||||||
memcpy(&buf[size], &(scanner->context_stack.len), sizeof(uint32_t));
|
memcpy(&buf[size], &(scanner->context_stack.len), sizeof(uint32_t));
|
||||||
size += sizeof(uint32_t);
|
size += sizeof(uint32_t);
|
||||||
for (int i = 0; i < scanner->context_stack.len; i++) {
|
for (uint32_t i = 0; i < scanner->context_stack.len; i++) {
|
||||||
Context *context = &scanner->context_stack.data[i];
|
Context *context = &scanner->context_stack.data[i];
|
||||||
if (size + sizeof(ContextType) + sizeof(uint32_t) + context->heredoc_identifier.len >= TREE_SITTER_SERIALIZATION_BUFFER_SIZE) {
|
if (size + sizeof(ContextType) + sizeof(uint32_t) + context->heredoc_identifier.len >= TREE_SITTER_SERIALIZATION_BUFFER_SIZE) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -413,7 +413,7 @@ bool tree_sitter_terraform_external_scanner_scan(void *payload, TSLexer *lexer,
|
|||||||
|
|
||||||
void tree_sitter_terraform_external_scanner_destroy(void *payload) {
|
void tree_sitter_terraform_external_scanner_destroy(void *payload) {
|
||||||
Scanner *scanner = (Scanner *)payload;
|
Scanner *scanner = (Scanner *)payload;
|
||||||
for (int i = 0; i < scanner->context_stack.len; i++) {
|
for (uint32_t i = 0; i < scanner->context_stack.len; i++) {
|
||||||
STRING_FREE(scanner->context_stack.data[i].heredoc_identifier);
|
STRING_FREE(scanner->context_stack.data[i].heredoc_identifier);
|
||||||
}
|
}
|
||||||
VEC_FREE(scanner->context_stack);
|
VEC_FREE(scanner->context_stack);
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
/** @param {string} dialect */
|
/** @param {string} dialect */
|
||||||
module.exports = function make_grammar(dialect) {
|
module.exports = function make_grammar(dialect) {
|
||||||
const PREC = {
|
const PREC = {
|
||||||
|
// unary negation should not pull expressions apart
|
||||||
|
expr: 8,
|
||||||
unary: 7,
|
unary: 7,
|
||||||
binary_mult: 6,
|
binary_mult: 6,
|
||||||
binary_add: 5,
|
binary_add: 5,
|
||||||
@@ -75,9 +77,9 @@ module.exports = function make_grammar(dialect) {
|
|||||||
$.function_call,
|
$.function_call,
|
||||||
$.for_expr,
|
$.for_expr,
|
||||||
$.operation,
|
$.operation,
|
||||||
seq($._expr_term, $.index),
|
prec.right(PREC.expr, seq($._expr_term, $.index)),
|
||||||
seq($._expr_term, $.get_attr),
|
prec.right(PREC.expr, seq($._expr_term, $.get_attr)),
|
||||||
seq($._expr_term, $.splat),
|
prec.right(PREC.expr, seq($._expr_term, $.splat)),
|
||||||
seq("(", $.expression, ")"),
|
seq("(", $.expression, ")"),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|||||||
16
package-lock.json
generated
16
package-lock.json
generated
@@ -15,10 +15,10 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prebuildify": "^6.0.1",
|
"prebuildify": "^6.0.1",
|
||||||
"tree-sitter-cli": "^0.25.3"
|
"tree-sitter-cli": "^0.25.6"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"tree-sitter": "^0.22.4"
|
"tree-sitter": "^0.25.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"tree-sitter": {
|
"tree-sitter": {
|
||||||
@@ -338,9 +338,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tree-sitter": {
|
"node_modules/tree-sitter": {
|
||||||
"version": "0.22.4",
|
"version": "0.25.0",
|
||||||
"resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.22.4.tgz",
|
"resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.25.0.tgz",
|
||||||
"integrity": "sha512-usbHZP9/oxNsUY65MQUsduGRqDHQOou1cagUSwjhoSYAmSahjQDAVsh9s+SlZkn8X8+O1FULRGwHu7AFP3kjzg==",
|
"integrity": "sha512-PGZZzFW63eElZJDe/b/R/LbsjDDYJa5UEjLZJB59RQsMX+fo0j54fqBPn1MGKav/QNa0JR0zBiVaikYDWCj5KQ==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
@@ -351,9 +351,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tree-sitter-cli": {
|
"node_modules/tree-sitter-cli": {
|
||||||
"version": "0.25.3",
|
"version": "0.25.6",
|
||||||
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.25.3.tgz",
|
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.25.6.tgz",
|
||||||
"integrity": "sha512-Bk6ZUXG+cKnwZpfR/te4NDrKld90p6350eqWlbLwSpV9/8vmL/x8LCw+3k7quY9oMDaYoMXHMvokXJbkM5A7bA==",
|
"integrity": "sha512-UhkXRkMPtBgE4OatZtYVtDsT3HFUliqAJcs49XQaZv8d2sbeTzEhpJVpMaCqBR3HGhb1WpyoodaFXQaMuOLPEg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
4
package.json
generated
4
package.json
generated
@@ -30,10 +30,10 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prebuildify": "^6.0.1",
|
"prebuildify": "^6.0.1",
|
||||||
"tree-sitter-cli": "^0.25.3"
|
"tree-sitter-cli": "^0.25.6"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"tree-sitter": "^0.22.4"
|
"tree-sitter": "^0.25.0"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"tree-sitter": {
|
"tree-sitter": {
|
||||||
|
|||||||
@@ -7,8 +7,11 @@ pkgs.mkShell {
|
|||||||
gdb
|
gdb
|
||||||
valgrind
|
valgrind
|
||||||
nodejs
|
nodejs
|
||||||
tree-sitter
|
|
||||||
emscripten
|
emscripten
|
||||||
];
|
];
|
||||||
|
shellHook = ''
|
||||||
|
npm install
|
||||||
|
export PATH="$(git rev-parse --show-toplevel)/node_modules/.bin:$PATH"
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
84
src/grammar.json
generated
84
src/grammar.json
generated
@@ -124,7 +124,8 @@
|
|||||||
"members": [
|
"members": [
|
||||||
{
|
{
|
||||||
"type": "PATTERN",
|
"type": "PATTERN",
|
||||||
"value": "\\p{ID_Start}"
|
"value": "\\p{ID_Start}",
|
||||||
|
"flags": "u"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
@@ -139,7 +140,8 @@
|
|||||||
"members": [
|
"members": [
|
||||||
{
|
{
|
||||||
"type": "PATTERN",
|
"type": "PATTERN",
|
||||||
"value": "\\p{ID_Continue}"
|
"value": "\\p{ID_Continue}",
|
||||||
|
"flags": "u"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "STRING",
|
"type": "STRING",
|
||||||
@@ -204,43 +206,55 @@
|
|||||||
"name": "operation"
|
"name": "operation"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "PREC_RIGHT",
|
||||||
"members": [
|
"value": 8,
|
||||||
{
|
"content": {
|
||||||
"type": "SYMBOL",
|
"type": "SEQ",
|
||||||
"name": "_expr_term"
|
"members": [
|
||||||
},
|
{
|
||||||
{
|
"type": "SYMBOL",
|
||||||
"type": "SYMBOL",
|
"name": "_expr_term"
|
||||||
"name": "index"
|
},
|
||||||
}
|
{
|
||||||
]
|
"type": "SYMBOL",
|
||||||
|
"name": "index"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "PREC_RIGHT",
|
||||||
"members": [
|
"value": 8,
|
||||||
{
|
"content": {
|
||||||
"type": "SYMBOL",
|
"type": "SEQ",
|
||||||
"name": "_expr_term"
|
"members": [
|
||||||
},
|
{
|
||||||
{
|
"type": "SYMBOL",
|
||||||
"type": "SYMBOL",
|
"name": "_expr_term"
|
||||||
"name": "get_attr"
|
},
|
||||||
}
|
{
|
||||||
]
|
"type": "SYMBOL",
|
||||||
|
"name": "get_attr"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "PREC_RIGHT",
|
||||||
"members": [
|
"value": 8,
|
||||||
{
|
"content": {
|
||||||
"type": "SYMBOL",
|
"type": "SEQ",
|
||||||
"name": "_expr_term"
|
"members": [
|
||||||
},
|
{
|
||||||
{
|
"type": "SYMBOL",
|
||||||
"type": "SYMBOL",
|
"name": "_expr_term"
|
||||||
"name": "splat"
|
},
|
||||||
}
|
{
|
||||||
]
|
"type": "SYMBOL",
|
||||||
|
"name": "splat"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
|
|||||||
6827
src/parser.c
generated
6827
src/parser.c
generated
File diff suppressed because it is too large
Load Diff
43
test/corpus/expresssion.txt
Normal file
43
test/corpus/expresssion.txt
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
======
|
||||||
|
Unary operation on variable with splat expression
|
||||||
|
=====
|
||||||
|
|
||||||
|
foo = !var.bar
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
(config_file
|
||||||
|
(body
|
||||||
|
(attribute
|
||||||
|
(identifier)
|
||||||
|
(expression
|
||||||
|
(operation
|
||||||
|
(unary_operation
|
||||||
|
(variable_expr
|
||||||
|
(identifier))
|
||||||
|
(get_attr
|
||||||
|
(identifier))))))))
|
||||||
|
|
||||||
|
=====
|
||||||
|
Attribute as conditional expression
|
||||||
|
=====
|
||||||
|
|
||||||
|
foo = local.bar == local.baz
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
|
(config_file
|
||||||
|
(body
|
||||||
|
(attribute
|
||||||
|
(identifier)
|
||||||
|
(expression
|
||||||
|
(operation
|
||||||
|
(binary_operation
|
||||||
|
(variable_expr
|
||||||
|
(identifier))
|
||||||
|
(get_attr
|
||||||
|
(identifier))
|
||||||
|
(variable_expr
|
||||||
|
(identifier))
|
||||||
|
(get_attr
|
||||||
|
(identifier))))))))
|
||||||
@@ -81,3 +81,48 @@ foo = a != b && c == d
|
|||||||
(identifier))
|
(identifier))
|
||||||
(variable_expr
|
(variable_expr
|
||||||
(identifier))))))))))
|
(identifier))))))))))
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
precedence in binary operators 2
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
foo = a.foo != "" && b.foo == "" ? 1 : 0
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(config_file
|
||||||
|
(body
|
||||||
|
(attribute
|
||||||
|
(identifier)
|
||||||
|
(expression
|
||||||
|
(conditional
|
||||||
|
(expression
|
||||||
|
(operation
|
||||||
|
(binary_operation
|
||||||
|
(operation
|
||||||
|
(binary_operation
|
||||||
|
(variable_expr
|
||||||
|
(identifier))
|
||||||
|
(get_attr
|
||||||
|
(identifier))
|
||||||
|
(literal_value
|
||||||
|
(string_lit
|
||||||
|
(quoted_template_start)
|
||||||
|
(quoted_template_end)))))
|
||||||
|
(operation
|
||||||
|
(binary_operation
|
||||||
|
(variable_expr
|
||||||
|
(identifier))
|
||||||
|
(get_attr
|
||||||
|
(identifier))
|
||||||
|
(literal_value
|
||||||
|
(string_lit
|
||||||
|
(quoted_template_start)
|
||||||
|
(quoted_template_end))))))))
|
||||||
|
(expression
|
||||||
|
(literal_value
|
||||||
|
(numeric_lit)))
|
||||||
|
(expression
|
||||||
|
(literal_value
|
||||||
|
(numeric_lit))))))))
|
||||||
|
|||||||
@@ -390,24 +390,24 @@ resource "azurerm_storage_blob" "proxy_cert" {
|
|||||||
(binary_operation
|
(binary_operation
|
||||||
(operation
|
(operation
|
||||||
(binary_operation
|
(binary_operation
|
||||||
(operation
|
|
||||||
(binary_operation
|
|
||||||
(variable_expr
|
|
||||||
(identifier))
|
|
||||||
(get_attr
|
|
||||||
(identifier))
|
|
||||||
(literal_value
|
|
||||||
(string_lit
|
|
||||||
(quoted_template_start)
|
|
||||||
(quoted_template_end)))))
|
|
||||||
(variable_expr
|
(variable_expr
|
||||||
(identifier))))
|
(identifier))
|
||||||
(get_attr
|
(get_attr
|
||||||
(identifier))
|
(identifier))
|
||||||
(literal_value
|
(literal_value
|
||||||
(string_lit
|
(string_lit
|
||||||
(quoted_template_start)
|
(quoted_template_start)
|
||||||
(quoted_template_end))))))
|
(quoted_template_end)))))
|
||||||
|
(operation
|
||||||
|
(binary_operation
|
||||||
|
(variable_expr
|
||||||
|
(identifier))
|
||||||
|
(get_attr
|
||||||
|
(identifier))
|
||||||
|
(literal_value
|
||||||
|
(string_lit
|
||||||
|
(quoted_template_start)
|
||||||
|
(quoted_template_end))))))))
|
||||||
(expression
|
(expression
|
||||||
(literal_value
|
(literal_value
|
||||||
(numeric_lit)))
|
(numeric_lit)))
|
||||||
|
|||||||
Reference in New Issue
Block a user