mirror of
https://github.com/pnx/tree-sitter-dotenv
synced 2026-08-17 13:38:12 +02:00
add support for export keyword
This commit is contained in:
parent
c40585e9c0
commit
b109061d77
7 changed files with 793 additions and 400 deletions
28
grammar.js
28
grammar.js
|
|
@ -8,6 +8,8 @@ const float_fractional_part = /\.\d+/
|
||||||
module.exports = grammar({
|
module.exports = grammar({
|
||||||
name: "dotenv",
|
name: "dotenv",
|
||||||
|
|
||||||
|
word: $ => $.identifier,
|
||||||
|
|
||||||
externals: $ => [
|
externals: $ => [
|
||||||
$._end_of_assignment,
|
$._end_of_assignment,
|
||||||
],
|
],
|
||||||
|
|
@ -18,14 +20,30 @@ module.exports = grammar({
|
||||||
$.assignment,
|
$.assignment,
|
||||||
)),
|
)),
|
||||||
|
|
||||||
assignment: $ => seq(
|
assignment: $ => choice(
|
||||||
field("key", $.identifier),
|
seq(
|
||||||
"=",
|
field("key", choice(
|
||||||
optional(field("value", $._value)),
|
$.identifier,
|
||||||
$._end_of_assignment,
|
alias($.export, $.identifier),
|
||||||
|
)),
|
||||||
|
"=",
|
||||||
|
optional(field("value", $._value)),
|
||||||
|
$._end_of_assignment,
|
||||||
|
),
|
||||||
|
prec(1, seq(
|
||||||
|
$.export,
|
||||||
|
field("key", choice(
|
||||||
|
$.identifier,
|
||||||
|
alias($.export, $.identifier),
|
||||||
|
)),
|
||||||
|
"=",
|
||||||
|
optional(field("value", $._value)),
|
||||||
|
$._end_of_assignment,
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
|
|
||||||
comment: _ => /\#[^\n]*/,
|
comment: _ => /\#[^\n]*/,
|
||||||
|
export: _ => token(prec(1, 'export')),
|
||||||
|
|
||||||
identifier: _ => /[A-Za-z_][A-Za-z0-9_]*/,
|
identifier: _ => /[A-Za-z_][A-Za-z0-9_]*/,
|
||||||
variable: $ => seq('$', choice(
|
variable: $ => seq('$', choice(
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
(comment) @comment
|
(comment) @comment
|
||||||
|
|
||||||
|
(export) @keyword
|
||||||
|
|
||||||
(boolean) @constant
|
(boolean) @constant
|
||||||
|
|
||||||
(number) @number
|
(number) @number
|
||||||
|
|
|
||||||
130
src/grammar.json
generated
130
src/grammar.json
generated
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json",
|
"$schema": "https://tree-sitter.github.io/tree-sitter/assets/schemas/grammar.schema.json",
|
||||||
"name": "dotenv",
|
"name": "dotenv",
|
||||||
|
"word": "identifier",
|
||||||
"rules": {
|
"rules": {
|
||||||
"document": {
|
"document": {
|
||||||
"type": "REPEAT",
|
"type": "REPEAT",
|
||||||
|
|
@ -19,39 +20,117 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"assignment": {
|
"assignment": {
|
||||||
"type": "SEQ",
|
"type": "CHOICE",
|
||||||
"members": [
|
"members": [
|
||||||
{
|
{
|
||||||
"type": "FIELD",
|
"type": "SEQ",
|
||||||
"name": "key",
|
|
||||||
"content": {
|
|
||||||
"type": "SYMBOL",
|
|
||||||
"name": "identifier"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "STRING",
|
|
||||||
"value": "="
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "CHOICE",
|
|
||||||
"members": [
|
"members": [
|
||||||
{
|
{
|
||||||
"type": "FIELD",
|
"type": "FIELD",
|
||||||
"name": "value",
|
"name": "key",
|
||||||
"content": {
|
"content": {
|
||||||
"type": "SYMBOL",
|
"type": "CHOICE",
|
||||||
"name": "_value"
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "identifier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ALIAS",
|
||||||
|
"content": {
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "export"
|
||||||
|
},
|
||||||
|
"named": true,
|
||||||
|
"value": "identifier"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "BLANK"
|
"type": "STRING",
|
||||||
|
"value": "="
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CHOICE",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "FIELD",
|
||||||
|
"name": "value",
|
||||||
|
"content": {
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "_value"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "BLANK"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "_end_of_assignment"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "SYMBOL",
|
"type": "PREC",
|
||||||
"name": "_end_of_assignment"
|
"value": 1,
|
||||||
|
"content": {
|
||||||
|
"type": "SEQ",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "export"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "FIELD",
|
||||||
|
"name": "key",
|
||||||
|
"content": {
|
||||||
|
"type": "CHOICE",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "identifier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ALIAS",
|
||||||
|
"content": {
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "export"
|
||||||
|
},
|
||||||
|
"named": true,
|
||||||
|
"value": "identifier"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "="
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "CHOICE",
|
||||||
|
"members": [
|
||||||
|
{
|
||||||
|
"type": "FIELD",
|
||||||
|
"name": "value",
|
||||||
|
"content": {
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "_value"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "BLANK"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "SYMBOL",
|
||||||
|
"name": "_end_of_assignment"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -59,6 +138,17 @@
|
||||||
"type": "PATTERN",
|
"type": "PATTERN",
|
||||||
"value": "\\#[^\\n]*"
|
"value": "\\#[^\\n]*"
|
||||||
},
|
},
|
||||||
|
"export": {
|
||||||
|
"type": "TOKEN",
|
||||||
|
"content": {
|
||||||
|
"type": "PREC",
|
||||||
|
"value": 1,
|
||||||
|
"content": {
|
||||||
|
"type": "STRING",
|
||||||
|
"value": "export"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"type": "PATTERN",
|
"type": "PATTERN",
|
||||||
"value": "[A-Za-z_][A-Za-z0-9_]*"
|
"value": "[A-Za-z_][A-Za-z0-9_]*"
|
||||||
|
|
|
||||||
14
src/node-types.json
generated
14
src/node-types.json
generated
|
|
@ -39,6 +39,16 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"children": {
|
||||||
|
"multiple": false,
|
||||||
|
"required": false,
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"type": "export",
|
||||||
|
"named": true
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -161,6 +171,10 @@
|
||||||
"type": "decimal",
|
"type": "decimal",
|
||||||
"named": true
|
"named": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "export",
|
||||||
|
"named": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "float",
|
"type": "float",
|
||||||
"named": true
|
"named": true
|
||||||
|
|
|
||||||
923
src/parser.c
generated
923
src/parser.c
generated
File diff suppressed because it is too large
Load diff
40
src/tree_sitter/array.h
generated
40
src/tree_sitter/array.h
generated
|
|
@ -50,18 +50,12 @@ extern "C" {
|
||||||
/// memory allocated for the array's contents.
|
/// memory allocated for the array's contents.
|
||||||
#define array_clear(self) ((self)->size = 0)
|
#define array_clear(self) ((self)->size = 0)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#define _array__cast(self, expr) (decltype((self)->contents))(expr)
|
|
||||||
#else
|
|
||||||
#define _array__cast(self, expr) (expr)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Reserve `new_capacity` elements of space in the array. If `new_capacity` is
|
/// Reserve `new_capacity` elements of space in the array. If `new_capacity` is
|
||||||
/// less than the array's current capacity, this function has no effect.
|
/// less than the array's current capacity, this function has no effect.
|
||||||
#define array_reserve(self, new_capacity) \
|
#define array_reserve(self, new_capacity) \
|
||||||
((self)->contents = _array__cast(self, _array__reserve( \
|
((self)->contents = _array__reserve( \
|
||||||
(void *)(self)->contents, &(self)->capacity, \
|
(void *)(self)->contents, &(self)->capacity, \
|
||||||
array_elem_size(self), new_capacity)) \
|
array_elem_size(self), new_capacity) \
|
||||||
)
|
)
|
||||||
|
|
||||||
/// Free any memory allocated for this array. Note that this does not free any
|
/// Free any memory allocated for this array. Note that this does not free any
|
||||||
|
|
@ -77,10 +71,10 @@ extern "C" {
|
||||||
/// Push a new `element` onto the end of the array.
|
/// Push a new `element` onto the end of the array.
|
||||||
#define array_push(self, element) \
|
#define array_push(self, element) \
|
||||||
do { \
|
do { \
|
||||||
(self)->contents = _array__cast(self, _array__grow( \
|
(self)->contents = _array__grow( \
|
||||||
(void *)(self)->contents, (self)->size, &(self)->capacity, \
|
(void *)(self)->contents, (self)->size, &(self)->capacity, \
|
||||||
1, array_elem_size(self) \
|
1, array_elem_size(self) \
|
||||||
)); \
|
); \
|
||||||
(self)->contents[(self)->size++] = (element); \
|
(self)->contents[(self)->size++] = (element); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
@ -89,10 +83,10 @@ extern "C" {
|
||||||
#define array_grow_by(self, count) \
|
#define array_grow_by(self, count) \
|
||||||
do { \
|
do { \
|
||||||
if ((count) == 0) break; \
|
if ((count) == 0) break; \
|
||||||
(self)->contents = _array__cast(self, _array__grow( \
|
(self)->contents = _array__grow( \
|
||||||
(self)->contents, (self)->size, &(self)->capacity, \
|
(self)->contents, (self)->size, &(self)->capacity, \
|
||||||
count, array_elem_size(self) \
|
count, array_elem_size(self) \
|
||||||
)); \
|
); \
|
||||||
memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \
|
memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \
|
||||||
(self)->size += (count); \
|
(self)->size += (count); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
@ -104,26 +98,26 @@ extern "C" {
|
||||||
/// Append `count` elements to the end of the array, reading their values from the
|
/// Append `count` elements to the end of the array, reading their values from the
|
||||||
/// `contents` pointer.
|
/// `contents` pointer.
|
||||||
#define array_extend(self, count, other_contents) \
|
#define array_extend(self, count, other_contents) \
|
||||||
((self)->contents = _array__cast(self, _array__splice( \
|
(self)->contents = _array__splice( \
|
||||||
(void*)(self)->contents, &(self)->size, &(self)->capacity, \
|
(void*)(self)->contents, &(self)->size, &(self)->capacity, \
|
||||||
array_elem_size(self), (self)->size, 0, count, other_contents \
|
array_elem_size(self), (self)->size, 0, count, other_contents \
|
||||||
)))
|
)
|
||||||
|
|
||||||
/// Remove `old_count` elements from the array starting at the given `index`. At
|
/// Remove `old_count` elements from the array starting at the given `index`. At
|
||||||
/// the same index, insert `new_count` new elements, reading their values from the
|
/// the same index, insert `new_count` new elements, reading their values from the
|
||||||
/// `new_contents` pointer.
|
/// `new_contents` pointer.
|
||||||
#define array_splice(self, _index, old_count, new_count, new_contents) \
|
#define array_splice(self, _index, old_count, new_count, new_contents) \
|
||||||
((self)->contents = _array__cast(self, _array__splice( \
|
(self)->contents = _array__splice( \
|
||||||
(void *)(self)->contents, &(self)->size, &(self)->capacity, \
|
(void *)(self)->contents, &(self)->size, &(self)->capacity, \
|
||||||
array_elem_size(self), _index, old_count, new_count, new_contents \
|
array_elem_size(self), _index, old_count, new_count, new_contents \
|
||||||
)))
|
)
|
||||||
|
|
||||||
/// Insert one `element` into the array at the given `index`.
|
/// Insert one `element` into the array at the given `index`.
|
||||||
#define array_insert(self, _index, element) \
|
#define array_insert(self, _index, element) \
|
||||||
((self)->contents = _array__cast(self, _array__splice( \
|
(self)->contents = _array__splice( \
|
||||||
(void *)(self)->contents, &(self)->size, &(self)->capacity, \
|
(void *)(self)->contents, &(self)->size, &(self)->capacity, \
|
||||||
array_elem_size(self), _index, 0, 1, &(element) \
|
array_elem_size(self), _index, 0, 1, &(element) \
|
||||||
)))
|
)
|
||||||
|
|
||||||
/// Remove one element from the array at the given `index`.
|
/// Remove one element from the array at the given `index`.
|
||||||
#define array_erase(self, _index) \
|
#define array_erase(self, _index) \
|
||||||
|
|
@ -134,17 +128,17 @@ extern "C" {
|
||||||
|
|
||||||
/// Assign the contents of one array to another, reallocating if necessary.
|
/// Assign the contents of one array to another, reallocating if necessary.
|
||||||
#define array_assign(self, other) \
|
#define array_assign(self, other) \
|
||||||
((self)->contents = _array__cast(self, _array__assign( \
|
(self)->contents = _array__assign( \
|
||||||
(void *)(self)->contents, &(self)->size, &(self)->capacity, \
|
(void *)(self)->contents, &(self)->size, &(self)->capacity, \
|
||||||
(const void *)(other)->contents, (other)->size, array_elem_size(self) \
|
(const void *)(other)->contents, (other)->size, array_elem_size(self) \
|
||||||
)))
|
)
|
||||||
|
|
||||||
/// Swap one array with another
|
/// Swap one array with another
|
||||||
#define array_swap(self, other) \
|
#define array_swap(self, other) \
|
||||||
do { \
|
do { \
|
||||||
void *_array_swap_tmp = (void *)(self)->contents; \
|
void *_array_swap_tmp = (void *)(self)->contents; \
|
||||||
(self)->contents = (other)->contents; \
|
(self)->contents = (other)->contents; \
|
||||||
(other)->contents = _array__cast(other, _array_swap_tmp); \
|
(other)->contents = _array_swap_tmp; \
|
||||||
_array__swap(&(self)->size, &(self)->capacity, \
|
_array__swap(&(self)->size, &(self)->capacity, \
|
||||||
&(other)->size, &(other)->capacity); \
|
&(other)->size, &(other)->capacity); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
|
||||||
56
test/corpus/export.txt
Normal file
56
test/corpus/export.txt
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
================================================================================
|
||||||
|
Export keyword
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
export VAR=one
|
||||||
|
export VAR = one
|
||||||
|
export TAB=two
|
||||||
|
export export=var
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(document
|
||||||
|
(assignment
|
||||||
|
(export)
|
||||||
|
(identifier)
|
||||||
|
(value))
|
||||||
|
(assignment
|
||||||
|
(export)
|
||||||
|
(identifier)
|
||||||
|
(value))
|
||||||
|
(assignment
|
||||||
|
(export)
|
||||||
|
(identifier)
|
||||||
|
(value))
|
||||||
|
(assignment
|
||||||
|
(export)
|
||||||
|
(identifier)
|
||||||
|
(value))
|
||||||
|
)
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
Export-like identifiers
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
export=one
|
||||||
|
export = one
|
||||||
|
exportVAR=two
|
||||||
|
exportVAR = two
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(document
|
||||||
|
(assignment
|
||||||
|
key: (identifier)
|
||||||
|
value: (value))
|
||||||
|
(assignment
|
||||||
|
key: (identifier)
|
||||||
|
value: (value))
|
||||||
|
(assignment
|
||||||
|
key: (identifier)
|
||||||
|
value: (value))
|
||||||
|
(assignment
|
||||||
|
key: (identifier)
|
||||||
|
value: (value))
|
||||||
|
)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue