Compare commits
11 Commits
009def4ae3
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 00f0fbcdf2 | |||
| 51698afe89 | |||
| 6b3300744d | |||
| dd5cf14b70 | |||
| 169afdafda | |||
| 257abf0c72 | |||
|
|
fad991865f | ||
|
|
cb0e322d6f | ||
|
|
09d38ff794 | ||
|
|
dffd961034 | ||
|
|
28e327cd3f |
7
.github/workflows/ci.yaml
vendored
7
.github/workflows/ci.yaml
vendored
@@ -38,18 +38,11 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up tree-sitter
|
||||
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
|
||||
uses: tree-sitter/parser-test-action@v2
|
||||
with:
|
||||
test-node: true
|
||||
test-rust: ${{runner.os == 'Linux'}}
|
||||
test-swift: ${{runner.os == 'macOS'}}
|
||||
- name: Parse sample files
|
||||
uses: tree-sitter/parse-action@v4
|
||||
id: parse-files
|
||||
|
||||
10
.github/workflows/release.yaml
vendored
10
.github/workflows/release.yaml
vendored
@@ -20,9 +20,19 @@ jobs:
|
||||
attestations: true
|
||||
npm:
|
||||
uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main
|
||||
with:
|
||||
generate: true
|
||||
abi-version: 14
|
||||
secrets:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
crates:
|
||||
uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main
|
||||
secrets:
|
||||
CARGO_REGISTRY_TOKEN: ${{secrets.CARGO_TOKEN}}
|
||||
pypi:
|
||||
uses: tree-sitter/workflows/.github/workflows/package-pypi.yml@main
|
||||
with:
|
||||
generate: true
|
||||
abi-version: 14
|
||||
secrets:
|
||||
PYPI_API_TOKEN: ${{secrets.PYPI_TOKEN}}
|
||||
|
||||
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,5 +1,17 @@
|
||||
# Changelog
|
||||
|
||||
## 1.2.0 - 2025-06-15
|
||||
|
||||
feat:
|
||||
* namespaced identitifers
|
||||
|
||||
fix:
|
||||
* precedence of unary operators and expressions
|
||||
|
||||
housekeeping:
|
||||
* regenerate with tree-sitter-cli 0.25.6
|
||||
* add bindings
|
||||
|
||||
## 1.1.0 - 2023-07-25
|
||||
|
||||
feature
|
||||
|
||||
2
CMakeLists.txt
generated
2
CMakeLists.txt
generated
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
project(tree-sitter-hcl
|
||||
VERSION "1.1.0"
|
||||
VERSION "1.2.0"
|
||||
DESCRIPTION "HCL and terraform grammar for tree-sitter"
|
||||
HOMEPAGE_URL "https://github.com/tree-sitter-grammars/tree-sitter-hcl"
|
||||
LANGUAGES C)
|
||||
|
||||
2
Cargo.toml
generated
2
Cargo.toml
generated
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "tree-sitter-hcl"
|
||||
description = "HCL and terraform grammar for tree-sitter"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
license = "Apache-2.0"
|
||||
readme = "README.md"
|
||||
keywords = ["incremental", "parsing", "tree-sitter", "hcl"]
|
||||
|
||||
2
Makefile
generated
2
Makefile
generated
@@ -4,7 +4,7 @@ endif
|
||||
|
||||
LANGUAGE_NAME := tree-sitter-hcl
|
||||
HOMEPAGE_URL := https://github.com/tree-sitter-grammars/tree-sitter-hcl
|
||||
VERSION := 1.1.0
|
||||
VERSION := 1.2.0
|
||||
|
||||
# repository
|
||||
SRC_DIR := src
|
||||
|
||||
8
Package.resolved
generated
8
Package.resolved
generated
@@ -6,8 +6,8 @@
|
||||
"repositoryURL": "https://github.com/tree-sitter/swift-tree-sitter",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "36aa61d1b531f744f35229f010efba9c6d6cbbdd",
|
||||
"version": "0.9.0"
|
||||
"revision": "08ef81eb8620617b55b08868126707ad72bf754f",
|
||||
"version": "0.25.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -15,8 +15,8 @@
|
||||
"repositoryURL": "https://github.com/tree-sitter/tree-sitter",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "d97db6d63507eb62c536bcb2c4ac7d70c8ec665e",
|
||||
"version": "0.23.2"
|
||||
"revision" : "460118b4c82318b083b4d527c9c750426730f9c0",
|
||||
"version" : "0.25.5"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
3
Package.swift
generated
3
Package.swift
generated
@@ -4,11 +4,12 @@ import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "TreeSitterHCL",
|
||||
platforms: [.macOS(.v10_13), .iOS(.v11)],
|
||||
products: [
|
||||
.library(name: "TreeSitterHCL", targets: ["TreeSitterHCL"]),
|
||||
],
|
||||
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: [
|
||||
.target(
|
||||
|
||||
63
README.md
63
README.md
@@ -1,39 +1,44 @@
|
||||
# tree-sitter-hcl
|
||||
HCL and Terraform parsers that treat `{%` as comment lines for... reasons. iykyk 🤷
|
||||
|
||||
tree-sitter grammar for the [HCL](https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md) language
|
||||
# Neovim usage with the `nvim-treesitter` plugin
|
||||
|
||||
## Try It Out
|
||||
Clone this repo somewhere then add this to your config:
|
||||
|
||||
Try the parser in the [playground](https://tree-sitter-grammars.github.io/tree-sitter-hcl/)
|
||||
```lua
|
||||
local configs = require("nvim-treesitter.configs")
|
||||
local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
|
||||
|
||||
## Example
|
||||
-- for some reason you can't use the repo url here. it won't override the
|
||||
-- default tf and hcl parsers.
|
||||
local jhcl_repo = "~/path/to/this/repo"
|
||||
|
||||
Highlighting `example/example.hcl`:
|
||||
parser_config.hcl = {
|
||||
install_info = {
|
||||
url = jhcl_repo,
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
}
|
||||
}
|
||||
|
||||

|
||||
parser_config.terraform = {
|
||||
install_info = {
|
||||
url = jhcl_repo,
|
||||
files = { "src/parser.c", "src/scanner.c" },
|
||||
location = "dialects/terraform",
|
||||
}
|
||||
}
|
||||
|
||||
## Developing
|
||||
configs.setup({
|
||||
-- ...
|
||||
|
||||
It is recommended to use `nix` to fulfill all development dependencies. To activate the development environment simply run `nix-shell` in the project root.
|
||||
-- We overwrote the default `nvim-treesitter` configs for `hcl` and
|
||||
-- `terraform` above, so we can include them in `ensure_installed` normally
|
||||
ensure_installed = {
|
||||
-- ...
|
||||
"hcl",
|
||||
"terraform",
|
||||
-- ...
|
||||
},
|
||||
|
||||
## Running Tests
|
||||
|
||||
To run tests simply run `nix-shell --run 'tree-sitter test'`.
|
||||
|
||||
## Compliance
|
||||
|
||||
The directory `example/real_world_stuff` contains a corpus of hcl files that I found with the github query `language:HCL` for users `coreos`, `hashicorp`, `oracle` and `terraform-community-modules`.
|
||||
|
||||
```bash
|
||||
tree-sitter parse --quiet --stat example/real_world_stuff/*/*
|
||||
|
||||
Total parses: 1892; successful parses: 1892; failed parses: 0; success percentage: 100.00%
|
||||
-- ...
|
||||
})
|
||||
```
|
||||
|
||||
## Fuzzing
|
||||
|
||||
See the [fuzzing repo for this parser](https://github.com/MichaHoffmann/tree-sitter-hcl-fuzz)
|
||||
|
||||
## Attributions
|
||||
|
||||
Pages were copied from https://github.com/m-novikov/tree-sitter-sql
|
||||
|
||||
15
bindings/go/binding.go
generated
Normal file
15
bindings/go/binding.go
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
package tree_sitter_hcl
|
||||
|
||||
// #cgo CFLAGS: -std=c11 -fPIC
|
||||
// #include "../../src/parser.c"
|
||||
// #if __has_include("../../src/scanner.c")
|
||||
// #include "../../src/scanner.c"
|
||||
// #endif
|
||||
import "C"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// Get the tree-sitter Language for this grammar.
|
||||
func Language() unsafe.Pointer {
|
||||
return unsafe.Pointer(C.tree_sitter_hcl())
|
||||
}
|
||||
15
bindings/go/binding_test.go
generated
Normal file
15
bindings/go/binding_test.go
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
package tree_sitter_hcl_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
tree_sitter "github.com/tree-sitter/go-tree-sitter"
|
||||
tree_sitter_hcl "github.com/tree-sitter-grammars/tree-sitter-hcl/bindings/go"
|
||||
)
|
||||
|
||||
func TestCanLoadGrammar(t *testing.T) {
|
||||
language := tree_sitter.NewLanguage(tree_sitter_hcl.Language())
|
||||
if language == nil {
|
||||
t.Errorf("Error loading HCL grammar")
|
||||
}
|
||||
}
|
||||
12
bindings/python/tests/test_binding.py
generated
Normal file
12
bindings/python/tests/test_binding.py
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
from unittest import TestCase
|
||||
|
||||
import tree_sitter
|
||||
import tree_sitter_hcl
|
||||
|
||||
|
||||
class TestLanguage(TestCase):
|
||||
def test_can_load_grammar(self):
|
||||
try:
|
||||
tree_sitter.Language(tree_sitter_hcl.language())
|
||||
except Exception:
|
||||
self.fail("Error loading HCL grammar")
|
||||
5
bindings/python/tree_sitter_hcl/__init__.py
generated
Normal file
5
bindings/python/tree_sitter_hcl/__init__.py
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
"""HCL and terraform grammar for tree-sitter"""
|
||||
|
||||
from ._binding import language
|
||||
|
||||
__all__ = ["language"]
|
||||
1
bindings/python/tree_sitter_hcl/__init__.pyi
generated
Normal file
1
bindings/python/tree_sitter_hcl/__init__.pyi
generated
Normal file
@@ -0,0 +1 @@
|
||||
def language() -> object: ...
|
||||
35
bindings/python/tree_sitter_hcl/binding.c
generated
Normal file
35
bindings/python/tree_sitter_hcl/binding.c
generated
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <Python.h>
|
||||
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
|
||||
TSLanguage *tree_sitter_hcl(void);
|
||||
|
||||
static PyObject* _binding_language(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(args)) {
|
||||
return PyCapsule_New(tree_sitter_hcl(), "tree_sitter.Language", NULL);
|
||||
}
|
||||
|
||||
static struct PyModuleDef_Slot slots[] = {
|
||||
#ifdef Py_GIL_DISABLED
|
||||
{Py_mod_gil, Py_MOD_GIL_NOT_USED},
|
||||
#endif
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static PyMethodDef methods[] = {
|
||||
{"language", _binding_language, METH_NOARGS,
|
||||
"Get the tree-sitter language for this grammar."},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static struct PyModuleDef module = {
|
||||
.m_base = PyModuleDef_HEAD_INIT,
|
||||
.m_name = "_binding",
|
||||
.m_doc = NULL,
|
||||
.m_size = 0,
|
||||
.m_methods = methods,
|
||||
.m_slots = slots,
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC PyInit__binding(void) {
|
||||
return PyModuleDef_Init(&module);
|
||||
}
|
||||
0
bindings/python/tree_sitter_hcl/py.typed
generated
Normal file
0
bindings/python/tree_sitter_hcl/py.typed
generated
Normal file
@@ -124,7 +124,8 @@
|
||||
"members": [
|
||||
{
|
||||
"type": "PATTERN",
|
||||
"value": "\\p{ID_Start}"
|
||||
"value": "\\p{ID_Start}",
|
||||
"flags": "u"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
@@ -139,7 +140,8 @@
|
||||
"members": [
|
||||
{
|
||||
"type": "PATTERN",
|
||||
"value": "\\p{ID_Continue}"
|
||||
"value": "\\p{ID_Continue}",
|
||||
"flags": "u"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
@@ -204,43 +206,55 @@
|
||||
"name": "operation"
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "index"
|
||||
}
|
||||
]
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 8,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "index"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "get_attr"
|
||||
}
|
||||
]
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 8,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "get_attr"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "splat"
|
||||
}
|
||||
]
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 8,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "splat"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
@@ -1681,6 +1695,19 @@
|
||||
"content": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "{%"
|
||||
},
|
||||
{
|
||||
"type": "PATTERN",
|
||||
"value": ".*"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
|
||||
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));
|
||||
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];
|
||||
if (size + sizeof(ContextType) + sizeof(uint32_t) + context->heredoc_identifier.len >= TREE_SITTER_SERIALIZATION_BUFFER_SIZE) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
VEC_FREE(scanner->context_stack);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{% test %}
|
||||
resource "example" "literals" {
|
||||
attr1 = "val1"
|
||||
tupl1 = [ 1, 2, 3.4, "foo" ]
|
||||
|
||||
96
example/example.tf
Normal file
96
example/example.tf
Normal file
@@ -0,0 +1,96 @@
|
||||
{% test %}
|
||||
resource "example" "literals" {
|
||||
attr1 = "val1"
|
||||
tupl1 = [ 1, 2, 3.4, "foo" ]
|
||||
tupl2 = []
|
||||
obj1 = { foo = "bar", baz = quz }
|
||||
null1 = null
|
||||
bool1 = true
|
||||
bool2 = false
|
||||
esc1 = "\" \t \UFF11FF22 \uFFFF \n"
|
||||
esc2 = "$${} %%{}"
|
||||
num1 = 2
|
||||
num2 = 2.112
|
||||
num3 = 2.112e-12
|
||||
num4 = 2.112e+12
|
||||
num5 = 2.112E+12
|
||||
num6 = 2.112E-12
|
||||
num7 = 0x21FF
|
||||
}
|
||||
|
||||
resource "example" "comments" {
|
||||
// comment
|
||||
# comment
|
||||
/*
|
||||
comment
|
||||
*/
|
||||
}
|
||||
|
||||
resource "example" "splat_expressions" {
|
||||
splat1 = foo.*.bar.baz[0]
|
||||
splat2 = foo[*].bar.baz[0]
|
||||
}
|
||||
|
||||
resource "example" "for_expressions" {
|
||||
for1 = { for i, v in ["a", "a", "b"] : v => i... }
|
||||
for2 = [ for k, v in x : "${k}-${v}" ]
|
||||
for3 = { for k, v in x: k => v }
|
||||
for4 = [ for v in x : v ]
|
||||
for5 = { for v in x : v => v }
|
||||
for6 = [ for v in x : v if v < 3 ]
|
||||
}
|
||||
|
||||
resource "example" "function_expressions" {
|
||||
func1 = is_number("123")
|
||||
func2 = multiline(
|
||||
arg1,
|
||||
arg2,
|
||||
arg3...
|
||||
)
|
||||
func3 = withobject({
|
||||
"foo" : 2,
|
||||
"bar" : baz,
|
||||
key : val,
|
||||
fizz : buzz,
|
||||
})
|
||||
}
|
||||
|
||||
resource "example" "binary_expressions" {
|
||||
cond1 = (1 == 2) ? 1 : "foobar"
|
||||
bin1 = ((1+2)%3)*4
|
||||
}
|
||||
|
||||
resource "example" "template_expressions" {
|
||||
tpl1 = "prefix-${var.bar}"
|
||||
tpl2 = "prefix-${func("bar")}"
|
||||
tpl3 = "prefix-${func("nested-${var.bar}")}"
|
||||
|
||||
tpl4 = <<EOF
|
||||
%{ for a in f(b) ~}
|
||||
${func("foo${ a }")}
|
||||
%{ endfor ~}
|
||||
EOF
|
||||
|
||||
tpl5 = <<-EOF
|
||||
%{~if cond~}
|
||||
"foo"
|
||||
%{~else~}
|
||||
4
|
||||
%{~endif~}
|
||||
EOF
|
||||
|
||||
tpl6 = <<-EOF
|
||||
%{ for a in f(b) ~}
|
||||
%{~if a~} "true" %{~else~} "false" %{~endif~}
|
||||
%{ endfor ~}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "example" "nested_blocks" {
|
||||
nested_block "first" {
|
||||
attr1 = "foo"
|
||||
nested_block "second" {
|
||||
attr1 = "bar"
|
||||
}
|
||||
}
|
||||
}
|
||||
7
go.mod
generated
Normal file
7
go.mod
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
module github.com/tree-sitter-grammars/tree-sitter-hcl
|
||||
|
||||
go 1.22
|
||||
|
||||
require github.com/tree-sitter/go-tree-sitter v0.24.0
|
||||
|
||||
require github.com/mattn/go-pointer v0.0.1 // indirect
|
||||
36
go.sum
generated
Normal file
36
go.sum
generated
Normal file
@@ -0,0 +1,36 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0=
|
||||
github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tree-sitter/go-tree-sitter v0.24.0 h1:kRZb6aBNfcI/u0Qh8XEt3zjNVnmxTisDBN+kXK0xRYQ=
|
||||
github.com/tree-sitter/go-tree-sitter v0.24.0/go.mod h1:x681iFVoLMEwOSIHA1chaLkXlroXEN7WY+VHGFaoDbk=
|
||||
github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb h1:A8425heRM8mylnv4H58FPUiH+aYivyitre0PzxrfmWs=
|
||||
github.com/tree-sitter/tree-sitter-c v0.21.5-0.20240818205408-927da1f210eb/go.mod h1:dOF6gtQiF9UwNh995T5OphYmtIypkjsp3ap7r9AN/iA=
|
||||
github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148 h1:AfFPZwtwGN01BW1jDdqBVqscTwetvMpydqYZz57RSlc=
|
||||
github.com/tree-sitter/tree-sitter-cpp v0.22.4-0.20240818224355-b1a4e2b25148/go.mod h1:Bh6U3viD57rFXRYIQ+kmiYtr+1Bx0AceypDLJJSyi9s=
|
||||
github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33 h1:TwqSV3qLp3tKSqirGLRHnjFk9Tc2oy57LIl+FQ4GjI4=
|
||||
github.com/tree-sitter/tree-sitter-embedded-template v0.21.1-0.20240819044651-ffbf64942c33/go.mod h1:CvCKCt3v04Ufos1zZnNCelBDeCGRpPucaN8QczoUsN4=
|
||||
github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012 h1:Xvxck3tE5FW7F7bTS97iNM2ADMyCMJztVqn5HYKdJGo=
|
||||
github.com/tree-sitter/tree-sitter-go v0.21.3-0.20240818010209-8c0f0e7a6012/go.mod h1:T40D0O1cPvUU/+AmiXVXy1cncYQT6wem4Z0g4SfAYvY=
|
||||
github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0 h1:c46K6uh5Dz00zJeU9BfjXdb8I+E4RkUdfnWJpQADXFo=
|
||||
github.com/tree-sitter/tree-sitter-html v0.20.5-0.20240818004741-d11201a263d0/go.mod h1:hcNt/kOJHcIcuMvouE7LJcYdeFUFbVpBJ6d4wmOA+tU=
|
||||
github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495 h1:jrt4qbJVEFs4H93/ITxygHc6u0TGqAkkate7TQ4wFSA=
|
||||
github.com/tree-sitter/tree-sitter-java v0.21.1-0.20240824015150-576d8097e495/go.mod h1:oyaR7fLnRV0hT9z6qwE9GkaeTom/hTDwK3H2idcOJFc=
|
||||
github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5 h1:om4X9AVg3asL8gxNJDcz4e/Wp+VpQj1PY3uJXKr6EOg=
|
||||
github.com/tree-sitter/tree-sitter-javascript v0.21.5-0.20240818005344-15887341e5b5/go.mod h1:nNqgPoV/h9uYWk6kYEFdEAhNVOacpfpRW5SFmdaP4tU=
|
||||
github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5 h1:pfV3G3k7NCKqKk8THBmyuh2zA33lgYHS3GVrzRR8ry4=
|
||||
github.com/tree-sitter/tree-sitter-json v0.21.1-0.20240818005659-bdd69eb8c8a5/go.mod h1:GbMKRjLfk0H+PI7nLi1Sx5lHf5wCpLz9al8tQYSxpEk=
|
||||
github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1 h1:ZXZMDwE+IhUtGug4Brv6NjJWUU3rfkZBKpemf6RY8/g=
|
||||
github.com/tree-sitter/tree-sitter-php v0.22.9-0.20240819002312-a552625b56c1/go.mod h1:UKCLuYnJ312Mei+3cyTmGOHzn0YAnaPRECgJmHtzrqs=
|
||||
github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb h1:EXEM82lFM7JjJb6qiKZXkpIDaCcbV2obNn82ghwj9lw=
|
||||
github.com/tree-sitter/tree-sitter-python v0.21.1-0.20240818005537-55a9b8a4fbfb/go.mod h1:lXCF1nGG5Dr4J3BTS0ObN4xJCCICiSu/b+Xe/VqMV7g=
|
||||
github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d h1:fcYCvoXdcP1uRQYXqJHRy6Hec+uKScQdKVtMwK9JeCI=
|
||||
github.com/tree-sitter/tree-sitter-ruby v0.21.1-0.20240818211811-7dbc1e2d0e2d/go.mod h1:T1nShQ4v5AJtozZ8YyAS4uzUtDAJj/iv4YfwXSbUHzg=
|
||||
github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447 h1:o9alBu1J/WjrcTKEthYtXmdkDc5OVXD+PqlvnEZ0Lzc=
|
||||
github.com/tree-sitter/tree-sitter-rust v0.21.3-0.20240818005432-2b43eafe6447/go.mod h1:1Oh95COkkTn6Ezp0vcMbvfhRP5gLeqqljR0BYnBzWvc=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -4,6 +4,8 @@
|
||||
/** @param {string} dialect */
|
||||
module.exports = function make_grammar(dialect) {
|
||||
const PREC = {
|
||||
// unary negation should not pull expressions apart
|
||||
expr: 8,
|
||||
unary: 7,
|
||||
binary_mult: 6,
|
||||
binary_add: 5,
|
||||
@@ -75,9 +77,9 @@ module.exports = function make_grammar(dialect) {
|
||||
$.function_call,
|
||||
$.for_expr,
|
||||
$.operation,
|
||||
seq($._expr_term, $.index),
|
||||
seq($._expr_term, $.get_attr),
|
||||
seq($._expr_term, $.splat),
|
||||
prec.right(PREC.expr, seq($._expr_term, $.index)),
|
||||
prec.right(PREC.expr, seq($._expr_term, $.get_attr)),
|
||||
prec.right(PREC.expr, seq($._expr_term, $.splat)),
|
||||
seq("(", $.expression, ")"),
|
||||
),
|
||||
|
||||
@@ -347,6 +349,7 @@ module.exports = function make_grammar(dialect) {
|
||||
comment: ($) =>
|
||||
token(
|
||||
choice(
|
||||
seq("{%", /.*/),
|
||||
seq("#", /.*/),
|
||||
seq("//", /.*/),
|
||||
seq("/*", /[^*]*\*+([^/*][^*]*\*+)*/, "/"),
|
||||
|
||||
20
package-lock.json
generated
20
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@tree-sitter-grammars/tree-sitter-hcl",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@tree-sitter-grammars/tree-sitter-hcl",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@@ -15,10 +15,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"prebuildify": "^6.0.1",
|
||||
"tree-sitter-cli": "^0.25.3"
|
||||
"tree-sitter-cli": "^0.25.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tree-sitter": "^0.22.4"
|
||||
"tree-sitter": "^0.25.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"tree-sitter": {
|
||||
@@ -338,9 +338,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tree-sitter": {
|
||||
"version": "0.22.4",
|
||||
"resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.22.4.tgz",
|
||||
"integrity": "sha512-usbHZP9/oxNsUY65MQUsduGRqDHQOou1cagUSwjhoSYAmSahjQDAVsh9s+SlZkn8X8+O1FULRGwHu7AFP3kjzg==",
|
||||
"version": "0.25.0",
|
||||
"resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.25.0.tgz",
|
||||
"integrity": "sha512-PGZZzFW63eElZJDe/b/R/LbsjDDYJa5UEjLZJB59RQsMX+fo0j54fqBPn1MGKav/QNa0JR0zBiVaikYDWCj5KQ==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
@@ -351,9 +351,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tree-sitter-cli": {
|
||||
"version": "0.25.3",
|
||||
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.25.3.tgz",
|
||||
"integrity": "sha512-Bk6ZUXG+cKnwZpfR/te4NDrKld90p6350eqWlbLwSpV9/8vmL/x8LCw+3k7quY9oMDaYoMXHMvokXJbkM5A7bA==",
|
||||
"version": "0.25.6",
|
||||
"resolved": "https://registry.npmjs.org/tree-sitter-cli/-/tree-sitter-cli-0.25.6.tgz",
|
||||
"integrity": "sha512-UhkXRkMPtBgE4OatZtYVtDsT3HFUliqAJcs49XQaZv8d2sbeTzEhpJVpMaCqBR3HGhb1WpyoodaFXQaMuOLPEg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
|
||||
9
package.json
generated
9
package.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tree-sitter-grammars/tree-sitter-hcl",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"description": "HCL and terraform grammar for tree-sitter",
|
||||
"repository": "https://github.com/tree-sitter-grammars/tree-sitter-hcl",
|
||||
"license": "Apache-2.0",
|
||||
@@ -30,10 +30,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"prebuildify": "^6.0.1",
|
||||
"tree-sitter-cli": "^0.25.3"
|
||||
"tree-sitter-cli": "^0.25.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tree-sitter": "^0.22.4"
|
||||
"tree-sitter": "^0.25.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"tree-sitter": {
|
||||
@@ -46,5 +46,8 @@
|
||||
"prestart": "tree-sitter build --wasm",
|
||||
"start": "tree-sitter playground",
|
||||
"test": "node --test bindings/node/*_test.js"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
|
||||
28
pyproject.toml
generated
Normal file
28
pyproject.toml
generated
Normal file
@@ -0,0 +1,28 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=42", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "tree-sitter-hcl"
|
||||
description = "HCL and terraform grammar for tree-sitter"
|
||||
version = "1.2.0"
|
||||
keywords = ["incremental", "parsing", "tree-sitter", "hcl"]
|
||||
classifiers = [
|
||||
"Intended Audience :: Developers",
|
||||
"Topic :: Software Development :: Compilers",
|
||||
"Topic :: Text Processing :: Linguistic",
|
||||
"Typing :: Typed",
|
||||
]
|
||||
requires-python = ">=3.10"
|
||||
license.text = "Apache-2.0"
|
||||
readme = "README.md"
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/tree-sitter-grammars/tree-sitter-hcl"
|
||||
|
||||
[project.optional-dependencies]
|
||||
core = ["tree-sitter~=0.24"]
|
||||
|
||||
[tool.cibuildwheel]
|
||||
build = "cp310-*"
|
||||
build-frontend = "build"
|
||||
77
setup.py
generated
Normal file
77
setup.py
generated
Normal file
@@ -0,0 +1,77 @@
|
||||
from os import path
|
||||
from platform import system
|
||||
from sysconfig import get_config_var
|
||||
|
||||
from setuptools import Extension, find_packages, setup
|
||||
from setuptools.command.build import build
|
||||
from setuptools.command.egg_info import egg_info
|
||||
from wheel.bdist_wheel import bdist_wheel
|
||||
|
||||
sources = [
|
||||
"bindings/python/tree_sitter_hcl/binding.c",
|
||||
"src/parser.c",
|
||||
]
|
||||
if path.exists("src/scanner.c"):
|
||||
sources.append("src/scanner.c")
|
||||
|
||||
macros: list[tuple[str, str | None]] = [
|
||||
("PY_SSIZE_T_CLEAN", None),
|
||||
("TREE_SITTER_HIDE_SYMBOLS", None),
|
||||
]
|
||||
if limited_api := not get_config_var("Py_GIL_DISABLED"):
|
||||
macros.append(("Py_LIMITED_API", "0x030A0000"))
|
||||
|
||||
if system() != "Windows":
|
||||
cflags = ["-std=c11", "-fvisibility=hidden"]
|
||||
else:
|
||||
cflags = ["/std:c11", "/utf-8"]
|
||||
|
||||
|
||||
class Build(build):
|
||||
def run(self):
|
||||
if path.isdir("queries"):
|
||||
dest = path.join(self.build_lib, "tree_sitter_hcl", "queries")
|
||||
self.copy_tree("queries", dest)
|
||||
super().run()
|
||||
|
||||
|
||||
class BdistWheel(bdist_wheel):
|
||||
def get_tag(self):
|
||||
python, abi, platform = super().get_tag()
|
||||
if python.startswith("cp"):
|
||||
python, abi = "cp310", "abi3"
|
||||
return python, abi, platform
|
||||
|
||||
|
||||
class EggInfo(egg_info):
|
||||
def find_sources(self):
|
||||
super().find_sources()
|
||||
self.filelist.recursive_include("queries", "*.scm")
|
||||
self.filelist.include("src/tree_sitter/*.h")
|
||||
|
||||
|
||||
setup(
|
||||
packages=find_packages("bindings/python"),
|
||||
package_dir={"": "bindings/python"},
|
||||
package_data={
|
||||
"tree_sitter_hcl": ["*.pyi", "py.typed"],
|
||||
"tree_sitter_hcl.queries": ["*.scm"],
|
||||
},
|
||||
ext_package="tree_sitter_hcl",
|
||||
ext_modules=[
|
||||
Extension(
|
||||
name="_binding",
|
||||
sources=sources,
|
||||
extra_compile_args=cflags,
|
||||
define_macros=macros,
|
||||
include_dirs=["src"],
|
||||
py_limited_api=limited_api,
|
||||
)
|
||||
],
|
||||
cmdclass={
|
||||
"build": Build,
|
||||
"bdist_wheel": BdistWheel,
|
||||
"egg_info": EggInfo,
|
||||
},
|
||||
zip_safe=False
|
||||
)
|
||||
@@ -7,8 +7,11 @@ pkgs.mkShell {
|
||||
gdb
|
||||
valgrind
|
||||
nodejs
|
||||
tree-sitter
|
||||
emscripten
|
||||
];
|
||||
shellHook = ''
|
||||
npm install
|
||||
export PATH="$(git rev-parse --show-toplevel)/node_modules/.bin:$PATH"
|
||||
'';
|
||||
}
|
||||
|
||||
|
||||
97
src/grammar.json
generated
97
src/grammar.json
generated
@@ -124,7 +124,8 @@
|
||||
"members": [
|
||||
{
|
||||
"type": "PATTERN",
|
||||
"value": "\\p{ID_Start}"
|
||||
"value": "\\p{ID_Start}",
|
||||
"flags": "u"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
@@ -139,7 +140,8 @@
|
||||
"members": [
|
||||
{
|
||||
"type": "PATTERN",
|
||||
"value": "\\p{ID_Continue}"
|
||||
"value": "\\p{ID_Continue}",
|
||||
"flags": "u"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
@@ -204,43 +206,55 @@
|
||||
"name": "operation"
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "index"
|
||||
}
|
||||
]
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 8,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "index"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "get_attr"
|
||||
}
|
||||
]
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 8,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "get_attr"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "splat"
|
||||
}
|
||||
]
|
||||
"type": "PREC_RIGHT",
|
||||
"value": 8,
|
||||
"content": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_expr_term"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "splat"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
@@ -1681,6 +1695,19 @@
|
||||
"content": {
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "{%"
|
||||
},
|
||||
{
|
||||
"type": "PATTERN",
|
||||
"value": ".*"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
|
||||
11124
src/parser.c
generated
11124
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))
|
||||
(variable_expr
|
||||
(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
|
||||
(operation
|
||||
(binary_operation
|
||||
(operation
|
||||
(binary_operation
|
||||
(variable_expr
|
||||
(identifier))
|
||||
(get_attr
|
||||
(identifier))
|
||||
(literal_value
|
||||
(string_lit
|
||||
(quoted_template_start)
|
||||
(quoted_template_end)))))
|
||||
(variable_expr
|
||||
(identifier))))
|
||||
(get_attr
|
||||
(identifier))
|
||||
(literal_value
|
||||
(string_lit
|
||||
(quoted_template_start)
|
||||
(quoted_template_end))))))
|
||||
(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)))
|
||||
|
||||
@@ -21,20 +21,11 @@
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "HCL and terraform grammar for tree-sitter",
|
||||
"links": {
|
||||
"repository": "https://github.com/tree-sitter-grammars/tree-sitter-hcl"
|
||||
}
|
||||
},
|
||||
"bindings": {
|
||||
"c": true,
|
||||
"go": false,
|
||||
"node": true,
|
||||
"python": false,
|
||||
"rust": true,
|
||||
"swift": true,
|
||||
"zig": false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user