Add parsing for foreach RANGE and items
This commit is contained in:
parent
02c1cdec24
commit
9d86152473
89
corpus/foreach.txt
Normal file
89
corpus/foreach.txt
Normal 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)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
44
grammar.js
44
grammar.js
|
@ -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),
|
||||||
},
|
},
|
||||||
|
|
186
src/grammar.json
186
src/grammar.json
|
@ -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": [
|
||||||
|
|
|
@ -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
11020
src/parser.c
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue