tree-sitter-sed 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +1 -1
- package/README.md +7 -1
- package/bindings/rust/build.rs +1 -0
- package/common/grammar.js +1033 -424
- package/common/scanner.h +919 -1090
- package/common/tokens.h +328 -0
- package/package.json +7 -6
- package/queries/highlights.scm +57 -32
- package/sed_ere/queries/highlights.scm +67 -33
- package/sed_ere/src/grammar.json +6189 -2979
- package/sed_ere/src/node-types.json +355 -535
- package/sed_ere/src/parser.c +72688 -41725
- package/src/grammar.json +5873 -2705
- package/src/node-types.json +372 -555
- package/src/parser.c +85733 -52320
- package/test/bindings.test.rs +174 -70
- package/tree-sitter.json +4 -3
- package/common/dsl.js +0 -39
- package/common/regex.js +0 -551
package/common/grammar.js
CHANGED
|
@@ -1,77 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
defineIssueRules,
|
|
3
|
-
issueField,
|
|
4
|
-
issueNode,
|
|
5
|
-
namedExternal,
|
|
6
|
-
} from "./dsl.js";
|
|
7
|
-
import regularExpressionRules from "./regex.js";
|
|
8
|
-
|
|
9
|
-
function missingAtEndOrBoundary($, reason) {
|
|
10
|
-
return choice(
|
|
11
|
-
issueField($, reason),
|
|
12
|
-
issueField($, `nonconforming_${reason}`),
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function blankSeparatedFileOperand($, name, operand) {
|
|
17
|
-
return seq(
|
|
18
|
-
$._blanks,
|
|
19
|
-
choice(operand, missingAtEndOrBoundary($, `missing_${name}`)),
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function fileOperandForms($, name, operand) {
|
|
24
|
-
return [
|
|
25
|
-
blankSeparatedFileOperand($, name, operand),
|
|
26
|
-
seq(issueField($, "omitted_file_separator"), operand),
|
|
27
|
-
missingAtEndOrBoundary($, `missing_${name}`),
|
|
28
|
-
];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function sourcePiece($, external, leaf) {
|
|
32
|
-
return choice(
|
|
33
|
-
namedExternal($, external, leaf),
|
|
34
|
-
issueField($, "nul_character"),
|
|
35
|
-
issueField($, "invalid_encoding"),
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function sourcePieces($, leaf, external) {
|
|
40
|
-
return prec.right(repeat1(sourcePiece($, external, leaf)));
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function lineOperand($, first, rest) {
|
|
44
|
-
return prec.right(
|
|
45
|
-
seq(
|
|
46
|
-
sourcePiece($, first, "file_literal"),
|
|
47
|
-
repeat(sourcePiece($, rest, "file_literal")),
|
|
48
|
-
),
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function operandAtoms($, literal, ...atoms) {
|
|
53
|
-
return repeat1(
|
|
54
|
-
choice(
|
|
55
|
-
literal,
|
|
56
|
-
seq($._escape_prefix, issueField($, "invalid_encoding")),
|
|
57
|
-
issueField($, "nul_character"),
|
|
58
|
-
issueField($, "invalid_encoding"),
|
|
59
|
-
...atoms,
|
|
60
|
-
),
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function missingCommandSeparator($) {
|
|
65
|
-
return choice(
|
|
66
|
-
issueNode($, "missing_command_separator"),
|
|
67
|
-
issueNode($, "incomplete_missing_command_separator"),
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function functionVerb($, spelling) {
|
|
72
|
-
return field("verb", alias(spelling, $.function_verb));
|
|
73
|
-
}
|
|
74
|
-
|
|
75
1
|
const functionDefinitions = [
|
|
76
2
|
{ rule: "block_function", spelling: "{", form: "block" },
|
|
77
3
|
{
|
|
@@ -120,6 +46,12 @@ const functionDefinitions = [
|
|
|
120
46
|
lineTerminated: true,
|
|
121
47
|
},
|
|
122
48
|
{ rule: "substitute_function", spelling: "s", form: "substitute" },
|
|
49
|
+
{
|
|
50
|
+
rule: "_write_substitute_function",
|
|
51
|
+
spelling: "s",
|
|
52
|
+
form: "substitute",
|
|
53
|
+
writeTerminated: true,
|
|
54
|
+
},
|
|
123
55
|
{
|
|
124
56
|
rule: "test_function",
|
|
125
57
|
spelling: "t",
|
|
@@ -155,44 +87,185 @@ const functionDefinitions = [
|
|
|
155
87
|
},
|
|
156
88
|
];
|
|
157
89
|
|
|
158
|
-
// Matching known verbs here creates GLR branches that compete with valid
|
|
159
|
-
// commands.
|
|
160
90
|
const unknownFunctionCharacter = new RegExp(
|
|
161
91
|
`[^ \\t0-9$\\/\\\\!;}\\n${functionDefinitions
|
|
162
92
|
.map(({ spelling }) => spelling)
|
|
163
93
|
.join("")}]`,
|
|
164
94
|
);
|
|
165
95
|
|
|
166
|
-
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
};
|
|
96
|
+
function defineIssueRules(definitions) {
|
|
97
|
+
const rules = {};
|
|
98
|
+
for (const { reason, id = reason, outcome, rule } of definitions) {
|
|
99
|
+
rules[`_${id}_reason`] = rule;
|
|
100
|
+
rules[`_${id}_outcome`] = ($) => alias($[`_${id}_reason`], $[reason]);
|
|
101
|
+
rules[`_${id}_issue`] = ($) => alias($[`_${id}_outcome`], $[outcome]);
|
|
102
|
+
}
|
|
103
|
+
return rules;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function issueField($, id) {
|
|
107
|
+
return field("issue", alias($[`_${id}_issue`], $.syntax_issue));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function missingAtEndOrBoundary($, reason) {
|
|
111
|
+
return choice(
|
|
112
|
+
issueField($, reason),
|
|
113
|
+
issueField($, `nonconforming_${reason}`),
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function blankSeparatedFileOperand($, name, operand) {
|
|
118
|
+
return seq(
|
|
119
|
+
$._blanks,
|
|
120
|
+
choice(operand, missingAtEndOrBoundary($, `missing_${name}`)),
|
|
121
|
+
);
|
|
122
|
+
}
|
|
172
123
|
|
|
173
|
-
function
|
|
124
|
+
function fileOperandForms($, name, operand) {
|
|
174
125
|
return [
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
),
|
|
126
|
+
blankSeparatedFileOperand($, name, operand),
|
|
127
|
+
seq(issueField($, "omitted_file_separator"), operand),
|
|
128
|
+
missingAtEndOrBoundary($, `missing_${name}`),
|
|
179
129
|
];
|
|
180
130
|
}
|
|
181
131
|
|
|
182
|
-
function
|
|
132
|
+
function sourcePiece($, external, leaf) {
|
|
133
|
+
return choice(
|
|
134
|
+
alias(external, $[leaf]),
|
|
135
|
+
issueField($, "nul_character"),
|
|
136
|
+
issueField($, "invalid_encoding"),
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function lineOperand($, first, rest) {
|
|
141
|
+
return prec.right(
|
|
142
|
+
seq(
|
|
143
|
+
sourcePiece($, first, "file_literal"),
|
|
144
|
+
repeat(sourcePiece($, rest, "file_literal")),
|
|
145
|
+
),
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function operandAtoms($, literal, ...atoms) {
|
|
150
|
+
return repeat1(
|
|
151
|
+
choice(
|
|
152
|
+
literal,
|
|
153
|
+
seq($._escape_prefix, issueField($, "invalid_encoding")),
|
|
154
|
+
issueField($, "nul_character"),
|
|
155
|
+
issueField($, "invalid_encoding"),
|
|
156
|
+
...atoms,
|
|
157
|
+
),
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function missingCommandSeparator($) {
|
|
183
162
|
return choice(
|
|
184
|
-
|
|
185
|
-
|
|
163
|
+
issueField($, "missing_command_separator"),
|
|
164
|
+
issueField($, "incomplete_missing_command_separator"),
|
|
186
165
|
);
|
|
187
166
|
}
|
|
188
167
|
|
|
168
|
+
function functionVerb($, spelling) {
|
|
169
|
+
return field("verb", alias(spelling, $.function_verb));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const exclusiveSubstitutionFlags = [
|
|
173
|
+
{
|
|
174
|
+
bit: 1,
|
|
175
|
+
flag: ($) => alias("g", $.global_flag),
|
|
176
|
+
conflict: "conflicting_global_flag",
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
bit: 2,
|
|
180
|
+
flag: ($) => $.occurrence_flag,
|
|
181
|
+
conflict: "conflicting_occurrence_flag",
|
|
182
|
+
},
|
|
183
|
+
];
|
|
184
|
+
|
|
185
|
+
function substitutionFlagRules() {
|
|
186
|
+
const rules = {};
|
|
187
|
+
for (const ending of ["plain", "write", "postwrite"]) {
|
|
188
|
+
for (const seen of [0, 1, 2, 3]) {
|
|
189
|
+
rules[`_flags_${ending}_${seen}`] = ($) => {
|
|
190
|
+
const steady = [
|
|
191
|
+
alias("i", $.case_insensitive_flag),
|
|
192
|
+
alias("p", $.print_flag),
|
|
193
|
+
...(ending === "postwrite"
|
|
194
|
+
? [
|
|
195
|
+
choice(
|
|
196
|
+
alias("w", $.substitution_flag),
|
|
197
|
+
issueField($, "nonfinal_write_flag"),
|
|
198
|
+
),
|
|
199
|
+
]
|
|
200
|
+
: [
|
|
201
|
+
issueField($, "invalid_substitution_flag"),
|
|
202
|
+
issueField($, "invalid_encoding"),
|
|
203
|
+
]),
|
|
204
|
+
];
|
|
205
|
+
const transitions = [];
|
|
206
|
+
for (const { bit, flag, conflict } of exclusiveSubstitutionFlags) {
|
|
207
|
+
const symbol = seen & ~bit ? issueField($, conflict) : flag($);
|
|
208
|
+
if (seen & bit) {
|
|
209
|
+
steady.push(symbol);
|
|
210
|
+
} else {
|
|
211
|
+
const tail = $[`_flags_${ending}_${seen | bit}`];
|
|
212
|
+
transitions.push(
|
|
213
|
+
seq(symbol, ending === "write" ? tail : optional(tail)),
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (ending === "write") {
|
|
218
|
+
return prec.right(
|
|
219
|
+
seq(
|
|
220
|
+
repeat(choice(...steady)),
|
|
221
|
+
choice(
|
|
222
|
+
alias($[`_write_flag_${seen}`], $.write_flag),
|
|
223
|
+
...transitions,
|
|
224
|
+
),
|
|
225
|
+
),
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
return prec.right(
|
|
229
|
+
transitions.length === 0
|
|
230
|
+
? repeat1(choice(...steady))
|
|
231
|
+
: choice(
|
|
232
|
+
repeat1(choice(...steady)),
|
|
233
|
+
seq(repeat(choice(...steady)), choice(...transitions)),
|
|
234
|
+
),
|
|
235
|
+
);
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
for (const seen of [0, 1, 2, 3]) {
|
|
240
|
+
rules[`_write_flag_${seen}`] = ($) => {
|
|
241
|
+
const wfile = field("wfile", alias($._substitution_wfile, $.wfile));
|
|
242
|
+
return choice(
|
|
243
|
+
seq(
|
|
244
|
+
field("verb", alias("w", $.substitution_flag)),
|
|
245
|
+
choice(
|
|
246
|
+
...fileOperandForms($, "wfile", wfile),
|
|
247
|
+
seq(issueField($, "incomplete_omitted_file_separator"), wfile),
|
|
248
|
+
),
|
|
249
|
+
),
|
|
250
|
+
seq(
|
|
251
|
+
issueField($, "nonfinal_write_flag"),
|
|
252
|
+
$[`_flags_postwrite_${seen}`],
|
|
253
|
+
blankSeparatedFileOperand($, "wfile", wfile),
|
|
254
|
+
),
|
|
255
|
+
);
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
return rules;
|
|
259
|
+
}
|
|
260
|
+
|
|
189
261
|
function delimiter($, name) {
|
|
190
|
-
return
|
|
262
|
+
return alias($[`_${name}`], $.delimiter);
|
|
191
263
|
}
|
|
192
264
|
|
|
193
265
|
function missingOpeningDelimiter($) {
|
|
194
266
|
return choice(
|
|
195
267
|
issueField($, "invalid_delimiter"),
|
|
268
|
+
issueField($, "invalid_encoding"),
|
|
196
269
|
issueField($, "missing_opening_delimiter"),
|
|
197
270
|
issueField($, "nonconforming_missing_opening_delimiter"),
|
|
198
271
|
);
|
|
@@ -217,6 +290,23 @@ function semicolonSeparator($) {
|
|
|
217
290
|
return alias(";", $.command_separator);
|
|
218
291
|
}
|
|
219
292
|
|
|
293
|
+
function writeCommandUnit($, block = false) {
|
|
294
|
+
return seq(
|
|
295
|
+
editingCommand($, "write_terminated"),
|
|
296
|
+
choice(
|
|
297
|
+
newlineSeparator($),
|
|
298
|
+
alias(
|
|
299
|
+
block ? $._write_block_terminal_separator : $._write_terminal_separator,
|
|
300
|
+
$.command_separator,
|
|
301
|
+
),
|
|
302
|
+
issueField($, "undefined_write_command_separator"),
|
|
303
|
+
...(block
|
|
304
|
+
? []
|
|
305
|
+
: [issueField($, "missing_separator_before_unmatched_brace")]),
|
|
306
|
+
),
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
220
310
|
function commandListRules() {
|
|
221
311
|
return {
|
|
222
312
|
script: ($) => optional(alias($._script_command_list, $.command_list)),
|
|
@@ -249,17 +339,12 @@ function commandListRules() {
|
|
|
249
339
|
seq(
|
|
250
340
|
field(
|
|
251
341
|
"suppression",
|
|
252
|
-
|
|
253
|
-
$,
|
|
254
|
-
$._default_output_suppression,
|
|
255
|
-
"default_output_suppression",
|
|
256
|
-
),
|
|
342
|
+
alias($._default_output_suppression, $.default_output_suppression),
|
|
257
343
|
),
|
|
258
344
|
repeat(sourcePiece($, $._comment_text, "comment_text")),
|
|
259
345
|
),
|
|
260
346
|
|
|
261
|
-
// Explicit recursion makes cursor traversal quadratic
|
|
262
|
-
// balanced.
|
|
347
|
+
// Explicit recursion makes cursor traversal quadratic.
|
|
263
348
|
_command_list: ($) =>
|
|
264
349
|
choice(
|
|
265
350
|
seq(
|
|
@@ -272,12 +357,13 @@ function commandListRules() {
|
|
|
272
357
|
|
|
273
358
|
_command_unit: ($) =>
|
|
274
359
|
choice(
|
|
360
|
+
writeCommandUnit($),
|
|
275
361
|
seq(
|
|
276
362
|
$._separable_command_item,
|
|
277
363
|
choice(
|
|
278
364
|
semicolonSeparator($),
|
|
279
365
|
newlineSeparator($),
|
|
280
|
-
|
|
366
|
+
issueField($, "missing_separator_before_unmatched_brace"),
|
|
281
367
|
),
|
|
282
368
|
),
|
|
283
369
|
seq(
|
|
@@ -285,15 +371,15 @@ function commandListRules() {
|
|
|
285
371
|
choice(
|
|
286
372
|
semicolonSeparator($),
|
|
287
373
|
newlineSeparator($),
|
|
288
|
-
|
|
289
|
-
|
|
374
|
+
issueField($, "missing_separator_before_unmatched_brace"),
|
|
375
|
+
issueField($, "missing_separator_after_unmatched_brace"),
|
|
290
376
|
),
|
|
291
377
|
),
|
|
292
378
|
seq(
|
|
293
379
|
editingCommand($, "line_terminated"),
|
|
294
380
|
choice(
|
|
295
381
|
newlineSeparator($),
|
|
296
|
-
|
|
382
|
+
issueField($, "missing_separator_before_unmatched_brace"),
|
|
297
383
|
),
|
|
298
384
|
),
|
|
299
385
|
editingCommand($, "recovered_line_terminated"),
|
|
@@ -304,12 +390,13 @@ function commandListRules() {
|
|
|
304
390
|
$._separable_command_item,
|
|
305
391
|
$._unmatched_closing_brace_item,
|
|
306
392
|
editingCommand($, "line_terminated"),
|
|
393
|
+
editingCommand($, "write_terminated"),
|
|
307
394
|
),
|
|
308
395
|
|
|
309
396
|
_unmatched_closing_brace_item: ($) =>
|
|
310
397
|
seq(
|
|
311
398
|
optional($._brace_leading_blanks),
|
|
312
|
-
|
|
399
|
+
issueField($, "unmatched_closing_brace"),
|
|
313
400
|
optional($._blanks),
|
|
314
401
|
),
|
|
315
402
|
|
|
@@ -323,15 +410,13 @@ function commandListRules() {
|
|
|
323
410
|
_block_commands: ($) =>
|
|
324
411
|
choice(
|
|
325
412
|
repeat1($._block_unit),
|
|
326
|
-
seq(
|
|
327
|
-
|
|
328
|
-
optional($._block_item),
|
|
329
|
-
missingCommandSeparator($),
|
|
330
|
-
),
|
|
413
|
+
seq(repeat($._block_unit), $._block_item, missingCommandSeparator($)),
|
|
414
|
+
missingCommandSeparator($),
|
|
331
415
|
),
|
|
332
416
|
|
|
333
417
|
_block_unit: ($) =>
|
|
334
418
|
choice(
|
|
419
|
+
writeCommandUnit($, true),
|
|
335
420
|
seq(
|
|
336
421
|
$._separable_command_item,
|
|
337
422
|
choice(semicolonSeparator($), newlineSeparator($)),
|
|
@@ -341,7 +426,11 @@ function commandListRules() {
|
|
|
341
426
|
),
|
|
342
427
|
|
|
343
428
|
_block_item: ($) =>
|
|
344
|
-
choice(
|
|
429
|
+
choice(
|
|
430
|
+
$._separable_command_item,
|
|
431
|
+
editingCommand($, "line_terminated"),
|
|
432
|
+
editingCommand($, "write_terminated"),
|
|
433
|
+
),
|
|
345
434
|
|
|
346
435
|
empty_command: ($) => seq(optional($._blanks), $._empty_command_marker),
|
|
347
436
|
|
|
@@ -356,8 +445,13 @@ function omittedAddress($) {
|
|
|
356
445
|
);
|
|
357
446
|
}
|
|
358
447
|
|
|
448
|
+
const regularExpressionRules = {
|
|
449
|
+
bre: { expression: "basic_reg_exp", duplication: "bre_dupl_symbol" },
|
|
450
|
+
ere: { expression: "extended_reg_exp", duplication: "ere_dupl_symbol" },
|
|
451
|
+
};
|
|
452
|
+
|
|
359
453
|
function addressRules(mode) {
|
|
360
|
-
const expression = mode
|
|
454
|
+
const { expression } = regularExpressionRules[mode];
|
|
361
455
|
|
|
362
456
|
function addressChoice($) {
|
|
363
457
|
return choice(
|
|
@@ -511,14 +605,7 @@ function delimitedFunction($, spelling, name, first, middleReason, rest) {
|
|
|
511
605
|
}
|
|
512
606
|
|
|
513
607
|
function operandRules(mode) {
|
|
514
|
-
const expression = mode
|
|
515
|
-
|
|
516
|
-
function substitutionFlagChoice($) {
|
|
517
|
-
return choice(
|
|
518
|
-
...nonWriteSubstitutionFlags($),
|
|
519
|
-
issueField($, "invalid_substitution_flag"),
|
|
520
|
-
);
|
|
521
|
-
}
|
|
608
|
+
const { expression } = regularExpressionRules[mode];
|
|
522
609
|
|
|
523
610
|
return {
|
|
524
611
|
substitute_function: ($) =>
|
|
@@ -534,10 +621,7 @@ function operandRules(mode) {
|
|
|
534
621
|
seq(
|
|
535
622
|
field("closing", delimiter($, "substitute_end")),
|
|
536
623
|
optional(
|
|
537
|
-
field(
|
|
538
|
-
"flags",
|
|
539
|
-
alias($._substitution_flags, $.substitution_flags),
|
|
540
|
-
),
|
|
624
|
+
field("flags", alias($._flags_plain_0, $.substitution_flags)),
|
|
541
625
|
),
|
|
542
626
|
),
|
|
543
627
|
unterminatedDelimiter($, "replacement"),
|
|
@@ -571,30 +655,20 @@ function operandRules(mode) {
|
|
|
571
655
|
|
|
572
656
|
escaped_newline: ($) => $._replacement_escaped_newline,
|
|
573
657
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
),
|
|
658
|
+
_write_substitute_function: ($) =>
|
|
659
|
+
seq(
|
|
660
|
+
functionVerb($, "s"),
|
|
661
|
+
field("opening", delimiter($, "substitute_start")),
|
|
662
|
+
optional(field("expression", $[expression])),
|
|
663
|
+
field("middle", delimiter($, "substitute_middle")),
|
|
664
|
+
optional(field("replacement", $.replacement)),
|
|
665
|
+
field("closing", delimiter($, "substitute_end")),
|
|
666
|
+
field("flags", alias($._flags_write_0, $.substitution_flags)),
|
|
580
667
|
),
|
|
581
668
|
|
|
582
|
-
|
|
669
|
+
...substitutionFlagRules(),
|
|
583
670
|
|
|
584
|
-
|
|
585
|
-
const wfile = field("wfile", alias($._substitution_wfile, $.wfile));
|
|
586
|
-
return seq(
|
|
587
|
-
field("verb", alias("w", $.substitution_flag)),
|
|
588
|
-
choice(
|
|
589
|
-
seq(
|
|
590
|
-
$._flag_after_write_marker,
|
|
591
|
-
repeat1(postWriteSubstitutionFlagChoice($)),
|
|
592
|
-
blankSeparatedFileOperand($, "wfile", wfile),
|
|
593
|
-
),
|
|
594
|
-
...fileOperandForms($, "wfile", wfile),
|
|
595
|
-
),
|
|
596
|
-
);
|
|
597
|
-
},
|
|
671
|
+
occurrence_flag: () => /[0-9]+/,
|
|
598
672
|
|
|
599
673
|
translate_function: ($) =>
|
|
600
674
|
delimitedFunction(
|
|
@@ -673,16 +747,31 @@ function functionRules() {
|
|
|
673
747
|
$._substitution_wfile_continuation,
|
|
674
748
|
),
|
|
675
749
|
|
|
676
|
-
label: ($) =>
|
|
750
|
+
label: ($) =>
|
|
751
|
+
choice(
|
|
752
|
+
seq($._label_start, $._label_body),
|
|
753
|
+
issueField($, "nonportable_label_length"),
|
|
754
|
+
),
|
|
755
|
+
|
|
756
|
+
_label_body: ($) =>
|
|
757
|
+
prec.right(
|
|
758
|
+
repeat1(
|
|
759
|
+
choice(
|
|
760
|
+
sourcePiece($, $._label_literal, "label_literal"),
|
|
761
|
+
issueField($, "nonportable_label_character"),
|
|
762
|
+
),
|
|
763
|
+
),
|
|
764
|
+
),
|
|
677
765
|
|
|
678
|
-
comment: ($) =>
|
|
766
|
+
comment: ($) =>
|
|
767
|
+
prec.right(repeat1(sourcePiece($, $._comment_text, "comment_text"))),
|
|
679
768
|
|
|
680
769
|
comment_function: ($) =>
|
|
681
770
|
prec.right(
|
|
682
771
|
seq(functionVerb($, "#"), optional(field("comment", $.comment))),
|
|
683
772
|
),
|
|
684
773
|
|
|
685
|
-
closing_brace: (
|
|
774
|
+
closing_brace: () => token("}"),
|
|
686
775
|
};
|
|
687
776
|
|
|
688
777
|
function fileForm(form) {
|
|
@@ -715,7 +804,7 @@ function functionRules() {
|
|
|
715
804
|
seq(
|
|
716
805
|
field(
|
|
717
806
|
"separator",
|
|
718
|
-
|
|
807
|
+
alias($._argument_separator, $.argument_separator),
|
|
719
808
|
),
|
|
720
809
|
optional(field("label", $.label)),
|
|
721
810
|
),
|
|
@@ -747,10 +836,22 @@ function functionRules() {
|
|
|
747
836
|
return rules;
|
|
748
837
|
}
|
|
749
838
|
|
|
839
|
+
function commandTail($) {
|
|
840
|
+
return seq(
|
|
841
|
+
repeat(issueField($, "invalid_encoding")),
|
|
842
|
+
optional(
|
|
843
|
+
choice(
|
|
844
|
+
issueField($, "unexpected_command_text"),
|
|
845
|
+
issueField($, "incomplete_command_text"),
|
|
846
|
+
),
|
|
847
|
+
),
|
|
848
|
+
);
|
|
849
|
+
}
|
|
850
|
+
|
|
750
851
|
function unknownFunction($, id) {
|
|
751
852
|
return seq(
|
|
752
|
-
issueField($, id),
|
|
753
|
-
|
|
853
|
+
choice(issueField($, id), issueField($, "invalid_encoding")),
|
|
854
|
+
commandTail($),
|
|
754
855
|
);
|
|
755
856
|
}
|
|
756
857
|
|
|
@@ -761,18 +862,24 @@ function editingCommandRules() {
|
|
|
761
862
|
2: ($) => $.address_clause,
|
|
762
863
|
};
|
|
763
864
|
|
|
764
|
-
//
|
|
765
|
-
// GLR paths cannot merge before the function verb.
|
|
865
|
+
// Separate address limits to prevent GLR merging before the verb.
|
|
766
866
|
const wrappers = [];
|
|
767
867
|
for (const [kind, isLineTerminated] of [
|
|
768
868
|
["chainable", false],
|
|
769
869
|
["line_terminated", true],
|
|
870
|
+
["write_terminated", false],
|
|
770
871
|
]) {
|
|
771
872
|
for (const maximum of [0, 1, 2]) {
|
|
772
873
|
const names = functionDefinitions
|
|
773
874
|
.filter(
|
|
774
|
-
({
|
|
775
|
-
lineTerminated
|
|
875
|
+
({
|
|
876
|
+
lineTerminated = false,
|
|
877
|
+
writeTerminated = false,
|
|
878
|
+
maxAddresses = 2,
|
|
879
|
+
}) =>
|
|
880
|
+
writeTerminated === (kind === "write_terminated") &&
|
|
881
|
+
lineTerminated === isLineTerminated &&
|
|
882
|
+
maxAddresses === maximum,
|
|
776
883
|
)
|
|
777
884
|
.map(({ rule }) => rule);
|
|
778
885
|
if (names.length > 0) {
|
|
@@ -815,16 +922,13 @@ function editingCommandRules() {
|
|
|
815
922
|
|
|
816
923
|
const rules = {
|
|
817
924
|
_chainable_editing_command: ($) =>
|
|
818
|
-
seq(
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
),
|
|
925
|
+
seq(addressedForms($, "chainable"), commandTail($)),
|
|
926
|
+
|
|
927
|
+
_write_terminated_editing_command: ($) =>
|
|
928
|
+
seq(addressedForms($, "write_terminated"), commandTail($)),
|
|
822
929
|
|
|
823
930
|
_line_terminated_editing_command: ($) =>
|
|
824
|
-
seq(
|
|
825
|
-
addressedForms($, "line_terminated"),
|
|
826
|
-
optional(issueField($, "unexpected_command_text")),
|
|
827
|
-
),
|
|
931
|
+
seq(addressedForms($, "line_terminated"), commandTail($)),
|
|
828
932
|
|
|
829
933
|
_recovered_line_terminated_editing_command: ($) =>
|
|
830
934
|
seq(
|
|
@@ -870,7 +974,14 @@ function editingCommandRules() {
|
|
|
870
974
|
};
|
|
871
975
|
|
|
872
976
|
for (const { name, names } of wrappers) {
|
|
873
|
-
rules[name] = ($) =>
|
|
977
|
+
rules[name] = ($) =>
|
|
978
|
+
choice(
|
|
979
|
+
...names.map((name) =>
|
|
980
|
+
name === "_write_substitute_function"
|
|
981
|
+
? alias($[name], $.substitute_function)
|
|
982
|
+
: $[name],
|
|
983
|
+
),
|
|
984
|
+
);
|
|
874
985
|
}
|
|
875
986
|
|
|
876
987
|
return rules;
|
|
@@ -886,38 +997,460 @@ function sedRules(mode) {
|
|
|
886
997
|
};
|
|
887
998
|
}
|
|
888
999
|
|
|
889
|
-
const
|
|
890
|
-
{ reason: "missing_function", atBoundary: true },
|
|
891
|
-
{ reason: "missing_label", atBoundary: true },
|
|
892
|
-
{ reason: "missing_rfile", atBoundary: true },
|
|
893
|
-
{ reason: "missing_wfile", atBoundary: true },
|
|
894
|
-
{ reason: "missing_text_introducer", atBoundary: true },
|
|
895
|
-
{
|
|
896
|
-
reason: "incomplete_text_introducer",
|
|
897
|
-
rule: ($) => $._text_incomplete_introducer,
|
|
898
|
-
},
|
|
899
|
-
{ reason: "missing_text" },
|
|
900
|
-
{ reason: "missing_closing_brace" },
|
|
901
|
-
{ reason: "missing_opening_delimiter", atBoundary: true },
|
|
902
|
-
];
|
|
1000
|
+
const nonportableRangeClasses = ["character_class", "equivalence_class"];
|
|
903
1001
|
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
1002
|
+
function intervalExpression($, opening, closing) {
|
|
1003
|
+
const piece = (name) =>
|
|
1004
|
+
choice(
|
|
1005
|
+
field(name, $.duplication_count),
|
|
1006
|
+
field(name, alias($._regex_interval_escaped_count, $.escaped_delimiter)),
|
|
1007
|
+
issueField($, "invalid_interval_character"),
|
|
1008
|
+
...(opening === "{"
|
|
1009
|
+
? [issueField($, "incomplete_regular_expression_escape")]
|
|
1010
|
+
: []),
|
|
1011
|
+
issueField($, "invalid_regular_expression_character"),
|
|
1012
|
+
issueField($, "invalid_encoding"),
|
|
1013
|
+
seq(
|
|
1014
|
+
$._escape_prefix,
|
|
1015
|
+
choice(
|
|
1016
|
+
issueField($, "escaped_invalid_regular_expression_character"),
|
|
1017
|
+
issueField($, "invalid_encoding"),
|
|
1018
|
+
),
|
|
1019
|
+
),
|
|
1020
|
+
);
|
|
1021
|
+
return seq(
|
|
1022
|
+
alias($._regex_interval_open, opening),
|
|
1023
|
+
choice(
|
|
1024
|
+
repeat1(piece("minimum")),
|
|
1025
|
+
issueField($, "missing_interval_minimum"),
|
|
1026
|
+
issueField($, "incomplete_interval_minimum"),
|
|
1027
|
+
),
|
|
1028
|
+
optional(
|
|
1029
|
+
seq(
|
|
1030
|
+
choice(
|
|
1031
|
+
alias($._regex_interval_separator, ","),
|
|
1032
|
+
alias($._regex_interval_escaped_separator, $.escaped_delimiter),
|
|
1033
|
+
),
|
|
1034
|
+
repeat(
|
|
1035
|
+
choice(
|
|
1036
|
+
piece("maximum"),
|
|
1037
|
+
issueField($, "unexpected_interval_separator"),
|
|
1038
|
+
),
|
|
1039
|
+
),
|
|
1040
|
+
),
|
|
1041
|
+
),
|
|
1042
|
+
choice(
|
|
1043
|
+
alias($._regex_interval_close, closing),
|
|
1044
|
+
issueField($, "missing_interval_close"),
|
|
1045
|
+
issueField($, "incomplete_interval"),
|
|
1046
|
+
...(opening === "\\{"
|
|
1047
|
+
? [
|
|
1048
|
+
issueField($, "invalid_interval_close"),
|
|
1049
|
+
issueField($, "incomplete_interval_close"),
|
|
1050
|
+
]
|
|
1051
|
+
: []),
|
|
1052
|
+
),
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
907
1055
|
|
|
908
|
-
function
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
1056
|
+
function compoundBracketExpression(
|
|
1057
|
+
$,
|
|
1058
|
+
openingExternal,
|
|
1059
|
+
marker,
|
|
1060
|
+
contentField,
|
|
1061
|
+
content,
|
|
1062
|
+
closingExternal,
|
|
1063
|
+
...payloadIssues
|
|
1064
|
+
) {
|
|
1065
|
+
const closingIssues = [
|
|
1066
|
+
issueField($, "missing_bracket_term_close"),
|
|
1067
|
+
issueField($, "incomplete_bracket_term"),
|
|
1068
|
+
];
|
|
1069
|
+
const closing = seq(
|
|
1070
|
+
alias(closingExternal, marker),
|
|
1071
|
+
choice("]", ...closingIssues),
|
|
1072
|
+
);
|
|
1073
|
+
const payload = repeat1(
|
|
1074
|
+
choice(
|
|
1075
|
+
field(contentField, content),
|
|
1076
|
+
issueField($, "invalid_regular_expression_character"),
|
|
1077
|
+
issueField($, "invalid_encoding"),
|
|
1078
|
+
...payloadIssues.map((reason) => issueField($, reason)),
|
|
1079
|
+
),
|
|
1080
|
+
);
|
|
1081
|
+
return seq(
|
|
1082
|
+
alias(openingExternal, "["),
|
|
1083
|
+
marker,
|
|
1084
|
+
choice(
|
|
1085
|
+
payload,
|
|
1086
|
+
issueField($, "missing_bracket_term_payload"),
|
|
1087
|
+
issueField($, "incomplete_bracket_term_payload"),
|
|
1088
|
+
),
|
|
1089
|
+
choice(closing, ...closingIssues),
|
|
1090
|
+
);
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
function bracketListBody($, list) {
|
|
1094
|
+
return choice(
|
|
1095
|
+
list,
|
|
1096
|
+
issueField($, "missing_bracket_list"),
|
|
1097
|
+
issueField($, "incomplete_missing_bracket_list"),
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
function subexpressionClose($, closing) {
|
|
1102
|
+
return choice(
|
|
1103
|
+
field("closing", alias($._regex_group_close, closing)),
|
|
1104
|
+
issueField($, "unclosed_subexpression"),
|
|
1105
|
+
issueField($, "incomplete_unclosed_subexpression"),
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
function bracketExpression($, ambiguous) {
|
|
1110
|
+
return seq(
|
|
1111
|
+
alias($._regex_bracket_open, "["),
|
|
1112
|
+
bracketListBody($, choice($.matching_list, $.nonmatching_list)),
|
|
1113
|
+
...(ambiguous ? [$._ambiguous_bracket_expression_marker] : []),
|
|
1114
|
+
choice(
|
|
1115
|
+
alias($._regex_bracket_close, "]"),
|
|
1116
|
+
issueField($, "unclosed_bracket_expression"),
|
|
1117
|
+
issueField($, "incomplete_unclosed_bracket_expression"),
|
|
1118
|
+
),
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
function rangeOperator($) {
|
|
1123
|
+
return alias($._regex_bracket_hyphen, "-");
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
function nonportableRangeRules() {
|
|
1127
|
+
const rules = {};
|
|
1128
|
+
for (const kind of nonportableRangeClasses) {
|
|
1129
|
+
rules[`_${kind}_start_range`] = ($) =>
|
|
1130
|
+
seq(issueField($, `${kind}_range_start`), rangeOperator($));
|
|
1131
|
+
}
|
|
1132
|
+
for (const kind of nonportableRangeClasses) {
|
|
1133
|
+
rules[`_${kind}_end_range`] = ($) => issueField($, `${kind}_range_end`);
|
|
1134
|
+
}
|
|
1135
|
+
return rules;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
function bracketRules() {
|
|
1139
|
+
return {
|
|
1140
|
+
bracket_expression: ($) => bracketExpression($, false),
|
|
1141
|
+
|
|
1142
|
+
_ambiguous_bracket_expression: ($) => bracketExpression($, true),
|
|
1143
|
+
|
|
1144
|
+
_bracket_expression: ($) =>
|
|
1145
|
+
choice(
|
|
1146
|
+
$.bracket_expression,
|
|
1147
|
+
issueField($, "ambiguous_bracket_expression"),
|
|
1148
|
+
),
|
|
1149
|
+
|
|
1150
|
+
matching_list: ($) => $.bracket_list,
|
|
1151
|
+
|
|
1152
|
+
nonmatching_list: ($) =>
|
|
1153
|
+
seq(
|
|
1154
|
+
alias($._regex_bracket_negation, "^"),
|
|
1155
|
+
bracketListBody($, $.bracket_list),
|
|
1156
|
+
),
|
|
1157
|
+
|
|
1158
|
+
bracket_list: ($) =>
|
|
1159
|
+
seq(
|
|
1160
|
+
$.follow_list,
|
|
1161
|
+
optional(alias($._regex_bracket_trailing_hyphen, "-")),
|
|
1162
|
+
),
|
|
1163
|
+
|
|
1164
|
+
follow_list: ($) => repeat1($.expression_term),
|
|
1165
|
+
|
|
1166
|
+
expression_term: ($) =>
|
|
1167
|
+
choice(
|
|
1168
|
+
$.single_expression,
|
|
1169
|
+
$.range_expression,
|
|
1170
|
+
issueField($, "shared_range_endpoint"),
|
|
1171
|
+
),
|
|
1172
|
+
|
|
1173
|
+
single_expression: ($) =>
|
|
1174
|
+
choice($.end_range, $.character_class, $.equivalence_class),
|
|
1175
|
+
|
|
1176
|
+
range_expression: ($) =>
|
|
1177
|
+
seq(
|
|
1178
|
+
choice(
|
|
1179
|
+
$.start_range,
|
|
1180
|
+
...nonportableRangeClasses.map((kind) =>
|
|
1181
|
+
alias($[`_${kind}_start_range`], $.start_range),
|
|
1182
|
+
),
|
|
1183
|
+
),
|
|
1184
|
+
choice(
|
|
1185
|
+
$.end_range,
|
|
1186
|
+
...nonportableRangeClasses.map((kind) =>
|
|
1187
|
+
alias($[`_${kind}_end_range`], $.end_range),
|
|
1188
|
+
),
|
|
1189
|
+
alias($._regex_bracket_range_end_hyphen, "-"),
|
|
1190
|
+
),
|
|
1191
|
+
),
|
|
1192
|
+
|
|
1193
|
+
...nonportableRangeRules(),
|
|
1194
|
+
|
|
1195
|
+
start_range: ($) => seq($.end_range, rangeOperator($)),
|
|
1196
|
+
|
|
1197
|
+
end_range: ($) =>
|
|
1198
|
+
choice(
|
|
1199
|
+
alias($._regex_bracket_literal, $.collating_element_single),
|
|
1200
|
+
$.collating_symbol,
|
|
1201
|
+
issueField($, "invalid_regular_expression_character"),
|
|
1202
|
+
issueField($, "invalid_encoding"),
|
|
1203
|
+
),
|
|
1204
|
+
|
|
1205
|
+
collating_symbol: ($) =>
|
|
1206
|
+
compoundBracketExpression(
|
|
1207
|
+
$,
|
|
1208
|
+
$._regex_open_dot,
|
|
1209
|
+
".",
|
|
1210
|
+
"element",
|
|
1211
|
+
choice(
|
|
1212
|
+
alias($._regex_coll_elem_single, $.collating_element_single),
|
|
1213
|
+
alias($._regex_coll_elem_multi, $.collating_element_multi),
|
|
1214
|
+
alias($._regex_meta_char, $.meta_character),
|
|
1215
|
+
),
|
|
1216
|
+
$._regex_dot_close,
|
|
1217
|
+
),
|
|
1218
|
+
|
|
1219
|
+
equivalence_class: ($) =>
|
|
1220
|
+
compoundBracketExpression(
|
|
1221
|
+
$,
|
|
1222
|
+
$._regex_open_equal,
|
|
1223
|
+
"=",
|
|
1224
|
+
"element",
|
|
1225
|
+
choice(
|
|
1226
|
+
alias($._regex_coll_elem_single, $.collating_element_single),
|
|
1227
|
+
alias($._regex_coll_elem_multi, $.collating_element_multi),
|
|
1228
|
+
),
|
|
1229
|
+
$._regex_equal_close,
|
|
1230
|
+
"equivalence_class_meta_character",
|
|
1231
|
+
"incomplete_equivalence_class_meta_character",
|
|
1232
|
+
),
|
|
1233
|
+
|
|
1234
|
+
character_class: ($) =>
|
|
1235
|
+
compoundBracketExpression(
|
|
1236
|
+
$,
|
|
1237
|
+
$._regex_open_colon,
|
|
1238
|
+
":",
|
|
1239
|
+
"name",
|
|
1240
|
+
alias($._regex_class_name, $.class_name),
|
|
1241
|
+
$._regex_colon_close,
|
|
1242
|
+
"invalid_character_class_name",
|
|
1243
|
+
),
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
function regularExpressionEscape($) {
|
|
1248
|
+
return choice(
|
|
1249
|
+
$.quoted_character,
|
|
1250
|
+
seq(
|
|
1251
|
+
$._escape_prefix,
|
|
1252
|
+
choice(
|
|
1253
|
+
issueField($, "escaped_invalid_regular_expression_character"),
|
|
1254
|
+
issueField($, "invalid_encoding"),
|
|
1255
|
+
),
|
|
1256
|
+
),
|
|
1257
|
+
$.escaped_delimiter,
|
|
1258
|
+
issueField($, "ordinary_character_escape"),
|
|
1259
|
+
issueField($, "incomplete_regular_expression_escape"),
|
|
1260
|
+
issueField($, "forbidden_regular_expression_newline"),
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
function oneCharOrCollElem($, ...additional) {
|
|
1265
|
+
return choice(
|
|
1266
|
+
issueField($, "invalid_regular_expression_character"),
|
|
1267
|
+
issueField($, "invalid_encoding"),
|
|
1268
|
+
$.ordinary_character,
|
|
1269
|
+
regularExpressionEscape($),
|
|
1270
|
+
$.sed_newline_escape,
|
|
1271
|
+
alias($._regex_period, "."),
|
|
1272
|
+
$._bracket_expression,
|
|
1273
|
+
issueField($, "special_delimiter_escape"),
|
|
1274
|
+
...additional,
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
function commonRegularExpressionRules() {
|
|
1279
|
+
return {
|
|
1280
|
+
duplication_count: ($) => $._regex_dup_count,
|
|
1281
|
+
|
|
1282
|
+
ordinary_character: ($) => $._regex_literal,
|
|
1283
|
+
|
|
1284
|
+
quoted_character: ($) => $._regex_quoted_escape,
|
|
1285
|
+
|
|
1286
|
+
escaped_delimiter: ($) => $._regex_escaped_delimiter,
|
|
1287
|
+
|
|
1288
|
+
sed_newline_escape: ($) => $._regex_newline_escape,
|
|
1289
|
+
|
|
1290
|
+
...bracketRules(),
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
function breRules() {
|
|
1295
|
+
return {
|
|
1296
|
+
...commonRegularExpressionRules(),
|
|
1297
|
+
basic_reg_exp: ($) => $.bre_branch,
|
|
1298
|
+
|
|
1299
|
+
bre_branch: ($) => repeat1($.bre_expression),
|
|
1300
|
+
|
|
1301
|
+
bre_expression: ($) =>
|
|
1302
|
+
prec.right(
|
|
1303
|
+
choice(
|
|
1304
|
+
seq(
|
|
1305
|
+
alias($._regex_beginning_anchor, "^"),
|
|
1306
|
+
optional($.simple_bre),
|
|
1307
|
+
optional(alias($._regex_end_anchor, "$")),
|
|
1308
|
+
),
|
|
1309
|
+
seq($.simple_bre, optional(alias($._regex_end_anchor, "$"))),
|
|
1310
|
+
alias($._regex_end_anchor, "$"),
|
|
1311
|
+
),
|
|
1312
|
+
),
|
|
1313
|
+
|
|
1314
|
+
simple_bre: ($) =>
|
|
1315
|
+
seq(
|
|
1316
|
+
choice(
|
|
1317
|
+
seq($.nondupl_bre, optional($.bre_dupl_symbol)),
|
|
1318
|
+
issueField($, "leading_duplication_symbol"),
|
|
1319
|
+
),
|
|
1320
|
+
repeat(issueField($, "adjacent_duplication_symbol")),
|
|
1321
|
+
),
|
|
1322
|
+
|
|
1323
|
+
nondupl_bre: ($) =>
|
|
1324
|
+
choice(
|
|
1325
|
+
$.one_char_or_coll_elem_bre,
|
|
1326
|
+
seq(
|
|
1327
|
+
field("opening", alias($._regex_group_open, "\\(")),
|
|
1328
|
+
optional(field("expression", $.basic_reg_exp)),
|
|
1329
|
+
subexpressionClose($, "\\)"),
|
|
1330
|
+
),
|
|
1331
|
+
$.backreference,
|
|
1332
|
+
issueField($, "unmatched_subexpression_close"),
|
|
1333
|
+
issueField($, "unmatched_interval_close"),
|
|
1334
|
+
),
|
|
1335
|
+
|
|
1336
|
+
backreference: ($) => $._regex_backreference,
|
|
1337
|
+
|
|
1338
|
+
one_char_or_coll_elem_bre: ($) =>
|
|
1339
|
+
oneCharOrCollElem(
|
|
1340
|
+
$,
|
|
1341
|
+
issueField($, "bre_vertical_line_escape"),
|
|
1342
|
+
issueField($, "bre_question_mark_escape"),
|
|
1343
|
+
issueField($, "bre_plus_escape"),
|
|
1344
|
+
issueField($, "bre_subexpression_right_anchor"),
|
|
1345
|
+
issueField($, "bre_subexpression_left_anchor"),
|
|
1346
|
+
),
|
|
1347
|
+
|
|
1348
|
+
bre_dupl_symbol: ($) =>
|
|
1349
|
+
choice(alias($._regex_zero_or_more, "*"), $._bre_interval),
|
|
1350
|
+
|
|
1351
|
+
_bre_interval: ($) => intervalExpression($, "\\{", "\\}"),
|
|
1352
|
+
};
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
function ereRules() {
|
|
1356
|
+
return {
|
|
1357
|
+
...commonRegularExpressionRules(),
|
|
1358
|
+
extended_reg_exp: ($) =>
|
|
1359
|
+
choice(
|
|
1360
|
+
$.ere_branch,
|
|
1361
|
+
seq(
|
|
1362
|
+
choice($.ere_branch, $._empty_ere_branch),
|
|
1363
|
+
repeat1(
|
|
1364
|
+
seq(
|
|
1365
|
+
alias($._regex_alternation_operator, "|"),
|
|
1366
|
+
choice($.ere_branch, $._empty_ere_branch),
|
|
1367
|
+
),
|
|
1368
|
+
),
|
|
1369
|
+
),
|
|
1370
|
+
),
|
|
1371
|
+
|
|
1372
|
+
_empty_ere_branch: ($) =>
|
|
1373
|
+
choice(
|
|
1374
|
+
issueField($, "empty_alternative"),
|
|
1375
|
+
issueField($, "incomplete_alternative"),
|
|
1376
|
+
),
|
|
1377
|
+
|
|
1378
|
+
ere_branch: ($) => repeat1($.ere_expression),
|
|
1379
|
+
|
|
1380
|
+
ere_expression: ($) =>
|
|
1381
|
+
prec.left(
|
|
1382
|
+
1,
|
|
1383
|
+
seq(
|
|
1384
|
+
choice(
|
|
1385
|
+
$.one_char_or_coll_elem_ere,
|
|
1386
|
+
alias($._regex_beginning_anchor, "^"),
|
|
1387
|
+
alias($._regex_end_anchor, "$"),
|
|
1388
|
+
seq(
|
|
1389
|
+
field("opening", alias($._regex_group_open, "(")),
|
|
1390
|
+
optional(field("expression", $.extended_reg_exp)),
|
|
1391
|
+
subexpressionClose($, ")"),
|
|
1392
|
+
),
|
|
1393
|
+
issueField($, "leading_duplication_symbol"),
|
|
1394
|
+
),
|
|
1395
|
+
repeat(
|
|
1396
|
+
choice(
|
|
1397
|
+
$.ere_dupl_symbol,
|
|
1398
|
+
issueField($, "adjacent_duplication_symbol"),
|
|
1399
|
+
),
|
|
1400
|
+
),
|
|
1401
|
+
),
|
|
1402
|
+
),
|
|
1403
|
+
|
|
1404
|
+
one_char_or_coll_elem_ere: ($) => oneCharOrCollElem($),
|
|
1405
|
+
|
|
1406
|
+
ere_dupl_symbol: ($) =>
|
|
1407
|
+
seq(
|
|
1408
|
+
choice(
|
|
1409
|
+
alias($._regex_zero_or_more, "*"),
|
|
1410
|
+
alias($._regex_one_or_more, "+"),
|
|
1411
|
+
alias($._regex_zero_or_one, "?"),
|
|
1412
|
+
$._ere_interval,
|
|
1413
|
+
),
|
|
1414
|
+
optional(field("modifier", $.repetition_modifier)),
|
|
1415
|
+
),
|
|
1416
|
+
|
|
1417
|
+
_ere_interval: ($) => intervalExpression($, "{", "}"),
|
|
1418
|
+
|
|
1419
|
+
repetition_modifier: ($) => $._regex_repetition_modifier,
|
|
1420
|
+
};
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
const missingCommandDefinitions = [
|
|
1424
|
+
{ reason: "missing_function", atBoundary: true },
|
|
1425
|
+
{ reason: "missing_label", atBoundary: true },
|
|
1426
|
+
{ reason: "missing_rfile", atBoundary: true },
|
|
1427
|
+
{ reason: "missing_wfile", atBoundary: true },
|
|
1428
|
+
{ reason: "missing_text_introducer", atBoundary: true },
|
|
1429
|
+
{
|
|
1430
|
+
reason: "incomplete_text_introducer",
|
|
1431
|
+
rule: ($) => $._text_incomplete_introducer,
|
|
1432
|
+
},
|
|
1433
|
+
{ reason: "missing_text" },
|
|
1434
|
+
{ reason: "missing_closing_brace" },
|
|
1435
|
+
{ reason: "missing_opening_delimiter", atBoundary: true },
|
|
1436
|
+
];
|
|
1437
|
+
|
|
1438
|
+
const boundaryMissingReasons = missingCommandDefinitions
|
|
1439
|
+
.filter(({ atBoundary }) => atBoundary)
|
|
1440
|
+
.map(({ reason }) => reason);
|
|
1441
|
+
|
|
1442
|
+
function missingMarkerNames(mode) {
|
|
1443
|
+
return [
|
|
1444
|
+
"omitted_address",
|
|
1445
|
+
"incomplete_omitted_address",
|
|
1446
|
+
"omitted_first_address",
|
|
1447
|
+
...(mode === "ere" ? ["empty_alternative"] : []),
|
|
1448
|
+
"missing_function",
|
|
1449
|
+
"missing_label",
|
|
918
1450
|
"missing_rfile",
|
|
919
1451
|
"missing_wfile",
|
|
920
1452
|
"omitted_file_separator",
|
|
1453
|
+
"incomplete_omitted_file_separator",
|
|
921
1454
|
"missing_text_introducer",
|
|
922
1455
|
"missing_text",
|
|
923
1456
|
"missing_command_separator",
|
|
@@ -927,7 +1460,6 @@ function missingMarkerNames(mode) {
|
|
|
927
1460
|
"missing_separator_before_unmatched_brace",
|
|
928
1461
|
"missing_separator_after_unmatched_brace",
|
|
929
1462
|
...boundaryMissingReasons.map((reason) => `nonconforming_${reason}`),
|
|
930
|
-
"missing_subexpression_placeholder",
|
|
931
1463
|
"incomplete_bracket_list",
|
|
932
1464
|
"incomplete_bracket_expression",
|
|
933
1465
|
...(mode === "ere" ? ["incomplete_alternative"] : []),
|
|
@@ -942,21 +1474,48 @@ function issueDefinitions(mode) {
|
|
|
942
1474
|
|
|
943
1475
|
return [
|
|
944
1476
|
{
|
|
945
|
-
reason: "
|
|
1477
|
+
reason: "nonportable_label_character",
|
|
1478
|
+
outcome: "unspecified_syntax",
|
|
1479
|
+
rule: ($) => alias($._nonportable_label_character, $.label_literal),
|
|
1480
|
+
},
|
|
1481
|
+
{
|
|
1482
|
+
reason: "nonportable_label_length",
|
|
1483
|
+
outcome: "unspecified_syntax",
|
|
1484
|
+
rule: ($) =>
|
|
1485
|
+
seq($._long_label_start, alias($._label_literal, $.label_literal)),
|
|
1486
|
+
},
|
|
1487
|
+
{
|
|
1488
|
+
reason: "missing_bracket_term_close",
|
|
946
1489
|
outcome: "undefined_syntax",
|
|
947
|
-
rule: ($) => $.
|
|
1490
|
+
rule: ($) => $._regex_missing_bracket_term_close,
|
|
948
1491
|
},
|
|
949
1492
|
{
|
|
950
|
-
|
|
951
|
-
reason: "malformed_bracket_term",
|
|
1493
|
+
reason: "invalid_character_class_name",
|
|
952
1494
|
outcome: "undefined_syntax",
|
|
953
1495
|
rule: ($) => $._regex_invalid_class_name,
|
|
954
1496
|
},
|
|
955
1497
|
{
|
|
956
1498
|
id: "equivalence_class_meta_character",
|
|
957
|
-
reason: "
|
|
1499
|
+
reason: "invalid_equivalence_class_element",
|
|
1500
|
+
outcome: "undefined_syntax",
|
|
1501
|
+
rule: ($) => alias($._regex_meta_char, $.meta_character),
|
|
1502
|
+
},
|
|
1503
|
+
{
|
|
1504
|
+
id: "incomplete_equivalence_class_meta_character",
|
|
1505
|
+
reason: "invalid_equivalence_class_element",
|
|
1506
|
+
outcome: "incomplete_syntax",
|
|
1507
|
+
rule: ($) => alias($._regex_incomplete_meta_char, $.meta_character),
|
|
1508
|
+
},
|
|
1509
|
+
{
|
|
1510
|
+
reason: "missing_bracket_term_payload",
|
|
958
1511
|
outcome: "undefined_syntax",
|
|
959
|
-
rule: ($) =>
|
|
1512
|
+
rule: ($) => $._regex_missing_bracket_term_payload,
|
|
1513
|
+
},
|
|
1514
|
+
{
|
|
1515
|
+
id: "incomplete_bracket_term_payload",
|
|
1516
|
+
reason: "missing_bracket_term_payload",
|
|
1517
|
+
outcome: "incomplete_syntax",
|
|
1518
|
+
rule: ($) => $._regex_incomplete_bracket_term_payload,
|
|
960
1519
|
},
|
|
961
1520
|
{
|
|
962
1521
|
reason: "nul_character",
|
|
@@ -968,6 +1527,18 @@ function issueDefinitions(mode) {
|
|
|
968
1527
|
outcome: "invalid_syntax",
|
|
969
1528
|
rule: ($) => $._nul_character,
|
|
970
1529
|
},
|
|
1530
|
+
{
|
|
1531
|
+
id: "escaped_nul_character",
|
|
1532
|
+
reason: "nul_character",
|
|
1533
|
+
outcome: "nonconforming_syntax",
|
|
1534
|
+
rule: ($) => $._single_nul_character,
|
|
1535
|
+
},
|
|
1536
|
+
{
|
|
1537
|
+
id: "escaped_invalid_regular_expression_character",
|
|
1538
|
+
reason: "invalid_regular_expression_character",
|
|
1539
|
+
outcome: "invalid_syntax",
|
|
1540
|
+
rule: ($) => $._single_nul_character,
|
|
1541
|
+
},
|
|
971
1542
|
{
|
|
972
1543
|
reason: "invalid_encoding",
|
|
973
1544
|
outcome: "invalid_syntax",
|
|
@@ -986,8 +1557,7 @@ function issueDefinitions(mode) {
|
|
|
986
1557
|
{
|
|
987
1558
|
reason: "shared_range_endpoint",
|
|
988
1559
|
outcome: "undefined_syntax",
|
|
989
|
-
rule: ($) =>
|
|
990
|
-
namedExternal($, $._regex_shared_range_endpoint, "range_operator"),
|
|
1560
|
+
rule: ($) => alias($._regex_shared_range_endpoint, "-"),
|
|
991
1561
|
},
|
|
992
1562
|
{
|
|
993
1563
|
reason: "omitted_address",
|
|
@@ -1017,11 +1587,6 @@ function issueDefinitions(mode) {
|
|
|
1017
1587
|
outcome: "undefined_syntax",
|
|
1018
1588
|
rule: ($) => $._regex_nonportable_escape,
|
|
1019
1589
|
},
|
|
1020
|
-
{
|
|
1021
|
-
reason: "empty_subexpression",
|
|
1022
|
-
outcome: "undefined_syntax",
|
|
1023
|
-
rule: missing("empty_subexpression"),
|
|
1024
|
-
},
|
|
1025
1590
|
{
|
|
1026
1591
|
reason: "unclosed_subexpression",
|
|
1027
1592
|
outcome: "undefined_syntax",
|
|
@@ -1032,49 +1597,67 @@ function issueDefinitions(mode) {
|
|
|
1032
1597
|
{
|
|
1033
1598
|
reason: "unmatched_subexpression_close",
|
|
1034
1599
|
outcome: "undefined_syntax",
|
|
1035
|
-
rule: ($) =>
|
|
1036
|
-
namedExternal(
|
|
1037
|
-
$,
|
|
1038
|
-
$._regex_unmatched_group_close,
|
|
1039
|
-
"back_close_parenthesis",
|
|
1040
|
-
),
|
|
1600
|
+
rule: ($) => $._regex_unmatched_group_close,
|
|
1041
1601
|
},
|
|
1042
1602
|
{
|
|
1043
1603
|
reason: "unmatched_interval_close",
|
|
1044
1604
|
outcome: "undefined_syntax",
|
|
1045
|
-
rule: ($) =>
|
|
1046
|
-
namedExternal(
|
|
1047
|
-
$,
|
|
1048
|
-
$._regex_unmatched_interval_close,
|
|
1049
|
-
"back_close_brace",
|
|
1050
|
-
),
|
|
1605
|
+
rule: ($) => $._regex_unmatched_interval_close,
|
|
1051
1606
|
},
|
|
1052
1607
|
]
|
|
1053
1608
|
: []),
|
|
1054
1609
|
{
|
|
1055
|
-
reason: "
|
|
1610
|
+
reason: "invalid_interval_character",
|
|
1611
|
+
outcome: "undefined_syntax",
|
|
1612
|
+
rule: ($) => $._regex_invalid_interval,
|
|
1613
|
+
},
|
|
1614
|
+
{
|
|
1615
|
+
reason: "unexpected_interval_separator",
|
|
1056
1616
|
outcome: "undefined_syntax",
|
|
1057
1617
|
rule: ($) =>
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
$._regex_invalid_interval,
|
|
1062
|
-
issueField($, "invalid_regular_expression_character"),
|
|
1063
|
-
issueField($, "invalid_encoding"),
|
|
1064
|
-
),
|
|
1065
|
-
),
|
|
1618
|
+
choice(
|
|
1619
|
+
alias($._regex_interval_separator, ","),
|
|
1620
|
+
alias($._regex_interval_escaped_separator, $.escaped_delimiter),
|
|
1066
1621
|
),
|
|
1067
1622
|
},
|
|
1623
|
+
{
|
|
1624
|
+
reason: "missing_interval_minimum",
|
|
1625
|
+
outcome: "undefined_syntax",
|
|
1626
|
+
rule: ($) => $._regex_missing_interval_minimum,
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
id: "incomplete_interval_minimum",
|
|
1630
|
+
reason: "missing_interval_minimum",
|
|
1631
|
+
outcome: "incomplete_syntax",
|
|
1632
|
+
rule: ($) => $._regex_incomplete_interval_minimum,
|
|
1633
|
+
},
|
|
1634
|
+
{
|
|
1635
|
+
reason: "missing_interval_close",
|
|
1636
|
+
outcome: "undefined_syntax",
|
|
1637
|
+
rule: ($) => $._regex_missing_interval_close,
|
|
1638
|
+
},
|
|
1639
|
+
...(mode === "bre"
|
|
1640
|
+
? [
|
|
1641
|
+
{
|
|
1642
|
+
reason: "invalid_interval_close",
|
|
1643
|
+
outcome: "undefined_syntax",
|
|
1644
|
+
rule: ($) => $._regex_invalid_interval_close,
|
|
1645
|
+
},
|
|
1646
|
+
{
|
|
1647
|
+
id: "incomplete_interval_close",
|
|
1648
|
+
reason: "invalid_interval_close",
|
|
1649
|
+
outcome: "incomplete_syntax",
|
|
1650
|
+
rule: ($) => $._regex_incomplete_interval_close,
|
|
1651
|
+
},
|
|
1652
|
+
]
|
|
1653
|
+
: []),
|
|
1068
1654
|
{
|
|
1069
1655
|
reason: "leading_duplication_symbol",
|
|
1070
1656
|
outcome: "undefined_syntax",
|
|
1071
1657
|
rule: ($) =>
|
|
1072
1658
|
seq(
|
|
1073
1659
|
$._regex_leading_duplication_marker,
|
|
1074
|
-
field(
|
|
1075
|
-
"operator",
|
|
1076
|
-
mode === "bre" ? $.bre_dupl_symbol : $.ere_dupl_symbol,
|
|
1077
|
-
),
|
|
1660
|
+
field("operator", $[regularExpressionRules[mode].duplication]),
|
|
1078
1661
|
),
|
|
1079
1662
|
},
|
|
1080
1663
|
{
|
|
@@ -1083,10 +1666,7 @@ function issueDefinitions(mode) {
|
|
|
1083
1666
|
rule: ($) =>
|
|
1084
1667
|
seq(
|
|
1085
1668
|
$._regex_adjacent_duplication_marker,
|
|
1086
|
-
field(
|
|
1087
|
-
"operator",
|
|
1088
|
-
mode === "bre" ? $.bre_dupl_symbol : $.ere_dupl_symbol,
|
|
1089
|
-
),
|
|
1669
|
+
field("operator", $[regularExpressionRules[mode].duplication]),
|
|
1090
1670
|
),
|
|
1091
1671
|
},
|
|
1092
1672
|
...(mode === "ere"
|
|
@@ -1114,7 +1694,7 @@ function issueDefinitions(mode) {
|
|
|
1114
1694
|
rule: ($) =>
|
|
1115
1695
|
choice(
|
|
1116
1696
|
$._translate_nonportable_escape,
|
|
1117
|
-
seq($._escape_prefix, issueField($, "
|
|
1697
|
+
seq($._escape_prefix, issueField($, "escaped_nul_character")),
|
|
1118
1698
|
),
|
|
1119
1699
|
},
|
|
1120
1700
|
{
|
|
@@ -1143,27 +1723,22 @@ function issueDefinitions(mode) {
|
|
|
1143
1723
|
rule: ($) =>
|
|
1144
1724
|
choice(
|
|
1145
1725
|
$._replacement_nonportable_escape,
|
|
1146
|
-
seq($._escape_prefix, issueField($, "
|
|
1726
|
+
seq($._escape_prefix, issueField($, "escaped_nul_character")),
|
|
1147
1727
|
),
|
|
1148
1728
|
},
|
|
1149
1729
|
{
|
|
1150
1730
|
reason: "special_delimiter_escape",
|
|
1151
1731
|
outcome: "unspecified_syntax",
|
|
1152
1732
|
rule: ($) =>
|
|
1153
|
-
|
|
1154
|
-
$,
|
|
1155
|
-
$._regex_special_escaped_delimiter,
|
|
1156
|
-
"escaped_delimiter",
|
|
1157
|
-
),
|
|
1733
|
+
alias($._regex_special_escaped_delimiter, $.escaped_delimiter),
|
|
1158
1734
|
},
|
|
1159
1735
|
{
|
|
1160
1736
|
reason: "replacement_ampersand_delimiter_escape",
|
|
1161
1737
|
outcome: "unspecified_syntax",
|
|
1162
1738
|
rule: ($) =>
|
|
1163
|
-
|
|
1164
|
-
$,
|
|
1739
|
+
alias(
|
|
1165
1740
|
$._replacement_ampersand_escaped_delimiter,
|
|
1166
|
-
|
|
1741
|
+
$.replacement_escaped_delimiter,
|
|
1167
1742
|
),
|
|
1168
1743
|
},
|
|
1169
1744
|
{
|
|
@@ -1172,7 +1747,7 @@ function issueDefinitions(mode) {
|
|
|
1172
1747
|
rule: ($) =>
|
|
1173
1748
|
choice(
|
|
1174
1749
|
$._text_unspecified_escape,
|
|
1175
|
-
seq($._escape_prefix, issueField($, "
|
|
1750
|
+
seq($._escape_prefix, issueField($, "escaped_nul_character")),
|
|
1176
1751
|
),
|
|
1177
1752
|
},
|
|
1178
1753
|
...(mode === "bre"
|
|
@@ -1180,29 +1755,17 @@ function issueDefinitions(mode) {
|
|
|
1180
1755
|
{
|
|
1181
1756
|
reason: "bre_vertical_line_escape",
|
|
1182
1757
|
outcome: "implementation_defined_syntax",
|
|
1183
|
-
rule: ($) =>
|
|
1184
|
-
field(
|
|
1185
|
-
"token",
|
|
1186
|
-
namedExternal($, $._regex_bre_vertical_line_escape, "back_bar"),
|
|
1187
|
-
),
|
|
1758
|
+
rule: ($) => $._regex_bre_vertical_line_escape,
|
|
1188
1759
|
},
|
|
1189
1760
|
{
|
|
1190
1761
|
reason: "bre_question_mark_escape",
|
|
1191
1762
|
outcome: "implementation_defined_syntax",
|
|
1192
|
-
rule: ($) =>
|
|
1193
|
-
field(
|
|
1194
|
-
"token",
|
|
1195
|
-
namedExternal($, $._regex_bre_question_mark_escape, "back_qm"),
|
|
1196
|
-
),
|
|
1763
|
+
rule: ($) => $._regex_bre_question_mark_escape,
|
|
1197
1764
|
},
|
|
1198
1765
|
{
|
|
1199
1766
|
reason: "bre_plus_escape",
|
|
1200
1767
|
outcome: "implementation_defined_syntax",
|
|
1201
|
-
rule: ($) =>
|
|
1202
|
-
field(
|
|
1203
|
-
"token",
|
|
1204
|
-
namedExternal($, $._regex_bre_plus_escape, "back_plus"),
|
|
1205
|
-
),
|
|
1768
|
+
rule: ($) => $._regex_bre_plus_escape,
|
|
1206
1769
|
},
|
|
1207
1770
|
{
|
|
1208
1771
|
reason: "bre_subexpression_left_anchor",
|
|
@@ -1221,6 +1784,12 @@ function issueDefinitions(mode) {
|
|
|
1221
1784
|
outcome: "nonconforming_syntax",
|
|
1222
1785
|
rule: missing("omitted_file_separator"),
|
|
1223
1786
|
},
|
|
1787
|
+
{
|
|
1788
|
+
id: "incomplete_omitted_file_separator",
|
|
1789
|
+
reason: "omitted_file_separator",
|
|
1790
|
+
outcome: "incomplete_syntax",
|
|
1791
|
+
rule: missing("incomplete_omitted_file_separator"),
|
|
1792
|
+
},
|
|
1224
1793
|
{
|
|
1225
1794
|
reason: "excess_address",
|
|
1226
1795
|
outcome: "nonconforming_syntax",
|
|
@@ -1245,8 +1814,7 @@ function issueDefinitions(mode) {
|
|
|
1245
1814
|
rule: ($) =>
|
|
1246
1815
|
choice(
|
|
1247
1816
|
token(prec(-2, unknownFunctionCharacter)),
|
|
1248
|
-
$.
|
|
1249
|
-
issueField($, "invalid_encoding"),
|
|
1817
|
+
$._single_nul_character,
|
|
1250
1818
|
),
|
|
1251
1819
|
},
|
|
1252
1820
|
{
|
|
@@ -1259,11 +1827,14 @@ function issueDefinitions(mode) {
|
|
|
1259
1827
|
reason: "unexpected_command_text",
|
|
1260
1828
|
outcome: "nonconforming_syntax",
|
|
1261
1829
|
rule: ($) =>
|
|
1262
|
-
|
|
1263
|
-
choice(
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1830
|
+
seq(
|
|
1831
|
+
choice($._unexpected_command_text, issueField($, "nul_character")),
|
|
1832
|
+
repeat(
|
|
1833
|
+
choice(
|
|
1834
|
+
$._unexpected_command_text,
|
|
1835
|
+
issueField($, "nul_character"),
|
|
1836
|
+
issueField($, "invalid_encoding"),
|
|
1837
|
+
),
|
|
1267
1838
|
),
|
|
1268
1839
|
),
|
|
1269
1840
|
},
|
|
@@ -1272,6 +1843,12 @@ function issueDefinitions(mode) {
|
|
|
1272
1843
|
outcome: "nonconforming_syntax",
|
|
1273
1844
|
rule: ($) => alias(token.immediate(";"), $.command_separator),
|
|
1274
1845
|
},
|
|
1846
|
+
{
|
|
1847
|
+
id: "incomplete_command_text",
|
|
1848
|
+
reason: "unexpected_command_text",
|
|
1849
|
+
outcome: "incomplete_syntax",
|
|
1850
|
+
rule: ($) => $._incomplete_command_text,
|
|
1851
|
+
},
|
|
1275
1852
|
{
|
|
1276
1853
|
reason: "blanks_around_address_separator",
|
|
1277
1854
|
outcome: "nonconforming_syntax",
|
|
@@ -1310,24 +1887,41 @@ function issueDefinitions(mode) {
|
|
|
1310
1887
|
rule: missing("missing_separator_after_unmatched_brace"),
|
|
1311
1888
|
},
|
|
1312
1889
|
{
|
|
1313
|
-
|
|
1314
|
-
|
|
1890
|
+
id: "undefined_write_command_separator",
|
|
1891
|
+
reason: "forbidden_command_separator",
|
|
1892
|
+
outcome: "undefined_syntax",
|
|
1893
|
+
rule: ($) => alias($._write_following_separator, $.command_separator),
|
|
1894
|
+
},
|
|
1895
|
+
{
|
|
1896
|
+
reason: "nonfinal_write_flag",
|
|
1897
|
+
outcome: "undefined_syntax",
|
|
1315
1898
|
rule: ($) =>
|
|
1316
|
-
|
|
1317
|
-
$.
|
|
1318
|
-
$.
|
|
1319
|
-
issueField($, "invalid_encoding"),
|
|
1899
|
+
seq(
|
|
1900
|
+
field("verb", alias("w", $.substitution_flag)),
|
|
1901
|
+
$._flag_after_write_marker,
|
|
1320
1902
|
),
|
|
1321
1903
|
},
|
|
1904
|
+
{
|
|
1905
|
+
id: "conflicting_global_flag",
|
|
1906
|
+
reason: "conflicting_substitution_flag",
|
|
1907
|
+
outcome: "unspecified_syntax",
|
|
1908
|
+
rule: ($) => alias("g", $.global_flag),
|
|
1909
|
+
},
|
|
1910
|
+
{
|
|
1911
|
+
id: "conflicting_occurrence_flag",
|
|
1912
|
+
reason: "conflicting_substitution_flag",
|
|
1913
|
+
outcome: "unspecified_syntax",
|
|
1914
|
+
rule: ($) => $.occurrence_flag,
|
|
1915
|
+
},
|
|
1916
|
+
{
|
|
1917
|
+
reason: "invalid_substitution_flag",
|
|
1918
|
+
outcome: "nonconforming_syntax",
|
|
1919
|
+
rule: ($) => $._invalid_substitution_flag,
|
|
1920
|
+
},
|
|
1322
1921
|
{
|
|
1323
1922
|
reason: "invalid_delimiter",
|
|
1324
1923
|
outcome: "nonconforming_syntax",
|
|
1325
|
-
rule: ($) =>
|
|
1326
|
-
choice(
|
|
1327
|
-
token(/\\/),
|
|
1328
|
-
$._nul_character,
|
|
1329
|
-
issueField($, "invalid_encoding"),
|
|
1330
|
-
),
|
|
1924
|
+
rule: ($) => choice(token(/\\/), $._single_nul_character),
|
|
1331
1925
|
},
|
|
1332
1926
|
{
|
|
1333
1927
|
reason: "unterminated_regular_expression",
|
|
@@ -1368,11 +1962,6 @@ function issueDefinitions(mode) {
|
|
|
1368
1962
|
outcome: "incomplete_syntax",
|
|
1369
1963
|
rule: rule ?? missing(reason),
|
|
1370
1964
|
})),
|
|
1371
|
-
{
|
|
1372
|
-
reason: "missing_subexpression",
|
|
1373
|
-
outcome: "incomplete_syntax",
|
|
1374
|
-
rule: missing("missing_subexpression"),
|
|
1375
|
-
},
|
|
1376
1965
|
{
|
|
1377
1966
|
id: "incomplete_unclosed_subexpression",
|
|
1378
1967
|
reason: "unclosed_subexpression",
|
|
@@ -1380,7 +1969,8 @@ function issueDefinitions(mode) {
|
|
|
1380
1969
|
rule: ($) => $._regex_incomplete_group,
|
|
1381
1970
|
},
|
|
1382
1971
|
{
|
|
1383
|
-
|
|
1972
|
+
id: "incomplete_bracket_term",
|
|
1973
|
+
reason: "missing_bracket_term_close",
|
|
1384
1974
|
outcome: "incomplete_syntax",
|
|
1385
1975
|
rule: ($) => $._regex_incomplete_bracket_term,
|
|
1386
1976
|
},
|
|
@@ -1399,14 +1989,16 @@ function issueDefinitions(mode) {
|
|
|
1399
1989
|
...(mode === "ere"
|
|
1400
1990
|
? [
|
|
1401
1991
|
{
|
|
1402
|
-
|
|
1992
|
+
id: "incomplete_alternative",
|
|
1993
|
+
reason: "empty_alternative",
|
|
1403
1994
|
outcome: "incomplete_syntax",
|
|
1404
1995
|
rule: ($) => $._incomplete_alternative_marker,
|
|
1405
1996
|
},
|
|
1406
1997
|
]
|
|
1407
1998
|
: []),
|
|
1408
1999
|
{
|
|
1409
|
-
|
|
2000
|
+
id: "incomplete_interval",
|
|
2001
|
+
reason: "missing_interval_close",
|
|
1410
2002
|
outcome: "incomplete_syntax",
|
|
1411
2003
|
rule: ($) => $._regex_incomplete_interval,
|
|
1412
2004
|
},
|
|
@@ -1417,7 +2009,8 @@ function issueDefinitions(mode) {
|
|
|
1417
2009
|
rule: ($) => $._incomplete_command_separator_marker,
|
|
1418
2010
|
},
|
|
1419
2011
|
{
|
|
1420
|
-
|
|
2012
|
+
id: "incomplete_regular_expression",
|
|
2013
|
+
reason: "unterminated_regular_expression",
|
|
1421
2014
|
outcome: "incomplete_syntax",
|
|
1422
2015
|
rule: ($) =>
|
|
1423
2016
|
choice($._regex_unterminated_address, $._regex_unterminated_substitute),
|
|
@@ -1428,7 +2021,8 @@ function issueDefinitions(mode) {
|
|
|
1428
2021
|
rule: ($) => $._regex_incomplete_escape,
|
|
1429
2022
|
},
|
|
1430
2023
|
{
|
|
1431
|
-
|
|
2024
|
+
id: "incomplete_replacement",
|
|
2025
|
+
reason: "unterminated_replacement",
|
|
1432
2026
|
outcome: "incomplete_syntax",
|
|
1433
2027
|
rule: ($) => $._replacement_unterminated,
|
|
1434
2028
|
},
|
|
@@ -1438,7 +2032,8 @@ function issueDefinitions(mode) {
|
|
|
1438
2032
|
rule: ($) => $._replacement_incomplete_escape,
|
|
1439
2033
|
},
|
|
1440
2034
|
{
|
|
1441
|
-
|
|
2035
|
+
id: "incomplete_translation",
|
|
2036
|
+
reason: "unterminated_translation",
|
|
1442
2037
|
outcome: "incomplete_syntax",
|
|
1443
2038
|
rule: ($) =>
|
|
1444
2039
|
choice(
|
|
@@ -1454,140 +2049,155 @@ function issueDefinitions(mode) {
|
|
|
1454
2049
|
];
|
|
1455
2050
|
}
|
|
1456
2051
|
|
|
1457
|
-
function externalTokens(
|
|
2052
|
+
export function externalTokens(mode) {
|
|
1458
2053
|
return [
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
2054
|
+
"regex_address_start",
|
|
2055
|
+
"escaped_regex_address_start",
|
|
2056
|
+
"regex_address_end",
|
|
2057
|
+
"substitute_start",
|
|
2058
|
+
"substitute_middle",
|
|
2059
|
+
"substitute_end",
|
|
2060
|
+
"translate_start",
|
|
2061
|
+
"translate_middle",
|
|
2062
|
+
"translate_end",
|
|
2063
|
+
"regex_literal",
|
|
2064
|
+
"invalid_character",
|
|
2065
|
+
"nul_character",
|
|
2066
|
+
"single_nul_character",
|
|
2067
|
+
"regex_beginning_anchor",
|
|
2068
|
+
"regex_end_anchor",
|
|
2069
|
+
"regex_period",
|
|
2070
|
+
"regex_quoted_escape",
|
|
2071
|
+
"escape_prefix",
|
|
2072
|
+
"regex_newline_escape",
|
|
2073
|
+
"regex_escaped_delimiter",
|
|
2074
|
+
"regex_special_escaped_delimiter",
|
|
2075
|
+
"regex_group_open",
|
|
2076
|
+
"regex_group_close",
|
|
2077
|
+
"regex_unclosed_group",
|
|
1482
2078
|
...(mode === "bre"
|
|
1483
2079
|
? [
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
2080
|
+
"regex_unmatched_group_close",
|
|
2081
|
+
"regex_bre_vertical_line_escape",
|
|
2082
|
+
"regex_bre_question_mark_escape",
|
|
2083
|
+
"regex_bre_plus_escape",
|
|
2084
|
+
"regex_bre_subexpression_caret",
|
|
2085
|
+
"regex_bre_subexpression_dollar",
|
|
2086
|
+
"regex_unmatched_interval_close",
|
|
1491
2087
|
]
|
|
1492
2088
|
: []),
|
|
1493
|
-
...(mode === "ere" ? [
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
2089
|
+
...(mode === "ere" ? ["regex_alternation_operator"] : []),
|
|
2090
|
+
"regex_leading_duplication_marker",
|
|
2091
|
+
"regex_adjacent_duplication_marker",
|
|
2092
|
+
"regex_zero_or_more",
|
|
1497
2093
|
...(mode === "ere"
|
|
1498
|
-
? [
|
|
1499
|
-
$._regex_one_or_more,
|
|
1500
|
-
$._regex_zero_or_one,
|
|
1501
|
-
$._regex_repetition_modifier,
|
|
1502
|
-
]
|
|
2094
|
+
? ["regex_one_or_more", "regex_zero_or_one", "regex_repetition_modifier"]
|
|
1503
2095
|
: []),
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
2096
|
+
"regex_interval_open",
|
|
2097
|
+
"regex_dup_count",
|
|
2098
|
+
"regex_interval_escaped_count",
|
|
2099
|
+
"regex_interval_escaped_separator",
|
|
2100
|
+
"regex_interval_separator",
|
|
2101
|
+
"regex_interval_close",
|
|
2102
|
+
...(mode === "bre" ? ["regex_backreference"] : []),
|
|
2103
|
+
"regex_invalid_interval",
|
|
2104
|
+
"regex_missing_interval_minimum",
|
|
2105
|
+
"regex_incomplete_interval_minimum",
|
|
2106
|
+
"regex_missing_interval_close",
|
|
2107
|
+
...(mode === "bre"
|
|
2108
|
+
? ["regex_invalid_interval_close", "regex_incomplete_interval_close"]
|
|
2109
|
+
: []),
|
|
2110
|
+
"regex_nonportable_escape",
|
|
2111
|
+
"regex_incomplete_escape",
|
|
2112
|
+
"regex_bracket_open",
|
|
2113
|
+
"regex_bracket_close",
|
|
2114
|
+
"regex_bracket_literal",
|
|
2115
|
+
"regex_bracket_negation",
|
|
2116
|
+
"regex_bracket_hyphen",
|
|
2117
|
+
"regex_bracket_range_end_hyphen",
|
|
2118
|
+
"regex_bracket_trailing_hyphen",
|
|
2119
|
+
"regex_open_colon",
|
|
2120
|
+
"regex_class_name",
|
|
2121
|
+
"regex_invalid_class_name",
|
|
2122
|
+
"regex_colon_close",
|
|
2123
|
+
"regex_open_dot",
|
|
2124
|
+
"regex_coll_elem_single",
|
|
2125
|
+
"regex_coll_elem_multi",
|
|
2126
|
+
"regex_meta_char",
|
|
2127
|
+
"regex_incomplete_meta_char",
|
|
2128
|
+
"regex_dot_close",
|
|
2129
|
+
"regex_open_equal",
|
|
2130
|
+
"regex_equal_close",
|
|
2131
|
+
"regex_missing_bracket_term_close",
|
|
2132
|
+
"regex_missing_bracket_term_payload",
|
|
2133
|
+
"regex_incomplete_bracket_term_payload",
|
|
2134
|
+
"regex_shared_range_endpoint",
|
|
2135
|
+
"ambiguous_bracket_expression_marker",
|
|
2136
|
+
"missing_bracket_list_marker",
|
|
2137
|
+
"unclosed_bracket_expression_marker",
|
|
2138
|
+
"nonportable_range_start_marker",
|
|
2139
|
+
"nonportable_range_end_marker",
|
|
2140
|
+
"regex_unterminated_address",
|
|
2141
|
+
"regex_unterminated_substitute",
|
|
2142
|
+
"replacement_literal",
|
|
2143
|
+
"replacement_match_reference",
|
|
2144
|
+
"replacement_backreference",
|
|
2145
|
+
"replacement_escaped_delimiter",
|
|
2146
|
+
"replacement_ampersand_escaped_delimiter",
|
|
2147
|
+
"replacement_escape_sequence",
|
|
2148
|
+
"replacement_nonportable_escape",
|
|
2149
|
+
"replacement_escaped_newline",
|
|
2150
|
+
"replacement_incomplete_escape",
|
|
2151
|
+
"replacement_unterminated",
|
|
2152
|
+
"translate_literal",
|
|
2153
|
+
"translate_escaped_delimiter",
|
|
2154
|
+
"translate_escape",
|
|
2155
|
+
"translate_nonportable_escape",
|
|
2156
|
+
"translate_incomplete_escape",
|
|
2157
|
+
"translate_unterminated_source",
|
|
2158
|
+
"translate_unterminated_destination",
|
|
2159
|
+
"invalid_substitution_flag",
|
|
2160
|
+
"flag_after_write_marker",
|
|
2161
|
+
"write_terminal_separator",
|
|
2162
|
+
"write_block_terminal_separator",
|
|
2163
|
+
"write_following_separator",
|
|
2164
|
+
"text_command_start",
|
|
2165
|
+
"text_incomplete_introducer",
|
|
2166
|
+
"text_literal",
|
|
2167
|
+
"text_backslash_escape",
|
|
2168
|
+
"text_escaped_newline",
|
|
2169
|
+
"text_unspecified_escape",
|
|
2170
|
+
"text_line_end",
|
|
2171
|
+
"text_eof",
|
|
2172
|
+
"default_output_suppression",
|
|
2173
|
+
"comment_text",
|
|
2174
|
+
"file_argument",
|
|
2175
|
+
"substitution_wfile_argument",
|
|
2176
|
+
"substitution_wfile_continuation",
|
|
2177
|
+
"line_word",
|
|
2178
|
+
"label_start",
|
|
2179
|
+
"long_label_start",
|
|
2180
|
+
"label_literal",
|
|
2181
|
+
"nonportable_label_character",
|
|
2182
|
+
"argument_separator",
|
|
2183
|
+
"brace_leading_blanks",
|
|
2184
|
+
"block_trailing_blanks",
|
|
2185
|
+
"empty_command_marker",
|
|
2186
|
+
"reserved_unknown_function_token",
|
|
2187
|
+
"regex_incomplete_group",
|
|
2188
|
+
"regex_incomplete_bracket_term",
|
|
2189
|
+
"regex_incomplete_interval",
|
|
2190
|
+
"regex_forbidden_newline_escape",
|
|
2191
|
+
"regex_line_unterminated_address",
|
|
2192
|
+
"regex_line_unterminated_substitute",
|
|
2193
|
+
"replacement_line_unterminated",
|
|
2194
|
+
"translate_line_unterminated_source",
|
|
2195
|
+
"translate_line_unterminated_destination",
|
|
2196
|
+
"blanks_around_address_separator",
|
|
2197
|
+
...missingMarkerNames(mode).map((name) => `${name}_marker`),
|
|
2198
|
+
"unexpected_command_text",
|
|
2199
|
+
"incomplete_command_text",
|
|
2200
|
+
"error_sentinel",
|
|
1591
2201
|
];
|
|
1592
2202
|
}
|
|
1593
2203
|
|
|
@@ -1596,10 +2206,10 @@ function defineGrammar(name, mode) {
|
|
|
1596
2206
|
throw new Error(`Unsupported regular-expression mode: ${mode}`);
|
|
1597
2207
|
}
|
|
1598
2208
|
|
|
1599
|
-
|
|
2209
|
+
const options = {
|
|
1600
2210
|
name,
|
|
1601
2211
|
|
|
1602
|
-
externals: ($) => externalTokens(
|
|
2212
|
+
externals: ($) => externalTokens(mode).map((name) => $[`_${name}`]),
|
|
1603
2213
|
|
|
1604
2214
|
extras: () => [],
|
|
1605
2215
|
|
|
@@ -1618,13 +2228,12 @@ function defineGrammar(name, mode) {
|
|
|
1618
2228
|
$._omitted_first_address_unit1_reason,
|
|
1619
2229
|
],
|
|
1620
2230
|
],
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
}
|
|
1627
|
-
});
|
|
2231
|
+
};
|
|
2232
|
+
const rules = sedRules(mode);
|
|
2233
|
+
const issues = defineIssueRules(issueDefinitions(mode));
|
|
2234
|
+
return mode === "bre"
|
|
2235
|
+
? grammar({ ...options, rules: { ...rules, ...breRules(), ...issues } })
|
|
2236
|
+
: grammar({ ...options, rules: { ...rules, ...ereRules(), ...issues } });
|
|
1628
2237
|
}
|
|
1629
2238
|
|
|
1630
2239
|
export default defineGrammar;
|