tree-sitter-sed 0.2.0 → 0.4.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/CMakeLists.txt +121 -0
- package/Makefile +145 -0
- package/README.md +6 -1
- package/bindings/c/tree-sitter-sed.pc.in +10 -0
- package/bindings/c/tree_sitter/tree-sitter-sed.h +17 -0
- package/common/dsl.js +23 -1
- package/common/grammar.js +264 -334
- package/common/regex.js +12 -23
- package/common/scanner.h +569 -592
- package/package.json +9 -5
- package/sed_ere/src/grammar.json +1264 -2013
- package/sed_ere/src/node-types.json +109 -32
- package/sed_ere/src/parser.c +37125 -36566
- package/src/grammar.json +1261 -2076
- package/src/node-types.json +131 -38
- package/src/parser.c +31231 -30740
- package/test/binding.test.c +9 -0
- package/tree-sitter.json +2 -2
package/common/grammar.js
CHANGED
|
@@ -1,72 +1,11 @@
|
|
|
1
1
|
const {
|
|
2
|
+
defineIssueRules,
|
|
2
3
|
issueField,
|
|
3
4
|
issueNode,
|
|
4
|
-
issueRuleName,
|
|
5
5
|
namedExternal,
|
|
6
6
|
} = require("./dsl");
|
|
7
7
|
const regularExpressionRules = require("./regex");
|
|
8
8
|
|
|
9
|
-
const outcomes = [
|
|
10
|
-
"undefined_syntax",
|
|
11
|
-
"unspecified_syntax",
|
|
12
|
-
"implementation_defined_syntax",
|
|
13
|
-
"implementation_option_syntax",
|
|
14
|
-
"nonconforming_syntax",
|
|
15
|
-
"incomplete_syntax",
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
function outcomeRuleName(id) {
|
|
19
|
-
return `_${id}_outcome`;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function reasonRuleName(id) {
|
|
23
|
-
return `_${id}_reason`;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function defineIssueRules(definitions) {
|
|
27
|
-
const activeOutcomes = outcomes.filter((outcome) =>
|
|
28
|
-
definitions.some((definition) => definition.outcome === outcome),
|
|
29
|
-
);
|
|
30
|
-
const rules = {
|
|
31
|
-
syntax_issue: ($) => choice(...activeOutcomes.map((outcome) => $[outcome])),
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
for (const outcome of activeOutcomes) {
|
|
35
|
-
rules[outcome] = ($) => {
|
|
36
|
-
const reasons = [
|
|
37
|
-
...new Set(
|
|
38
|
-
definitions
|
|
39
|
-
.filter((definition) => definition.outcome === outcome)
|
|
40
|
-
.map(({ reason }) => reason),
|
|
41
|
-
),
|
|
42
|
-
].map((reason) => $[reason]);
|
|
43
|
-
return reasons.length === 1 ? reasons[0] : choice(...reasons);
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
for (const reason of new Set(definitions.map(({ reason }) => reason))) {
|
|
48
|
-
rules[reason] = ($) => {
|
|
49
|
-
const variants = definitions
|
|
50
|
-
.filter((definition) => definition.reason === reason)
|
|
51
|
-
.map((definition) => {
|
|
52
|
-
const id = definition.id ?? reason;
|
|
53
|
-
return $[reasonRuleName(id)];
|
|
54
|
-
});
|
|
55
|
-
return variants.length === 1 ? variants[0] : choice(...variants);
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
for (const definition of definitions) {
|
|
60
|
-
const { outcome, reason, rule } = definition;
|
|
61
|
-
const id = definition.id ?? reason;
|
|
62
|
-
rules[reasonRuleName(id)] = rule;
|
|
63
|
-
rules[outcomeRuleName(id)] = ($) => alias($[reasonRuleName(id)], $[reason]);
|
|
64
|
-
rules[issueRuleName(id)] = ($) => alias($[outcomeRuleName(id)], $[outcome]);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return rules;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
9
|
function missingAtEndOrBoundary($, reason) {
|
|
71
10
|
return choice(
|
|
72
11
|
issueField($, reason),
|
|
@@ -207,6 +146,13 @@ const nonWriteSubstitutionFlagRules = [
|
|
|
207
146
|
"print_flag",
|
|
208
147
|
];
|
|
209
148
|
|
|
149
|
+
function postWriteSubstitutionFlagChoice($) {
|
|
150
|
+
return choice(
|
|
151
|
+
...nonWriteSubstitutionFlagRules.map((rule) => $[rule]),
|
|
152
|
+
alias("w", $.substitution_flag),
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
210
156
|
function delimiter($, name) {
|
|
211
157
|
return alias($[`_${name}_delimiter`], $.delimiter);
|
|
212
158
|
}
|
|
@@ -250,8 +196,6 @@ function commandListRules() {
|
|
|
250
196
|
return {
|
|
251
197
|
script: ($) => optional(alias($._script_command_list, $.command_list)),
|
|
252
198
|
|
|
253
|
-
command_list: ($) => $._command_list,
|
|
254
|
-
|
|
255
199
|
_script_command_list: ($) =>
|
|
256
200
|
choice($._initial_suppressing_comment_command_list, $._command_list),
|
|
257
201
|
|
|
@@ -438,6 +382,14 @@ function commandListRules() {
|
|
|
438
382
|
function addressRules(mode) {
|
|
439
383
|
const expression = mode === "bre" ? "basic_reg_exp" : "extended_reg_exp";
|
|
440
384
|
|
|
385
|
+
function addressChoice($) {
|
|
386
|
+
return choice(
|
|
387
|
+
$.line_number_address,
|
|
388
|
+
$.last_line_address,
|
|
389
|
+
$.context_address,
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
|
|
441
393
|
function contextAddress($, opening) {
|
|
442
394
|
return seq(
|
|
443
395
|
field("opening", opening),
|
|
@@ -452,84 +404,97 @@ function addressRules(mode) {
|
|
|
452
404
|
);
|
|
453
405
|
}
|
|
454
406
|
|
|
407
|
+
function commaSeparator($) {
|
|
408
|
+
return field(
|
|
409
|
+
"separator",
|
|
410
|
+
alias($._comma_address_separator, $.address_separator),
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
|
|
455
414
|
return {
|
|
456
415
|
address_clause: ($) =>
|
|
457
416
|
choice(
|
|
458
417
|
$._single_address_clause,
|
|
459
418
|
$._double_address_clause,
|
|
460
|
-
$.
|
|
419
|
+
$._max2_excess_address_clause,
|
|
461
420
|
),
|
|
462
421
|
|
|
463
422
|
_single_address_clause: ($) => field("first", $.address),
|
|
464
423
|
|
|
465
424
|
_double_address_clause: ($) =>
|
|
466
425
|
choice(
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
field(
|
|
472
|
-
"separator",
|
|
473
|
-
alias($._address_separator, $.address_separator),
|
|
474
|
-
),
|
|
475
|
-
field("second", $.address),
|
|
476
|
-
),
|
|
426
|
+
seq(
|
|
427
|
+
field("first", $.address),
|
|
428
|
+
field("separator", alias($._address_separator, $.address_separator)),
|
|
429
|
+
field("second", $.address),
|
|
477
430
|
),
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
issueField($, "omitted_first_address"),
|
|
488
|
-
),
|
|
489
|
-
seq(
|
|
490
|
-
field("first", $.address),
|
|
491
|
-
field(
|
|
492
|
-
"separator",
|
|
493
|
-
alias($._comma_address_separator, $.address_separator),
|
|
494
|
-
),
|
|
495
|
-
issueField($, "omitted_address"),
|
|
496
|
-
),
|
|
497
|
-
seq(
|
|
498
|
-
field(
|
|
499
|
-
"separator",
|
|
500
|
-
alias($._comma_address_separator, $.address_separator),
|
|
501
|
-
),
|
|
502
|
-
issueField($, "omitted_address"),
|
|
503
|
-
),
|
|
504
|
-
),
|
|
431
|
+
seq(
|
|
432
|
+
issueField($, "omitted_first_address"),
|
|
433
|
+
commaSeparator($),
|
|
434
|
+
field("second", $.address),
|
|
435
|
+
),
|
|
436
|
+
seq(
|
|
437
|
+
field("first", $.address),
|
|
438
|
+
commaSeparator($),
|
|
439
|
+
$._omitted_second_address_issue,
|
|
505
440
|
),
|
|
506
|
-
),
|
|
507
|
-
|
|
508
|
-
_address_clause_with_excess: ($) =>
|
|
509
|
-
prec(
|
|
510
|
-
2,
|
|
511
441
|
seq(
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
442
|
+
issueField($, "omitted_first_address"),
|
|
443
|
+
commaSeparator($),
|
|
444
|
+
$._omitted_second_address_issue,
|
|
515
445
|
),
|
|
516
446
|
),
|
|
517
447
|
|
|
518
|
-
|
|
448
|
+
_omitted_second_address_issue: ($) =>
|
|
519
449
|
choice(
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
450
|
+
issueField($, "omitted_address"),
|
|
451
|
+
issueField($, "incomplete_omitted_address"),
|
|
452
|
+
),
|
|
453
|
+
|
|
454
|
+
_max2_excess_address_clause: ($) =>
|
|
455
|
+
prec.dynamic(
|
|
456
|
+
1,
|
|
457
|
+
choice(
|
|
458
|
+
seq($._double_address_clause, $._max2_excess_address_tail),
|
|
459
|
+
seq($._max2_excess_address_clause, $._max2_excess_address_tail),
|
|
523
460
|
),
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
461
|
+
),
|
|
462
|
+
|
|
463
|
+
_max1_address_clause: ($) =>
|
|
464
|
+
choice($._single_address_clause, $._max1_excess_address_clause),
|
|
465
|
+
|
|
466
|
+
_max1_excess_address_clause: ($) =>
|
|
467
|
+
prec.dynamic(
|
|
468
|
+
1,
|
|
469
|
+
choice(
|
|
470
|
+
seq(field("first", $.address), $._max1_excess_address_tail),
|
|
471
|
+
seq(
|
|
472
|
+
issueField($, "omitted_first_address_unit1"),
|
|
473
|
+
$._max1_excess_address_tail,
|
|
528
474
|
),
|
|
529
|
-
|
|
475
|
+
seq($._max1_excess_address_clause, $._max1_excess_address_tail),
|
|
530
476
|
),
|
|
531
477
|
),
|
|
532
478
|
|
|
479
|
+
_max0_address_clause: ($) =>
|
|
480
|
+
prec.dynamic(
|
|
481
|
+
1,
|
|
482
|
+
choice(
|
|
483
|
+
issueField($, "excess_address"),
|
|
484
|
+
seq(
|
|
485
|
+
issueField($, "omitted_first_address_unit0"),
|
|
486
|
+
$._max0_excess_address_tail,
|
|
487
|
+
),
|
|
488
|
+
seq($._max0_address_clause, $._max0_excess_address_tail),
|
|
489
|
+
),
|
|
490
|
+
),
|
|
491
|
+
|
|
492
|
+
_max0_excess_address_tail: ($) => issueField($, "excess_address_unit0"),
|
|
493
|
+
|
|
494
|
+
_max1_excess_address_tail: ($) => issueField($, "excess_address_unit1"),
|
|
495
|
+
|
|
496
|
+
_max2_excess_address_tail: ($) => issueField($, "excess_address_unit2"),
|
|
497
|
+
|
|
533
498
|
_address_separator: ($) =>
|
|
534
499
|
choice(
|
|
535
500
|
$._comma_address_separator,
|
|
@@ -540,25 +505,23 @@ function addressRules(mode) {
|
|
|
540
505
|
),
|
|
541
506
|
|
|
542
507
|
_comma_address_separator: ($) =>
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
1,
|
|
546
|
-
seq(
|
|
547
|
-
issueField($, "blanks_around_address_separator"),
|
|
548
|
-
choice(
|
|
549
|
-
seq($._blanks, $._address_separator_token, optional($._blanks)),
|
|
550
|
-
seq($._address_separator_token, $._blanks),
|
|
551
|
-
),
|
|
552
|
-
),
|
|
553
|
-
),
|
|
508
|
+
seq(
|
|
509
|
+
optional(issueField($, "blanks_around_address_separator")),
|
|
554
510
|
$._address_separator_token,
|
|
511
|
+
optional(issueField($, "blanks_around_address_separator")),
|
|
555
512
|
),
|
|
556
513
|
|
|
557
514
|
_address_separator_token: ($) =>
|
|
558
515
|
field("token", alias(",", $.address_separator_token)),
|
|
559
516
|
|
|
560
|
-
address:
|
|
561
|
-
|
|
517
|
+
address: addressChoice,
|
|
518
|
+
|
|
519
|
+
// Keep maximum-specific GLR paths distinct until the function verb.
|
|
520
|
+
_max0_address: addressChoice,
|
|
521
|
+
|
|
522
|
+
_max1_address: addressChoice,
|
|
523
|
+
|
|
524
|
+
_max2_address: addressChoice,
|
|
562
525
|
|
|
563
526
|
line_number_address: () => /[[:digit:]]+/,
|
|
564
527
|
|
|
@@ -588,12 +551,6 @@ function operandRules(mode) {
|
|
|
588
551
|
}
|
|
589
552
|
|
|
590
553
|
return {
|
|
591
|
-
substitute_function: ($) =>
|
|
592
|
-
choice(
|
|
593
|
-
$._substitute_function_without_write,
|
|
594
|
-
$._substitute_function_with_write,
|
|
595
|
-
),
|
|
596
|
-
|
|
597
554
|
_substitute_function_without_write: ($) =>
|
|
598
555
|
choice(
|
|
599
556
|
seq(
|
|
@@ -702,12 +659,6 @@ function operandRules(mode) {
|
|
|
702
659
|
escaped_newline: ($) =>
|
|
703
660
|
namedExternal($, $._replacement_escaped_newline, "escaped_newline_token"),
|
|
704
661
|
|
|
705
|
-
substitution_flags: ($) =>
|
|
706
|
-
choice(
|
|
707
|
-
$._substitution_flags_without_write,
|
|
708
|
-
$._substitution_flags_with_write,
|
|
709
|
-
),
|
|
710
|
-
|
|
711
662
|
_substitution_flags_without_write: ($) =>
|
|
712
663
|
choice(
|
|
713
664
|
substitutionFlagChoice($),
|
|
@@ -731,6 +682,16 @@ function operandRules(mode) {
|
|
|
731
682
|
seq(
|
|
732
683
|
field("verb", alias("w", $.substitution_flag)),
|
|
733
684
|
choice(
|
|
685
|
+
seq(
|
|
686
|
+
$._flag_after_write_marker,
|
|
687
|
+
issueField($, "flag_after_write_flag"),
|
|
688
|
+
repeat(postWriteSubstitutionFlagChoice($)),
|
|
689
|
+
$._blanks,
|
|
690
|
+
choice(
|
|
691
|
+
field("wfile", alias($._substitution_wfile, $.wfile)),
|
|
692
|
+
missingAtEndOrBoundary($, "missing_wfile"),
|
|
693
|
+
),
|
|
694
|
+
),
|
|
734
695
|
seq($._blanks, field("wfile", alias($._substitution_wfile, $.wfile))),
|
|
735
696
|
seq($._blanks, missingAtEndOrBoundary($, "missing_wfile")),
|
|
736
697
|
seq(
|
|
@@ -799,8 +760,6 @@ function functionRules() {
|
|
|
799
760
|
);
|
|
800
761
|
|
|
801
762
|
const rules = {
|
|
802
|
-
function: ($) => choice(...functionDefinitions.map(({ rule }) => $[rule])),
|
|
803
|
-
|
|
804
763
|
text: ($) =>
|
|
805
764
|
seq(
|
|
806
765
|
repeat1(
|
|
@@ -847,77 +806,67 @@ function functionRules() {
|
|
|
847
806
|
),
|
|
848
807
|
};
|
|
849
808
|
|
|
850
|
-
|
|
851
|
-
|
|
809
|
+
function fileForm(form) {
|
|
810
|
+
const missingFileReason = `missing_${form}`;
|
|
811
|
+
return ($) => [
|
|
812
|
+
choice(
|
|
813
|
+
seq($._blanks, field(form, $[form])),
|
|
814
|
+
seq($._blanks, missingAtEndOrBoundary($, missingFileReason)),
|
|
815
|
+
seq(issueField($, "omitted_file_separator"), field(form, $[form])),
|
|
816
|
+
missingAtEndOrBoundary($, missingFileReason),
|
|
817
|
+
),
|
|
818
|
+
];
|
|
852
819
|
}
|
|
853
820
|
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
functionVerb($, spelling),
|
|
863
|
-
field("commands", alias($._block_commands, $.command_list)),
|
|
864
|
-
field("closing", $.closing_brace),
|
|
865
|
-
optional($._blanks),
|
|
866
|
-
);
|
|
867
|
-
} else if (form === "text") {
|
|
868
|
-
rules[rule] = ($) =>
|
|
869
|
-
seq(
|
|
870
|
-
functionVerb($, spelling),
|
|
871
|
-
choice(
|
|
872
|
-
seq(
|
|
873
|
-
field("introducer", $.text_introducer),
|
|
874
|
-
choice(
|
|
875
|
-
field("text", $.text),
|
|
876
|
-
seq(optional(issueField($, "missing_text")), $._text_end),
|
|
877
|
-
),
|
|
878
|
-
),
|
|
879
|
-
missingAtEndOrBoundary($, "missing_text_introducer"),
|
|
880
|
-
),
|
|
881
|
-
);
|
|
882
|
-
} else if (form === "optionalLabel") {
|
|
883
|
-
rules[rule] = ($) =>
|
|
884
|
-
seq(
|
|
885
|
-
functionVerb($, spelling),
|
|
886
|
-
optional(
|
|
887
|
-
prec.right(
|
|
888
|
-
seq(
|
|
889
|
-
field("separator", alias(" ", $.argument_separator)),
|
|
890
|
-
optional(field("label", $.label)),
|
|
891
|
-
),
|
|
892
|
-
),
|
|
893
|
-
),
|
|
894
|
-
);
|
|
895
|
-
} else if (form === "requiredLabel") {
|
|
896
|
-
rules[rule] = ($) =>
|
|
821
|
+
const formArguments = {
|
|
822
|
+
block: ($) => [
|
|
823
|
+
field("commands", alias($._block_commands, $.command_list)),
|
|
824
|
+
field("closing", $.closing_brace),
|
|
825
|
+
optional($._blanks),
|
|
826
|
+
],
|
|
827
|
+
text: ($) => [
|
|
828
|
+
choice(
|
|
897
829
|
seq(
|
|
898
|
-
|
|
830
|
+
field("introducer", $.text_introducer),
|
|
899
831
|
choice(
|
|
900
|
-
field("
|
|
901
|
-
|
|
832
|
+
field("text", $.text),
|
|
833
|
+
seq(optional(issueField($, "missing_text")), $._text_end),
|
|
902
834
|
),
|
|
903
|
-
)
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
seq(issueField($, "omitted_file_separator"), field(form, $[form])),
|
|
914
|
-
missingAtEndOrBoundary($, missingFileReason),
|
|
835
|
+
),
|
|
836
|
+
missingAtEndOrBoundary($, "missing_text_introducer"),
|
|
837
|
+
),
|
|
838
|
+
],
|
|
839
|
+
optionalLabel: ($) => [
|
|
840
|
+
optional(
|
|
841
|
+
prec.right(
|
|
842
|
+
seq(
|
|
843
|
+
field("separator", alias(" ", $.argument_separator)),
|
|
844
|
+
optional(field("label", $.label)),
|
|
915
845
|
),
|
|
916
|
-
)
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
846
|
+
),
|
|
847
|
+
),
|
|
848
|
+
],
|
|
849
|
+
requiredLabel: ($) => [
|
|
850
|
+
choice(
|
|
851
|
+
field("label", $.label),
|
|
852
|
+
missingAtEndOrBoundary($, "missing_label"),
|
|
853
|
+
),
|
|
854
|
+
],
|
|
855
|
+
rfile: fileForm("rfile"),
|
|
856
|
+
wfile: fileForm("wfile"),
|
|
857
|
+
comment: ($) => [optional(field("comment", $.comment))],
|
|
858
|
+
};
|
|
859
|
+
|
|
860
|
+
for (const { rule, spelling } of noArgumentDefinitions) {
|
|
861
|
+
rules[rule] = ($) => functionVerb($, spelling);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
for (const { form, rule, spelling } of functionDefinitions) {
|
|
865
|
+
const argumentParts = formArguments[form];
|
|
866
|
+
if (argumentParts === undefined) {
|
|
867
|
+
continue;
|
|
920
868
|
}
|
|
869
|
+
rules[rule] = ($) => seq(functionVerb($, spelling), ...argumentParts($));
|
|
921
870
|
}
|
|
922
871
|
|
|
923
872
|
return rules;
|
|
@@ -948,6 +897,33 @@ function editingCommandRules() {
|
|
|
948
897
|
return alias($[name], $.function);
|
|
949
898
|
}
|
|
950
899
|
|
|
900
|
+
function addressClauseForMaximum($, maximum) {
|
|
901
|
+
if (maximum === 0) {
|
|
902
|
+
return alias($._max0_address_clause, $.address_clause);
|
|
903
|
+
}
|
|
904
|
+
if (maximum === 1) {
|
|
905
|
+
return alias($._max1_address_clause, $.address_clause);
|
|
906
|
+
}
|
|
907
|
+
return $.address_clause;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
function addressedCommand($, addresses, selectedFunction) {
|
|
911
|
+
return seq(
|
|
912
|
+
optional($._blanks),
|
|
913
|
+
optional(seq(field("addresses", addresses), optional($._blanks))),
|
|
914
|
+
optional(field("negation", $.negation)),
|
|
915
|
+
field("function", selectedFunction),
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
function addressedFunction($, functionRule) {
|
|
920
|
+
return addressedCommand(
|
|
921
|
+
$,
|
|
922
|
+
$.address_clause,
|
|
923
|
+
alias(functionRule, $.function),
|
|
924
|
+
);
|
|
925
|
+
}
|
|
926
|
+
|
|
951
927
|
function addressedForms($, definitions, kind) {
|
|
952
928
|
const forms = [];
|
|
953
929
|
for (const maximum of [0, 1, 2]) {
|
|
@@ -955,98 +931,24 @@ function editingCommandRules() {
|
|
|
955
931
|
if (names.length === 0) {
|
|
956
932
|
continue;
|
|
957
933
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
const parts = [optional($._blanks)];
|
|
965
|
-
if (addresses !== null) {
|
|
966
|
-
const addressed = seq(
|
|
967
|
-
field("addresses", addresses),
|
|
968
|
-
optional($._blanks),
|
|
969
|
-
);
|
|
970
|
-
parts.push(optionalAddresses ? optional(addressed) : addressed);
|
|
971
|
-
}
|
|
972
|
-
parts.push(
|
|
973
|
-
optional(field("negation", $.negation)),
|
|
974
|
-
field("function", selectedFunction),
|
|
975
|
-
);
|
|
976
|
-
if (reportExcess) {
|
|
977
|
-
parts.push(issueField($, "excess_addresses"));
|
|
978
|
-
}
|
|
979
|
-
return seq(...parts);
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
if (maximum === 2) {
|
|
983
|
-
forms.push(
|
|
984
|
-
addressedForm($.address_clause, { optionalAddresses: true }),
|
|
985
|
-
);
|
|
986
|
-
continue;
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
const excessAddressForm = addressedForm(
|
|
990
|
-
alias($._address_clause_with_excess, $.address_clause),
|
|
991
|
-
{ reportExcess: true },
|
|
934
|
+
forms.push(
|
|
935
|
+
addressedCommand(
|
|
936
|
+
$,
|
|
937
|
+
addressClauseForMaximum($, maximum),
|
|
938
|
+
functionWrapper($, wrapperName(kind, maximum)),
|
|
939
|
+
),
|
|
992
940
|
);
|
|
993
|
-
|
|
994
|
-
if (maximum === 0) {
|
|
995
|
-
forms.push(
|
|
996
|
-
choice(
|
|
997
|
-
addressedForm(null),
|
|
998
|
-
addressedForm(
|
|
999
|
-
alias(
|
|
1000
|
-
choice($._single_address_clause, $._double_address_clause),
|
|
1001
|
-
$.address_clause,
|
|
1002
|
-
),
|
|
1003
|
-
{ reportExcess: true },
|
|
1004
|
-
),
|
|
1005
|
-
excessAddressForm,
|
|
1006
|
-
),
|
|
1007
|
-
);
|
|
1008
|
-
} else {
|
|
1009
|
-
forms.push(
|
|
1010
|
-
choice(
|
|
1011
|
-
addressedForm(alias($._single_address_clause, $.address_clause), {
|
|
1012
|
-
optionalAddresses: true,
|
|
1013
|
-
}),
|
|
1014
|
-
addressedForm(alias($._double_address_clause, $.address_clause), {
|
|
1015
|
-
reportExcess: true,
|
|
1016
|
-
}),
|
|
1017
|
-
excessAddressForm,
|
|
1018
|
-
),
|
|
1019
|
-
);
|
|
1020
|
-
}
|
|
1021
941
|
}
|
|
1022
942
|
|
|
1023
943
|
return choice(...forms);
|
|
1024
944
|
}
|
|
1025
945
|
|
|
1026
946
|
const rules = {
|
|
1027
|
-
editing_command: ($) =>
|
|
1028
|
-
choice(
|
|
1029
|
-
$._chainable_editing_command,
|
|
1030
|
-
$._line_terminated_editing_command,
|
|
1031
|
-
$._recovered_line_terminated_editing_command,
|
|
1032
|
-
$._recovered_editing_command,
|
|
1033
|
-
),
|
|
1034
|
-
|
|
1035
947
|
_chainable_editing_command: ($) =>
|
|
1036
948
|
seq(
|
|
1037
949
|
choice(
|
|
1038
950
|
addressedForms($, chainable, "chainable"),
|
|
1039
|
-
|
|
1040
|
-
optional($._blanks),
|
|
1041
|
-
optional(
|
|
1042
|
-
seq(field("addresses", $.address_clause), optional($._blanks)),
|
|
1043
|
-
),
|
|
1044
|
-
optional(field("negation", $.negation)),
|
|
1045
|
-
field(
|
|
1046
|
-
"function",
|
|
1047
|
-
alias($._chainable_substitute_function, $.function),
|
|
1048
|
-
),
|
|
1049
|
-
),
|
|
951
|
+
addressedFunction($, $._chainable_substitute_function),
|
|
1050
952
|
),
|
|
1051
953
|
optional(issueField($, "unexpected_command_text")),
|
|
1052
954
|
),
|
|
@@ -1084,28 +986,11 @@ function editingCommandRules() {
|
|
|
1084
986
|
addressedForms($, lineTerminated, "line_terminated"),
|
|
1085
987
|
|
|
1086
988
|
_line_terminated_substitute_editing_command_body: ($) =>
|
|
1087
|
-
|
|
1088
|
-
optional($._blanks),
|
|
1089
|
-
optional(
|
|
1090
|
-
seq(field("addresses", $.address_clause), optional($._blanks)),
|
|
1091
|
-
),
|
|
1092
|
-
optional(field("negation", $.negation)),
|
|
1093
|
-
field(
|
|
1094
|
-
"function",
|
|
1095
|
-
alias($._line_terminated_substitute_function, $.function),
|
|
1096
|
-
),
|
|
1097
|
-
),
|
|
989
|
+
addressedFunction($, $._line_terminated_substitute_function),
|
|
1098
990
|
|
|
1099
991
|
_recovered_editing_command: ($) =>
|
|
1100
992
|
choice(
|
|
1101
|
-
|
|
1102
|
-
optional($._blanks),
|
|
1103
|
-
optional(
|
|
1104
|
-
seq(field("addresses", $.address_clause), optional($._blanks)),
|
|
1105
|
-
),
|
|
1106
|
-
optional(field("negation", $.negation)),
|
|
1107
|
-
field("function", alias($._unknown_function, $.function)),
|
|
1108
|
-
),
|
|
993
|
+
addressedFunction($, $._unknown_function),
|
|
1109
994
|
seq(
|
|
1110
995
|
optional($._blanks),
|
|
1111
996
|
optional(
|
|
@@ -1160,7 +1045,6 @@ function editingCommandRules() {
|
|
|
1160
1045
|
repeat(
|
|
1161
1046
|
seq(
|
|
1162
1047
|
optional(issueField($, "blanks_after_negation")),
|
|
1163
|
-
field("operator", alias("!", $.negation_operator)),
|
|
1164
1048
|
issueField($, "duplicate_negation"),
|
|
1165
1049
|
),
|
|
1166
1050
|
),
|
|
@@ -1197,12 +1081,11 @@ function sedRules(mode) {
|
|
|
1197
1081
|
function missingMarkerNames(mode) {
|
|
1198
1082
|
return [
|
|
1199
1083
|
"omitted_address",
|
|
1084
|
+
"incomplete_omitted_address",
|
|
1200
1085
|
"omitted_first_address",
|
|
1201
1086
|
"empty_subexpression",
|
|
1202
1087
|
"missing_subexpression",
|
|
1203
1088
|
...(mode === "ere" ? ["empty_alternative"] : []),
|
|
1204
|
-
"excess_addresses",
|
|
1205
|
-
"additional_address",
|
|
1206
1089
|
"missing_function",
|
|
1207
1090
|
"missing_label",
|
|
1208
1091
|
"missing_rfile",
|
|
@@ -1211,9 +1094,7 @@ function missingMarkerNames(mode) {
|
|
|
1211
1094
|
"missing_text_introducer",
|
|
1212
1095
|
"missing_text",
|
|
1213
1096
|
"missing_command_separator",
|
|
1214
|
-
"blanks_around_address_separator",
|
|
1215
1097
|
"missing_address_separator",
|
|
1216
|
-
"duplicate_negation",
|
|
1217
1098
|
"missing_closing_brace",
|
|
1218
1099
|
"missing_opening_delimiter",
|
|
1219
1100
|
"missing_separator_before_unmatched_brace",
|
|
@@ -1272,12 +1153,25 @@ function issueDefinitions(mode) {
|
|
|
1272
1153
|
outcome: "undefined_syntax",
|
|
1273
1154
|
rule: missing("omitted_address"),
|
|
1274
1155
|
},
|
|
1156
|
+
{
|
|
1157
|
+
id: "incomplete_omitted_address",
|
|
1158
|
+
reason: "omitted_address",
|
|
1159
|
+
outcome: "incomplete_syntax",
|
|
1160
|
+
rule: missing("incomplete_omitted_address"),
|
|
1161
|
+
},
|
|
1275
1162
|
{
|
|
1276
1163
|
id: "omitted_first_address",
|
|
1277
1164
|
reason: "omitted_address",
|
|
1278
1165
|
outcome: "undefined_syntax",
|
|
1279
1166
|
rule: missing("omitted_first_address"),
|
|
1280
1167
|
},
|
|
1168
|
+
// The marker is shared, but maximum-specific reductions must not merge.
|
|
1169
|
+
...[0, 1].map((maximum) => ({
|
|
1170
|
+
id: `omitted_first_address_unit${maximum}`,
|
|
1171
|
+
reason: "omitted_address",
|
|
1172
|
+
outcome: "undefined_syntax",
|
|
1173
|
+
rule: missing("omitted_first_address"),
|
|
1174
|
+
})),
|
|
1281
1175
|
{
|
|
1282
1176
|
reason: "ordinary_character_escape",
|
|
1283
1177
|
outcome: "undefined_syntax",
|
|
@@ -1298,12 +1192,22 @@ function issueDefinitions(mode) {
|
|
|
1298
1192
|
{
|
|
1299
1193
|
reason: "unmatched_subexpression_close",
|
|
1300
1194
|
outcome: "undefined_syntax",
|
|
1301
|
-
rule: ($) =>
|
|
1195
|
+
rule: ($) =>
|
|
1196
|
+
namedExternal(
|
|
1197
|
+
$,
|
|
1198
|
+
$._regex_unmatched_group_close,
|
|
1199
|
+
"back_close_parenthesis_token",
|
|
1200
|
+
),
|
|
1302
1201
|
},
|
|
1303
1202
|
{
|
|
1304
1203
|
reason: "unmatched_interval_close",
|
|
1305
1204
|
outcome: "undefined_syntax",
|
|
1306
|
-
rule: ($) =>
|
|
1205
|
+
rule: ($) =>
|
|
1206
|
+
namedExternal(
|
|
1207
|
+
$,
|
|
1208
|
+
$._regex_unmatched_interval_close,
|
|
1209
|
+
"back_close_brace",
|
|
1210
|
+
),
|
|
1307
1211
|
},
|
|
1308
1212
|
]
|
|
1309
1213
|
: []),
|
|
@@ -1351,6 +1255,11 @@ function issueDefinitions(mode) {
|
|
|
1351
1255
|
outcome: "undefined_syntax",
|
|
1352
1256
|
rule: () => token.immediate(";"),
|
|
1353
1257
|
},
|
|
1258
|
+
{
|
|
1259
|
+
reason: "flag_after_write_flag",
|
|
1260
|
+
outcome: "undefined_syntax",
|
|
1261
|
+
rule: ($) => postWriteSubstitutionFlagChoice($),
|
|
1262
|
+
},
|
|
1354
1263
|
{
|
|
1355
1264
|
reason: "equivalence_class_range_start",
|
|
1356
1265
|
outcome: "unspecified_syntax",
|
|
@@ -1369,7 +1278,7 @@ function issueDefinitions(mode) {
|
|
|
1369
1278
|
{
|
|
1370
1279
|
reason: "blanks_after_negation",
|
|
1371
1280
|
outcome: "unspecified_syntax",
|
|
1372
|
-
rule: () => token.immediate(/[[:blank:]]+/),
|
|
1281
|
+
rule: ($) => alias(token.immediate(/[[:blank:]]+/), $.blank),
|
|
1373
1282
|
},
|
|
1374
1283
|
{
|
|
1375
1284
|
reason: "unspecified_replacement_escape",
|
|
@@ -1426,15 +1335,32 @@ function issueDefinitions(mode) {
|
|
|
1426
1335
|
rule: missing("omitted_file_separator"),
|
|
1427
1336
|
},
|
|
1428
1337
|
{
|
|
1429
|
-
reason: "
|
|
1338
|
+
reason: "excess_address",
|
|
1430
1339
|
outcome: "nonconforming_syntax",
|
|
1431
|
-
rule:
|
|
1340
|
+
rule: ($) => field("address", alias($._max0_address, $.address)),
|
|
1432
1341
|
},
|
|
1433
|
-
{
|
|
1434
|
-
|
|
1342
|
+
...[0, 1, 2].map((maximum) => ({
|
|
1343
|
+
id: `excess_address_unit${maximum}`,
|
|
1344
|
+
reason: "excess_address",
|
|
1435
1345
|
outcome: "nonconforming_syntax",
|
|
1436
|
-
rule:
|
|
1437
|
-
|
|
1346
|
+
rule: ($) =>
|
|
1347
|
+
choice(
|
|
1348
|
+
seq(
|
|
1349
|
+
field(
|
|
1350
|
+
"separator",
|
|
1351
|
+
alias($._address_separator, $.address_separator),
|
|
1352
|
+
),
|
|
1353
|
+
field("address", alias($[`_max${maximum}_address`], $.address)),
|
|
1354
|
+
),
|
|
1355
|
+
seq(
|
|
1356
|
+
field(
|
|
1357
|
+
"separator",
|
|
1358
|
+
alias($._comma_address_separator, $.address_separator),
|
|
1359
|
+
),
|
|
1360
|
+
$._omitted_second_address_issue,
|
|
1361
|
+
),
|
|
1362
|
+
),
|
|
1363
|
+
})),
|
|
1438
1364
|
{
|
|
1439
1365
|
reason: "unknown_function",
|
|
1440
1366
|
outcome: "nonconforming_syntax",
|
|
@@ -1463,7 +1389,7 @@ function issueDefinitions(mode) {
|
|
|
1463
1389
|
{
|
|
1464
1390
|
reason: "blanks_around_address_separator",
|
|
1465
1391
|
outcome: "nonconforming_syntax",
|
|
1466
|
-
rule:
|
|
1392
|
+
rule: ($) => alias($._blanks_around_address_separator, $.blank),
|
|
1467
1393
|
},
|
|
1468
1394
|
{
|
|
1469
1395
|
reason: "missing_address_separator",
|
|
@@ -1473,7 +1399,7 @@ function issueDefinitions(mode) {
|
|
|
1473
1399
|
{
|
|
1474
1400
|
reason: "duplicate_negation",
|
|
1475
1401
|
outcome: "nonconforming_syntax",
|
|
1476
|
-
rule:
|
|
1402
|
+
rule: ($) => field("operator", alias("!", $.negation_operator)),
|
|
1477
1403
|
},
|
|
1478
1404
|
{
|
|
1479
1405
|
reason: "unmatched_closing_brace",
|
|
@@ -1701,7 +1627,6 @@ function externalTokens($, mode) {
|
|
|
1701
1627
|
$._bre_question_mark_escape_marker,
|
|
1702
1628
|
$._bre_plus_escape_marker,
|
|
1703
1629
|
$._regex_unmatched_interval_close,
|
|
1704
|
-
$._unmatched_interval_close_marker,
|
|
1705
1630
|
]
|
|
1706
1631
|
: []),
|
|
1707
1632
|
...(mode === "ere" ? [$._regex_alternation_operator] : []),
|
|
@@ -1767,6 +1692,7 @@ function externalTokens($, mode) {
|
|
|
1767
1692
|
$._translate_unterminated_source,
|
|
1768
1693
|
$._translate_unterminated_destination,
|
|
1769
1694
|
$._invalid_substitution_flag,
|
|
1695
|
+
$._flag_after_write_marker,
|
|
1770
1696
|
$._text_command_start,
|
|
1771
1697
|
$._text_literal,
|
|
1772
1698
|
$._text_backslash_escape,
|
|
@@ -1790,6 +1716,7 @@ function externalTokens($, mode) {
|
|
|
1790
1716
|
$._replacement_line_unterminated,
|
|
1791
1717
|
$._translate_line_unterminated_source,
|
|
1792
1718
|
$._translate_line_unterminated_destination,
|
|
1719
|
+
$._blanks_around_address_separator,
|
|
1793
1720
|
...missingMarkerNames(mode).map((name) => $[`_${name}_marker`]),
|
|
1794
1721
|
$._error_sentinel,
|
|
1795
1722
|
];
|
|
@@ -1808,16 +1735,19 @@ function defineGrammar(name, mode) {
|
|
|
1808
1735
|
extras: () => [],
|
|
1809
1736
|
|
|
1810
1737
|
conflicts: ($) => [
|
|
1738
|
+
[$.address_clause, $._recovered_editing_command],
|
|
1739
|
+
[$.address_clause, $._max1_address_clause],
|
|
1740
|
+
[$._double_address_clause, $._excess_address_unit1_reason],
|
|
1741
|
+
[$.address, $._max0_address],
|
|
1742
|
+
[$.address, $._max1_address],
|
|
1811
1743
|
[
|
|
1812
|
-
$.
|
|
1813
|
-
$.
|
|
1814
|
-
$.
|
|
1744
|
+
$._omitted_first_address_reason,
|
|
1745
|
+
$._omitted_first_address_unit0_reason,
|
|
1746
|
+
$._omitted_first_address_unit1_reason,
|
|
1815
1747
|
],
|
|
1816
1748
|
[
|
|
1817
|
-
$.
|
|
1818
|
-
$.
|
|
1819
|
-
$._line_terminated_regular_editing_command_body,
|
|
1820
|
-
$._recovered_editing_command,
|
|
1749
|
+
$._omitted_first_address_unit0_reason,
|
|
1750
|
+
$._omitted_first_address_unit1_reason,
|
|
1821
1751
|
],
|
|
1822
1752
|
],
|
|
1823
1753
|
|