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
|
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
|
||||||
|
|||||||
10
.github/workflows/release.yaml
vendored
10
.github/workflows/release.yaml
vendored
@@ -20,9 +20,19 @@ jobs:
|
|||||||
attestations: true
|
attestations: true
|
||||||
npm:
|
npm:
|
||||||
uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main
|
uses: tree-sitter/workflows/.github/workflows/package-npm.yml@main
|
||||||
|
with:
|
||||||
|
generate: true
|
||||||
|
abi-version: 14
|
||||||
secrets:
|
secrets:
|
||||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||||
crates:
|
crates:
|
||||||
uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main
|
uses: tree-sitter/workflows/.github/workflows/package-crates.yml@main
|
||||||
secrets:
|
secrets:
|
||||||
CARGO_REGISTRY_TOKEN: ${{secrets.CARGO_TOKEN}}
|
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
|
# 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
|
## 1.1.0 - 2023-07-25
|
||||||
|
|
||||||
feature
|
feature
|
||||||
|
|||||||
2
CMakeLists.txt
generated
2
CMakeLists.txt
generated
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
project(tree-sitter-hcl
|
project(tree-sitter-hcl
|
||||||
VERSION "1.1.0"
|
VERSION "1.2.0"
|
||||||
DESCRIPTION "HCL and terraform grammar for tree-sitter"
|
DESCRIPTION "HCL and terraform grammar for tree-sitter"
|
||||||
HOMEPAGE_URL "https://github.com/tree-sitter-grammars/tree-sitter-hcl"
|
HOMEPAGE_URL "https://github.com/tree-sitter-grammars/tree-sitter-hcl"
|
||||||
LANGUAGES C)
|
LANGUAGES C)
|
||||||
|
|||||||
2
Cargo.toml
generated
2
Cargo.toml
generated
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tree-sitter-hcl"
|
name = "tree-sitter-hcl"
|
||||||
description = "HCL and terraform grammar for tree-sitter"
|
description = "HCL and terraform grammar for tree-sitter"
|
||||||
version = "1.1.0"
|
version = "1.2.0"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
keywords = ["incremental", "parsing", "tree-sitter", "hcl"]
|
keywords = ["incremental", "parsing", "tree-sitter", "hcl"]
|
||||||
|
|||||||
2
Makefile
generated
2
Makefile
generated
@@ -4,7 +4,7 @@ endif
|
|||||||
|
|
||||||
LANGUAGE_NAME := tree-sitter-hcl
|
LANGUAGE_NAME := tree-sitter-hcl
|
||||||
HOMEPAGE_URL := https://github.com/tree-sitter-grammars/tree-sitter-hcl
|
HOMEPAGE_URL := https://github.com/tree-sitter-grammars/tree-sitter-hcl
|
||||||
VERSION := 1.1.0
|
VERSION := 1.2.0
|
||||||
|
|
||||||
# repository
|
# repository
|
||||||
SRC_DIR := src
|
SRC_DIR := src
|
||||||
|
|||||||
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(
|
||||||
|
|||||||
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": [
|
"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",
|
||||||
@@ -1681,6 +1695,19 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"type": "CHOICE",
|
"type": "CHOICE",
|
||||||
"members": [
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "{%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "PATTERN",
|
||||||
|
"value": ".*"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
"members": [
|
"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));
|
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);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% test %}
|
||||||
resource "example" "literals" {
|
resource "example" "literals" {
|
||||||
attr1 = "val1"
|
attr1 = "val1"
|
||||||
tupl1 = [ 1, 2, 3.4, "foo" ]
|
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 */
|
/** @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, ")"),
|
||||||
),
|
),
|
||||||
|
|
||||||
@@ -347,6 +349,7 @@ module.exports = function make_grammar(dialect) {
|
|||||||
comment: ($) =>
|
comment: ($) =>
|
||||||
token(
|
token(
|
||||||
choice(
|
choice(
|
||||||
|
seq("{%", /.*/),
|
||||||
seq("#", /.*/),
|
seq("#", /.*/),
|
||||||
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",
|
"name": "@tree-sitter-grammars/tree-sitter-hcl",
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@tree-sitter-grammars/tree-sitter-hcl",
|
"name": "@tree-sitter-grammars/tree-sitter-hcl",
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -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",
|
||||||
|
|||||||
9
package.json
generated
9
package.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@tree-sitter-grammars/tree-sitter-hcl",
|
"name": "@tree-sitter-grammars/tree-sitter-hcl",
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"description": "HCL and terraform grammar for tree-sitter",
|
"description": "HCL and terraform grammar for tree-sitter",
|
||||||
"repository": "https://github.com/tree-sitter-grammars/tree-sitter-hcl",
|
"repository": "https://github.com/tree-sitter-grammars/tree-sitter-hcl",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
@@ -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": {
|
||||||
@@ -46,5 +46,8 @@
|
|||||||
"prestart": "tree-sitter build --wasm",
|
"prestart": "tree-sitter build --wasm",
|
||||||
"start": "tree-sitter playground",
|
"start": "tree-sitter playground",
|
||||||
"test": "node --test bindings/node/*_test.js"
|
"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
|
gdb
|
||||||
valgrind
|
valgrind
|
||||||
nodejs
|
nodejs
|
||||||
tree-sitter
|
|
||||||
emscripten
|
emscripten
|
||||||
];
|
];
|
||||||
|
shellHook = ''
|
||||||
|
npm install
|
||||||
|
export PATH="$(git rev-parse --show-toplevel)/node_modules/.bin:$PATH"
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
99
src/grammar.json
generated
99
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",
|
||||||
@@ -1681,6 +1695,19 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"type": "CHOICE",
|
"type": "CHOICE",
|
||||||
"members": [
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "{%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "PATTERN",
|
||||||
|
"value": ".*"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "SEQ",
|
"type": "SEQ",
|
||||||
"members": [
|
"members": [
|
||||||
@@ -1784,4 +1811,4 @@
|
|||||||
"inline": [],
|
"inline": [],
|
||||||
"supertypes": [],
|
"supertypes": [],
|
||||||
"reserved": {}
|
"reserved": {}
|
||||||
}
|
}
|
||||||
|
|||||||
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))
|
(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)))
|
||||||
|
|||||||
@@ -21,20 +21,11 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"description": "HCL and terraform grammar for tree-sitter",
|
"description": "HCL and terraform grammar for tree-sitter",
|
||||||
"links": {
|
"links": {
|
||||||
"repository": "https://github.com/tree-sitter-grammars/tree-sitter-hcl"
|
"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