Add parsing for foreach RANGE and items

This commit is contained in:
Uy Ha 2021-06-04 14:15:12 +02:00
parent 02c1cdec24
commit 9d86152473
5 changed files with 4790 additions and 6714 deletions

89
corpus/foreach.txt Normal file
View file

@ -0,0 +1,89 @@
========
No items
========
foreach(var)
endforeach()
---
(source_file
(command_invocation
(foreach_loop
(foreach_items
loop_var: (variable)
)
)
)
)
========
One item
========
foreach(var item)
endforeach()
---
(source_file
(command_invocation
(foreach_loop
(foreach_items
loop_var: (variable)
(seperation (space))
(arguments
(argument (unquoted_argument))
)
)
)
)
)
==========
Range stop
==========
foreach(var RANGE 10)
endforeach()
---
(source_file
(command_invocation
(foreach_loop
(foreach_range
(foreach_range_stop
loop_var: (variable)
(seperation (space))
(seperation (space))
stop: (integer)
)
)
)
)
)
================
Range start stop
================
foreach(var RANGE 0 10)
endforeach()
---
(source_file
(command_invocation
(foreach_loop
(foreach_range
(foreach_range_full
loop_var: (variable)
(seperation (space))
(seperation (space))
start: (integer)
(seperation (space))
stop: (integer)
)
)
)
)
)

View file

@ -9,13 +9,14 @@ module.exports = grammar({
space: ($) => /[ \t]+/, space: ($) => /[ \t]+/,
newline: ($) => /\n/, newline: ($) => /\n/,
identifier: ($) => /[A-Za-z_][A-Za-z0-9_]*/, identifier: ($) => /[A-Za-z_][A-Za-z0-9_]*/,
integer: ($) => /[+-]*\d+/,
escape_sequence: ($) => choice($._escape_identity, $._escape_encoded, $._escape_semicolon), escape_sequence: ($) => choice($._escape_identity, $._escape_encoded, $._escape_semicolon),
_escape_identity: ($) => /\\[^A-Za-z0-9;]/, _escape_identity: ($) => /\\[^A-Za-z0-9;]/,
_escape_encoded: ($) => choice("\\t", "\\r", "\\n"), _escape_encoded: ($) => choice("\\t", "\\r", "\\n"),
_escape_semicolon: ($) => ";", _escape_semicolon: ($) => ";",
variable: ($) => repeat1(choice(/[a-zA-Z0-9/_.+-]/, $.escape_sequence)), variable: ($) => prec.left(repeat1(choice(/[a-zA-Z0-9/_.+-]/, $.escape_sequence))),
variable_ref: ($) => choice($.normal_var, $.env_var, $.cache_var), variable_ref: ($) => choice($.normal_var, $.env_var, $.cache_var),
normal_var: ($) => seq("${", $.variable, "}"), normal_var: ($) => seq("${", $.variable, "}"),
env_var: ($) => seq("$ENV{", $.variable, "}"), env_var: ($) => seq("$ENV{", $.variable, "}"),
@ -29,7 +30,8 @@ module.exports = grammar({
_bracket_close: ($) => seq("]", repeat("="), "]"), _bracket_close: ($) => seq("]", repeat("="), "]"),
quoted_argument: ($) => seq('"', optional($.quoted_element), '"'), quoted_argument: ($) => seq('"', optional($.quoted_element), '"'),
quoted_element: ($) => repeat1(choice($.variable_ref, /[^\\"]/, $.escape_sequence, seq("\\", $.newline))), quoted_element: ($) =>
repeat1(choice($.variable_ref, /[^\\"]/, $.escape_sequence, seq("\\", $.newline))),
unquoted_argument: ($) => repeat1(choice($.variable_ref, /[^ ()#\"\\]/, $.escape_sequence)), unquoted_argument: ($) => repeat1(choice($.variable_ref, /[^ ()#\"\\]/, $.escape_sequence)),
@ -42,7 +44,8 @@ module.exports = grammar({
"foreach", "foreach",
repeat($.seperation), repeat($.seperation),
"(", "(",
choice($.foreach_range, $.foreach_lists_items, $.foreach_zip_lists), repeat($.seperation),
choice($.foreach_items, $.foreach_range, $.foreach_lists_items, $.foreach_zip_lists),
")", ")",
repeat($.command_invocation), repeat($.command_invocation),
repeat($.space), repeat($.space),
@ -52,13 +55,42 @@ module.exports = grammar({
optional($.variable), optional($.variable),
")" ")"
), ),
foreach_items: ($) => seq("items"), foreach_items: ($) =>
foreach_range: ($) => seq("a"), seq(field("loop_var", $.variable), repeat($.seperation), optional($.arguments)),
foreach_lists_items: ($) => seq("b"), foreach_lists_items: ($) => seq("b"),
foreach_zip_lists: ($) => seq("c"), foreach_zip_lists: ($) => seq("c"),
foreach_range: ($) => choice($.foreach_range_stop, $.foreach_range_full),
foreach_range_stop: ($) =>
seq(
field("loop_var", $.variable),
repeat1($.seperation),
"RANGE",
repeat1($.seperation),
field("stop", $.integer)
),
foreach_range_full: ($) =>
seq(
field("loop_var", $.variable),
repeat1($.seperation),
"RANGE",
repeat1($.seperation),
field("start", $.integer),
repeat1($.seperation),
field("stop", $.integer),
optional(seq(repeat1($.seperation), field("step", $.integer)))
),
normal_command: ($) => normal_command: ($) =>
seq(repeat($.space), $.identifier, repeat($.space), "(", repeat($.seperation), optional($.arguments), ")"), seq(
repeat($.space),
$.identifier,
repeat($.space),
"(",
repeat($.seperation),
optional($.arguments),
")"
),
command_invocation: ($) => choice($.normal_command, $.foreach_loop), command_invocation: ($) => choice($.normal_command, $.foreach_loop),
}, },

View file

@ -37,6 +37,10 @@
"type": "PATTERN", "type": "PATTERN",
"value": "[A-Za-z_][A-Za-z0-9_]*" "value": "[A-Za-z_][A-Za-z0-9_]*"
}, },
"integer": {
"type": "PATTERN",
"value": "[+-]*\\d+"
},
"escape_sequence": { "escape_sequence": {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
@ -80,6 +84,9 @@
"value": ";" "value": ";"
}, },
"variable": { "variable": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "REPEAT1", "type": "REPEAT1",
"content": { "content": {
"type": "CHOICE", "type": "CHOICE",
@ -94,6 +101,7 @@
} }
] ]
} }
}
}, },
"variable_ref": { "variable_ref": {
"type": "CHOICE", "type": "CHOICE",
@ -410,21 +418,8 @@
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
{ {
"type": "CHOICE",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL", "type": "SYMBOL",
"name": "arguments" "name": "foreach_items"
},
"named": true,
"value": "foreach_items"
},
{
"type": "BLANK"
}
]
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@ -491,12 +486,35 @@
} }
] ]
}, },
"foreach_range": { "foreach_items": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "STRING", "type": "FIELD",
"value": "a" "name": "loop_var",
"content": {
"type": "SYMBOL",
"name": "variable"
}
},
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "seperation"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "arguments"
},
{
"type": "BLANK"
}
]
} }
] ]
}, },
@ -518,6 +536,140 @@
} }
] ]
}, },
"foreach_range": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "foreach_range_stop"
},
{
"type": "SYMBOL",
"name": "foreach_range_full"
}
]
},
"foreach_range_stop": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "loop_var",
"content": {
"type": "SYMBOL",
"name": "variable"
}
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "seperation"
}
},
{
"type": "STRING",
"value": "RANGE"
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "seperation"
}
},
{
"type": "FIELD",
"name": "stop",
"content": {
"type": "SYMBOL",
"name": "integer"
}
}
]
},
"foreach_range_full": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "loop_var",
"content": {
"type": "SYMBOL",
"name": "variable"
}
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "seperation"
}
},
{
"type": "STRING",
"value": "RANGE"
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "seperation"
}
},
{
"type": "FIELD",
"name": "start",
"content": {
"type": "SYMBOL",
"name": "integer"
}
},
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "seperation"
}
},
{
"type": "FIELD",
"name": "stop",
"content": {
"type": "SYMBOL",
"name": "integer"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "seperation"
}
},
{
"type": "FIELD",
"name": "step",
"content": {
"type": "SYMBOL",
"name": "integer"
}
}
]
},
{
"type": "BLANK"
}
]
}
]
},
"normal_command": { "normal_command": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [

View file

@ -118,13 +118,24 @@
{ {
"type": "foreach_items", "type": "foreach_items",
"named": true, "named": true,
"fields": {}, "fields": {
"children": { "loop_var": {
"multiple": true, "multiple": false,
"required": true, "required": true,
"types": [ "types": [
{ {
"type": "argument", "type": "variable",
"named": true
}
]
}
},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "arguments",
"named": true "named": true
}, },
{ {
@ -145,7 +156,7 @@
"fields": {}, "fields": {},
"children": { "children": {
"multiple": true, "multiple": true,
"required": false, "required": true,
"types": [ "types": [
{ {
"type": "command_invocation", "type": "command_invocation",
@ -185,7 +196,113 @@
{ {
"type": "foreach_range", "type": "foreach_range",
"named": true, "named": true,
"fields": {} "fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "foreach_range_full",
"named": true
},
{
"type": "foreach_range_stop",
"named": true
}
]
}
},
{
"type": "foreach_range_full",
"named": true,
"fields": {
"loop_var": {
"multiple": false,
"required": true,
"types": [
{
"type": "variable",
"named": true
}
]
},
"start": {
"multiple": false,
"required": true,
"types": [
{
"type": "integer",
"named": true
}
]
},
"step": {
"multiple": false,
"required": false,
"types": [
{
"type": "integer",
"named": true
}
]
},
"stop": {
"multiple": false,
"required": true,
"types": [
{
"type": "integer",
"named": true
}
]
}
},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "seperation",
"named": true
}
]
}
},
{
"type": "foreach_range_stop",
"named": true,
"fields": {
"loop_var": {
"multiple": false,
"required": true,
"types": [
{
"type": "variable",
"named": true
}
]
},
"stop": {
"multiple": false,
"required": true,
"types": [
{
"type": "integer",
"named": true
}
]
}
},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "seperation",
"named": true
}
]
}
}, },
{ {
"type": "foreach_zip_lists", "type": "foreach_zip_lists",
@ -406,6 +523,10 @@
"type": "=", "type": "=",
"named": false "named": false
}, },
{
"type": "RANGE",
"named": false
},
{ {
"type": "[", "type": "[",
"named": false "named": false
@ -430,10 +551,6 @@
"type": "]", "type": "]",
"named": false "named": false
}, },
{
"type": "a",
"named": false
},
{ {
"type": "b", "type": "b",
"named": false "named": false
@ -454,6 +571,10 @@
"type": "identifier", "type": "identifier",
"named": true "named": true
}, },
{
"type": "integer",
"named": true
},
{ {
"type": "newline", "type": "newline",
"named": true "named": true

11020
src/parser.c

File diff suppressed because it is too large Load diff