1
0
Fork 0
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:
Henrik Hautakoski 2026-07-14 20:14:41 +02:00
parent c40585e9c0
commit b109061d77
7 changed files with 793 additions and 400 deletions

View file

@ -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(

View file

@ -2,6 +2,8 @@
(comment) @comment (comment) @comment
(export) @keyword
(boolean) @constant (boolean) @constant
(number) @number (number) @number

130
src/grammar.json generated
View file

@ -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
View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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
View 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))
)