clarity-pattern-parser 8.4.15 → 9.0.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/TODO.md +4 -1
- package/dist/grammar/Grammar.d.ts +18 -10
- package/dist/grammar/patterns/andLiteral.d.ts +2 -0
- package/dist/grammar/patterns/anonymousPattern.d.ts +2 -0
- package/dist/grammar/patterns/inlinePattern.d.ts +1 -0
- package/dist/grammar/patterns/literals.d.ts +3 -0
- package/dist/grammar/patterns/pattern.d.ts +2 -2
- package/dist/grammar/patterns.d.ts +2 -0
- package/dist/index.browser.js +471 -184
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.esm.js +470 -185
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +471 -184
- package/dist/index.js.map +1 -1
- package/dist/patterns/And.d.ts +4 -1
- package/dist/patterns/Cursor.d.ts +5 -0
- package/dist/patterns/CursorHistory.d.ts +7 -0
- package/dist/patterns/FiniteRepeat.d.ts +4 -1
- package/dist/patterns/InfiniteRepeat.d.ts +5 -4
- package/dist/patterns/Literal.d.ts +6 -5
- package/dist/patterns/Not.d.ts +5 -4
- package/dist/patterns/Or.d.ts +5 -4
- package/dist/patterns/Pattern.d.ts +4 -2
- package/dist/patterns/Reference.d.ts +5 -4
- package/dist/patterns/Regex.d.ts +5 -4
- package/dist/patterns/Repeat.d.ts +3 -0
- package/dist/patterns/arePatternsEqual.d.ts +2 -0
- package/package.json +1 -1
- package/src/grammar/Grammar.test.ts +117 -74
- package/src/grammar/Grammar.ts +241 -158
- package/src/grammar/patterns/anonymousPattern.ts +23 -0
- package/src/grammar/patterns/body.ts +9 -6
- package/src/grammar/patterns/comment.ts +3 -2
- package/src/grammar/patterns/grammar.ts +15 -12
- package/src/grammar/patterns/import.ts +18 -12
- package/src/grammar/patterns/literal.ts +2 -1
- package/src/grammar/patterns/literals.ts +20 -0
- package/src/grammar/patterns/optionsLiteral.ts +19 -0
- package/src/grammar/patterns/pattern.ts +23 -9
- package/src/grammar/patterns/regexLiteral.ts +1 -0
- package/src/grammar/patterns/repeatLiteral.ts +30 -25
- package/src/grammar/patterns/sequenceLiteral.ts +24 -0
- package/src/grammar/patterns/spaces.ts +8 -6
- package/src/grammar/patterns/statement.ts +8 -20
- package/src/grammar/patterns.test.ts +38 -0
- package/src/grammar/patterns.ts +24 -0
- package/src/grammar/spec.md +4 -12
- package/src/index.ts +11 -5
- package/src/intellisense/AutoComplete.test.ts +41 -40
- package/src/intellisense/css/method.ts +2 -2
- package/src/intellisense/css/unit.ts +2 -2
- package/src/intellisense/css/value.ts +1 -1
- package/src/intellisense/javascript/Javascript.test.ts +31 -32
- package/src/intellisense/javascript/arrayLiteral.ts +7 -6
- package/src/intellisense/javascript/assignment.ts +6 -6
- package/src/intellisense/javascript/deleteStatement.ts +2 -2
- package/src/intellisense/javascript/escapedCharacter.ts +6 -6
- package/src/intellisense/javascript/exponent.ts +6 -6
- package/src/intellisense/javascript/expression.ts +18 -17
- package/src/intellisense/javascript/fraction.ts +3 -3
- package/src/intellisense/javascript/infixOperator.ts +10 -10
- package/src/intellisense/javascript/integer.ts +1 -1
- package/src/intellisense/javascript/invocation.ts +8 -7
- package/src/intellisense/javascript/literal.ts +3 -3
- package/src/intellisense/javascript/numberLiteral.ts +5 -4
- package/src/intellisense/javascript/objectAccess.ts +2 -3
- package/src/intellisense/javascript/objectLiteral.ts +8 -7
- package/src/intellisense/javascript/optionalSpaces.ts +2 -1
- package/src/intellisense/javascript/parameters.ts +5 -5
- package/src/intellisense/javascript/prefixOperator.ts +3 -4
- package/src/intellisense/javascript/propertyAccess.ts +9 -8
- package/src/intellisense/javascript/stringLiteral.ts +14 -15
- package/src/patterns/Cursor.ts +42 -4
- package/src/patterns/CursorHistory.ts +20 -4
- package/src/patterns/FiniteRepeat.test.ts +52 -51
- package/src/patterns/FiniteRepeat.ts +60 -38
- package/src/patterns/InfiniteRepeat.test.ts +36 -49
- package/src/patterns/InfiniteRepeat.ts +70 -37
- package/src/patterns/Literal.test.ts +16 -27
- package/src/patterns/Literal.ts +34 -27
- package/src/patterns/Not.test.ts +7 -7
- package/src/patterns/Not.ts +24 -6
- package/src/patterns/Optional.test.ts +164 -0
- package/src/patterns/Optional.ts +143 -0
- package/src/patterns/{Or.test.ts → Options.test.ts} +51 -49
- package/src/patterns/{Or.ts → Options.ts} +32 -23
- package/src/patterns/Pattern.ts +6 -5
- package/src/patterns/Reference.test.ts +21 -22
- package/src/patterns/Reference.ts +26 -15
- package/src/patterns/Regex.test.ts +15 -15
- package/src/patterns/Regex.ts +29 -19
- package/src/patterns/Repeat.test.ts +12 -22
- package/src/patterns/Repeat.ts +22 -21
- package/src/patterns/{And.test.ts → Sequence.test.ts} +78 -78
- package/src/patterns/{And.ts → Sequence.ts} +40 -29
- package/src/patterns/arePatternsEqual.ts +12 -0
- package/src/patterns/clonePatterns.ts +2 -2
- package/src/grammar/patterns/andLiteral.ts +0 -8
- package/src/grammar/patterns/orLiteral.ts +0 -8
package/dist/index.esm.js
CHANGED
|
@@ -243,6 +243,7 @@ class CursorHistory {
|
|
|
243
243
|
this._patterns = [];
|
|
244
244
|
this._nodes = [];
|
|
245
245
|
this._errors = [];
|
|
246
|
+
this._trace = [];
|
|
246
247
|
}
|
|
247
248
|
get isRecording() {
|
|
248
249
|
return this._isRecording;
|
|
@@ -271,6 +272,9 @@ class CursorHistory {
|
|
|
271
272
|
get patterns() {
|
|
272
273
|
return this._patterns;
|
|
273
274
|
}
|
|
275
|
+
get trace() {
|
|
276
|
+
return this._trace;
|
|
277
|
+
}
|
|
274
278
|
recordMatch(pattern, node) {
|
|
275
279
|
if (this._isRecording) {
|
|
276
280
|
this._patterns.push(pattern);
|
|
@@ -325,6 +329,11 @@ class CursorHistory {
|
|
|
325
329
|
resolveError() {
|
|
326
330
|
this._currentError = null;
|
|
327
331
|
}
|
|
332
|
+
pushStackTrace(trace) {
|
|
333
|
+
if (this._isRecording) {
|
|
334
|
+
this._trace.push(trace);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
328
337
|
}
|
|
329
338
|
|
|
330
339
|
class Cursor {
|
|
@@ -381,6 +390,7 @@ class Cursor {
|
|
|
381
390
|
this._index = 0;
|
|
382
391
|
this._length = text.length;
|
|
383
392
|
this._history = new CursorHistory();
|
|
393
|
+
this._stackTrace = [];
|
|
384
394
|
}
|
|
385
395
|
hasNext() {
|
|
386
396
|
return this._index + 1 < this._length;
|
|
@@ -430,9 +440,42 @@ class Cursor {
|
|
|
430
440
|
stopRecording() {
|
|
431
441
|
this._history.stopRecording();
|
|
432
442
|
}
|
|
443
|
+
startParseWith(pattern) {
|
|
444
|
+
const patternName = pattern.name;
|
|
445
|
+
const trace = {
|
|
446
|
+
pattern,
|
|
447
|
+
cursorIndex: this.index
|
|
448
|
+
};
|
|
449
|
+
if (this._stackTrace.find(t => t.pattern.id === pattern.id && this.index === t.cursorIndex)) {
|
|
450
|
+
throw new Error(`Cyclical Pattern: ${this._stackTrace.map(t => `${t.pattern.name}#${t.pattern.id}{${t.cursorIndex}}`).join(" -> ")} -> ${patternName}#${pattern.id}{${this.index}}.`);
|
|
451
|
+
}
|
|
452
|
+
this._history.pushStackTrace(trace);
|
|
453
|
+
this._stackTrace.push(trace);
|
|
454
|
+
}
|
|
455
|
+
endParse() {
|
|
456
|
+
this._stackTrace.pop();
|
|
457
|
+
}
|
|
458
|
+
audit() {
|
|
459
|
+
return this._history.trace.map(t => {
|
|
460
|
+
const onChar = this.getChars(t.cursorIndex, t.cursorIndex);
|
|
461
|
+
const restChars = this.getChars(t.cursorIndex + 1, t.cursorIndex + 5);
|
|
462
|
+
const context = `{${t.cursorIndex}}[${onChar}]${restChars}`;
|
|
463
|
+
return `${this._buildPatternContext(t.pattern)}-->${context}`;
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
_buildPatternContext(pattern) {
|
|
467
|
+
if (pattern.parent != null) {
|
|
468
|
+
return `${pattern.parent.name}.${pattern.name}`;
|
|
469
|
+
}
|
|
470
|
+
return pattern.name;
|
|
471
|
+
}
|
|
433
472
|
}
|
|
434
473
|
|
|
474
|
+
let idIndex$8 = 0;
|
|
435
475
|
class Literal {
|
|
476
|
+
get id() {
|
|
477
|
+
return this._id;
|
|
478
|
+
}
|
|
436
479
|
get type() {
|
|
437
480
|
return this._type;
|
|
438
481
|
}
|
|
@@ -455,9 +498,10 @@ class Literal {
|
|
|
455
498
|
if (value.length === 0) {
|
|
456
499
|
throw new Error("Value Cannot be empty.");
|
|
457
500
|
}
|
|
501
|
+
this._id = `literal-${idIndex$8++}`;
|
|
458
502
|
this._type = "literal";
|
|
459
503
|
this._name = name;
|
|
460
|
-
this.
|
|
504
|
+
this._text = value;
|
|
461
505
|
this._runes = Array.from(value);
|
|
462
506
|
this._isOptional = isOptional;
|
|
463
507
|
this._parent = null;
|
|
@@ -470,8 +514,9 @@ class Literal {
|
|
|
470
514
|
const ast = this.parse(cursor);
|
|
471
515
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
472
516
|
}
|
|
473
|
-
exec(text) {
|
|
517
|
+
exec(text, record = false) {
|
|
474
518
|
const cursor = new Cursor(text);
|
|
519
|
+
record && cursor.startRecording();
|
|
475
520
|
const ast = this.parse(cursor);
|
|
476
521
|
return {
|
|
477
522
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -479,20 +524,24 @@ class Literal {
|
|
|
479
524
|
};
|
|
480
525
|
}
|
|
481
526
|
parse(cursor) {
|
|
527
|
+
cursor.startParseWith(this);
|
|
482
528
|
this._firstIndex = cursor.index;
|
|
483
529
|
const passed = this._tryToParse(cursor);
|
|
484
530
|
if (passed) {
|
|
485
531
|
cursor.resolveError();
|
|
486
532
|
const node = this._createNode();
|
|
487
533
|
cursor.recordMatch(this, node);
|
|
534
|
+
cursor.endParse();
|
|
488
535
|
return node;
|
|
489
536
|
}
|
|
490
537
|
if (!this._isOptional) {
|
|
491
538
|
cursor.recordErrorAt(this._firstIndex, this._endIndex, this);
|
|
539
|
+
cursor.endParse();
|
|
492
540
|
return null;
|
|
493
541
|
}
|
|
494
542
|
cursor.resolveError();
|
|
495
543
|
cursor.moveTo(this._firstIndex);
|
|
544
|
+
cursor.endParse();
|
|
496
545
|
return null;
|
|
497
546
|
}
|
|
498
547
|
_tryToParse(cursor) {
|
|
@@ -506,7 +555,7 @@ class Literal {
|
|
|
506
555
|
break;
|
|
507
556
|
}
|
|
508
557
|
if (i + 1 === literalRuneLength) {
|
|
509
|
-
this._lastIndex = this._firstIndex + this.
|
|
558
|
+
this._lastIndex = this._firstIndex + this._text.length - 1;
|
|
510
559
|
passed = true;
|
|
511
560
|
break;
|
|
512
561
|
}
|
|
@@ -519,14 +568,15 @@ class Literal {
|
|
|
519
568
|
return passed;
|
|
520
569
|
}
|
|
521
570
|
_createNode() {
|
|
522
|
-
return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this.
|
|
571
|
+
return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this._text);
|
|
523
572
|
}
|
|
524
573
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
525
|
-
const clone = new Literal(name, this.
|
|
574
|
+
const clone = new Literal(name, this._text, isOptional);
|
|
575
|
+
clone._id = this._id;
|
|
526
576
|
return clone;
|
|
527
577
|
}
|
|
528
578
|
getTokens() {
|
|
529
|
-
return [this.
|
|
579
|
+
return [this._text];
|
|
530
580
|
}
|
|
531
581
|
getTokensAfter(_lastMatched) {
|
|
532
582
|
return [];
|
|
@@ -552,9 +602,16 @@ class Literal {
|
|
|
552
602
|
find(_predicate) {
|
|
553
603
|
return null;
|
|
554
604
|
}
|
|
605
|
+
isEqual(pattern) {
|
|
606
|
+
return pattern.type === this.type && pattern._text === this._text;
|
|
607
|
+
}
|
|
555
608
|
}
|
|
556
609
|
|
|
610
|
+
let idIndex$7 = 0;
|
|
557
611
|
class Regex {
|
|
612
|
+
get id() {
|
|
613
|
+
return this._id;
|
|
614
|
+
}
|
|
558
615
|
get type() {
|
|
559
616
|
return this._type;
|
|
560
617
|
}
|
|
@@ -579,6 +636,7 @@ class Regex {
|
|
|
579
636
|
this._firstIndex = -1;
|
|
580
637
|
this._substring = "";
|
|
581
638
|
this._tokens = [];
|
|
639
|
+
this._id = `regex-${idIndex$7++}`;
|
|
582
640
|
this._type = "regex";
|
|
583
641
|
this._name = name;
|
|
584
642
|
this._isOptional = isOptional;
|
|
@@ -603,8 +661,9 @@ class Regex {
|
|
|
603
661
|
const ast = this.parse(cursor);
|
|
604
662
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
605
663
|
}
|
|
606
|
-
exec(text) {
|
|
664
|
+
exec(text, record = false) {
|
|
607
665
|
const cursor = new Cursor(text);
|
|
666
|
+
record && cursor.startRecording();
|
|
608
667
|
const ast = this.parse(cursor);
|
|
609
668
|
return {
|
|
610
669
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -612,9 +671,11 @@ class Regex {
|
|
|
612
671
|
};
|
|
613
672
|
}
|
|
614
673
|
parse(cursor) {
|
|
674
|
+
cursor.startParseWith(this);
|
|
615
675
|
this._firstIndex = cursor.index;
|
|
616
676
|
this.resetState(cursor);
|
|
617
677
|
this.tryToParse(cursor);
|
|
678
|
+
cursor.endParse();
|
|
618
679
|
return this._node;
|
|
619
680
|
}
|
|
620
681
|
resetState(cursor) {
|
|
@@ -646,9 +707,10 @@ class Regex {
|
|
|
646
707
|
this._node = null;
|
|
647
708
|
}
|
|
648
709
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
649
|
-
const
|
|
650
|
-
|
|
651
|
-
|
|
710
|
+
const clone = new Regex(name, this._originalRegexString, isOptional);
|
|
711
|
+
clone._tokens = this._tokens.slice();
|
|
712
|
+
clone._id = this._id;
|
|
713
|
+
return clone;
|
|
652
714
|
}
|
|
653
715
|
getTokens() {
|
|
654
716
|
return this._tokens;
|
|
@@ -680,6 +742,9 @@ class Regex {
|
|
|
680
742
|
setTokens(tokens) {
|
|
681
743
|
this._tokens = tokens;
|
|
682
744
|
}
|
|
745
|
+
isEqual(pattern) {
|
|
746
|
+
return pattern.type === this.type && pattern._originalRegexString === this._originalRegexString;
|
|
747
|
+
}
|
|
683
748
|
}
|
|
684
749
|
|
|
685
750
|
function findPattern(pattern, predicate) {
|
|
@@ -704,7 +769,11 @@ function findPattern(pattern, predicate) {
|
|
|
704
769
|
}
|
|
705
770
|
}
|
|
706
771
|
|
|
772
|
+
let idIndex$6 = 0;
|
|
707
773
|
class Reference {
|
|
774
|
+
get id() {
|
|
775
|
+
return this._id;
|
|
776
|
+
}
|
|
708
777
|
get type() {
|
|
709
778
|
return this._type;
|
|
710
779
|
}
|
|
@@ -724,6 +793,7 @@ class Reference {
|
|
|
724
793
|
return this._isOptional;
|
|
725
794
|
}
|
|
726
795
|
constructor(name, isOptional = false) {
|
|
796
|
+
this._id = `reference-${idIndex$6++}`;
|
|
727
797
|
this._type = "reference";
|
|
728
798
|
this._name = name;
|
|
729
799
|
this._parent = null;
|
|
@@ -736,8 +806,9 @@ class Reference {
|
|
|
736
806
|
const ast = this.parse(cursor);
|
|
737
807
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
738
808
|
}
|
|
739
|
-
exec(text) {
|
|
809
|
+
exec(text, record = false) {
|
|
740
810
|
const cursor = new Cursor(text);
|
|
811
|
+
record && cursor.startRecording();
|
|
741
812
|
const ast = this.parse(cursor);
|
|
742
813
|
return {
|
|
743
814
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -813,7 +884,12 @@ class Reference {
|
|
|
813
884
|
return null;
|
|
814
885
|
}
|
|
815
886
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
816
|
-
|
|
887
|
+
const clone = new Reference(name, isOptional);
|
|
888
|
+
clone._id = this._id;
|
|
889
|
+
return clone;
|
|
890
|
+
}
|
|
891
|
+
isEqual(pattern) {
|
|
892
|
+
return pattern.type === this.type && pattern.name === this.name;
|
|
817
893
|
}
|
|
818
894
|
}
|
|
819
895
|
|
|
@@ -821,7 +897,11 @@ function clonePatterns(patterns, isOptional) {
|
|
|
821
897
|
return patterns.map(p => p.clone(p.name, isOptional));
|
|
822
898
|
}
|
|
823
899
|
|
|
900
|
+
let idIndex$5 = 0;
|
|
824
901
|
class Or {
|
|
902
|
+
get id() {
|
|
903
|
+
return this._id;
|
|
904
|
+
}
|
|
825
905
|
get type() {
|
|
826
906
|
return this._type;
|
|
827
907
|
}
|
|
@@ -846,6 +926,7 @@ class Or {
|
|
|
846
926
|
}
|
|
847
927
|
const children = clonePatterns(options, false);
|
|
848
928
|
this._assignChildrenToParent(children);
|
|
929
|
+
this._id = `or-${idIndex$5++}`;
|
|
849
930
|
this._type = "or";
|
|
850
931
|
this._name = name;
|
|
851
932
|
this._parent = null;
|
|
@@ -864,8 +945,9 @@ class Or {
|
|
|
864
945
|
const ast = this.parse(cursor);
|
|
865
946
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
866
947
|
}
|
|
867
|
-
exec(text) {
|
|
948
|
+
exec(text, record = false) {
|
|
868
949
|
const cursor = new Cursor(text);
|
|
950
|
+
record && cursor.startRecording();
|
|
869
951
|
const ast = this.parse(cursor);
|
|
870
952
|
return {
|
|
871
953
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -873,19 +955,23 @@ class Or {
|
|
|
873
955
|
};
|
|
874
956
|
}
|
|
875
957
|
parse(cursor) {
|
|
958
|
+
cursor.startParseWith(this);
|
|
876
959
|
this._firstIndex = cursor.index;
|
|
877
960
|
const node = this._tryToParse(cursor);
|
|
878
961
|
if (node != null) {
|
|
879
962
|
cursor.moveTo(node.lastIndex);
|
|
880
963
|
cursor.resolveError();
|
|
964
|
+
cursor.endParse();
|
|
881
965
|
return node;
|
|
882
966
|
}
|
|
883
967
|
if (!this._isOptional) {
|
|
884
968
|
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
969
|
+
cursor.endParse();
|
|
885
970
|
return null;
|
|
886
971
|
}
|
|
887
972
|
cursor.resolveError();
|
|
888
973
|
cursor.moveTo(this._firstIndex);
|
|
974
|
+
cursor.endParse();
|
|
889
975
|
return null;
|
|
890
976
|
}
|
|
891
977
|
_tryToParse(cursor) {
|
|
@@ -948,11 +1034,19 @@ class Or {
|
|
|
948
1034
|
}
|
|
949
1035
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
950
1036
|
const or = new Or(name, this._children, isOptional, this._isGreedy);
|
|
1037
|
+
or._id = this._id;
|
|
951
1038
|
return or;
|
|
952
1039
|
}
|
|
1040
|
+
isEqual(pattern) {
|
|
1041
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
1042
|
+
}
|
|
953
1043
|
}
|
|
954
1044
|
|
|
1045
|
+
let idIndex$4 = 0;
|
|
955
1046
|
class FiniteRepeat {
|
|
1047
|
+
get id() {
|
|
1048
|
+
return this._id;
|
|
1049
|
+
}
|
|
956
1050
|
get type() {
|
|
957
1051
|
return this._type;
|
|
958
1052
|
}
|
|
@@ -978,6 +1072,7 @@ class FiniteRepeat {
|
|
|
978
1072
|
return this._max;
|
|
979
1073
|
}
|
|
980
1074
|
constructor(name, pattern, repeatAmount, options = {}) {
|
|
1075
|
+
this._id = `finite-repeat-${idIndex$4++}`;
|
|
981
1076
|
this._type = "finite-repeat";
|
|
982
1077
|
this._name = name;
|
|
983
1078
|
this._parent = null;
|
|
@@ -994,6 +1089,7 @@ class FiniteRepeat {
|
|
|
994
1089
|
}
|
|
995
1090
|
}
|
|
996
1091
|
parse(cursor) {
|
|
1092
|
+
cursor.startParseWith(this);
|
|
997
1093
|
const startIndex = cursor.index;
|
|
998
1094
|
const nodes = [];
|
|
999
1095
|
const modulo = this._hasDivider ? 2 : 1;
|
|
@@ -1028,16 +1124,19 @@ class FiniteRepeat {
|
|
|
1028
1124
|
const lastIndex = cursor.index;
|
|
1029
1125
|
cursor.moveTo(startIndex);
|
|
1030
1126
|
cursor.recordErrorAt(startIndex, lastIndex, this);
|
|
1127
|
+
cursor.endParse();
|
|
1031
1128
|
return null;
|
|
1032
1129
|
}
|
|
1033
1130
|
else if (nodes.length === 0) {
|
|
1034
1131
|
cursor.resolveError();
|
|
1035
1132
|
cursor.moveTo(startIndex);
|
|
1133
|
+
cursor.endParse();
|
|
1036
1134
|
return null;
|
|
1037
1135
|
}
|
|
1038
1136
|
const firstIndex = nodes[0].firstIndex;
|
|
1039
1137
|
const lastIndex = nodes[nodes.length - 1].lastIndex;
|
|
1040
1138
|
cursor.moveTo(lastIndex);
|
|
1139
|
+
cursor.endParse();
|
|
1041
1140
|
return new Node(this._type, this.name, firstIndex, lastIndex, nodes);
|
|
1042
1141
|
}
|
|
1043
1142
|
test(text) {
|
|
@@ -1045,8 +1144,9 @@ class FiniteRepeat {
|
|
|
1045
1144
|
const ast = this.parse(cursor);
|
|
1046
1145
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1047
1146
|
}
|
|
1048
|
-
exec(text) {
|
|
1147
|
+
exec(text, record = false) {
|
|
1049
1148
|
const cursor = new Cursor(text);
|
|
1149
|
+
record && cursor.startRecording();
|
|
1050
1150
|
const ast = this.parse(cursor);
|
|
1051
1151
|
return {
|
|
1052
1152
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -1063,11 +1163,13 @@ class FiniteRepeat {
|
|
|
1063
1163
|
min = Math.max(this._min, 1);
|
|
1064
1164
|
}
|
|
1065
1165
|
}
|
|
1066
|
-
|
|
1166
|
+
const clone = new FiniteRepeat(name, this._children[0], this._max, {
|
|
1067
1167
|
divider: this._hasDivider ? this._children[1] : undefined,
|
|
1068
1168
|
min,
|
|
1069
1169
|
trimDivider: this._trimDivider
|
|
1070
1170
|
});
|
|
1171
|
+
clone._id = this._id;
|
|
1172
|
+
return clone;
|
|
1071
1173
|
}
|
|
1072
1174
|
getTokens() {
|
|
1073
1175
|
return this._children[0].getTokens();
|
|
@@ -1115,9 +1217,16 @@ class FiniteRepeat {
|
|
|
1115
1217
|
find(predicate) {
|
|
1116
1218
|
return findPattern(this, predicate);
|
|
1117
1219
|
}
|
|
1220
|
+
isEqual(pattern) {
|
|
1221
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
1222
|
+
}
|
|
1118
1223
|
}
|
|
1119
1224
|
|
|
1225
|
+
let idIndex$3 = 0;
|
|
1120
1226
|
class InfiniteRepeat {
|
|
1227
|
+
get id() {
|
|
1228
|
+
return this._id;
|
|
1229
|
+
}
|
|
1121
1230
|
get type() {
|
|
1122
1231
|
return this._type;
|
|
1123
1232
|
}
|
|
@@ -1150,6 +1259,7 @@ class InfiniteRepeat {
|
|
|
1150
1259
|
children = [pattern.clone(pattern.name, false)];
|
|
1151
1260
|
}
|
|
1152
1261
|
this._assignChildrenToParent(children);
|
|
1262
|
+
this._id = `infinite-repeat-${idIndex$3++}`;
|
|
1153
1263
|
this._type = "infinite-repeat";
|
|
1154
1264
|
this._name = name;
|
|
1155
1265
|
this._min = min;
|
|
@@ -1171,8 +1281,9 @@ class InfiniteRepeat {
|
|
|
1171
1281
|
const ast = this.parse(cursor);
|
|
1172
1282
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1173
1283
|
}
|
|
1174
|
-
exec(text) {
|
|
1284
|
+
exec(text, record = false) {
|
|
1175
1285
|
const cursor = new Cursor(text);
|
|
1286
|
+
record && cursor.startRecording();
|
|
1176
1287
|
const ast = this.parse(cursor);
|
|
1177
1288
|
return {
|
|
1178
1289
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -1180,6 +1291,7 @@ class InfiniteRepeat {
|
|
|
1180
1291
|
};
|
|
1181
1292
|
}
|
|
1182
1293
|
parse(cursor) {
|
|
1294
|
+
cursor.startParseWith(this);
|
|
1183
1295
|
this._firstIndex = cursor.index;
|
|
1184
1296
|
this._nodes = [];
|
|
1185
1297
|
const passed = this._tryToParse(cursor);
|
|
@@ -1190,12 +1302,15 @@ class InfiniteRepeat {
|
|
|
1190
1302
|
cursor.moveTo(node.lastIndex);
|
|
1191
1303
|
cursor.recordMatch(this, node);
|
|
1192
1304
|
}
|
|
1305
|
+
cursor.endParse();
|
|
1193
1306
|
return node;
|
|
1194
1307
|
}
|
|
1195
1308
|
if (this._min > 0) {
|
|
1309
|
+
cursor.endParse();
|
|
1196
1310
|
return null;
|
|
1197
1311
|
}
|
|
1198
1312
|
cursor.resolveError();
|
|
1313
|
+
cursor.endParse();
|
|
1199
1314
|
return null;
|
|
1200
1315
|
}
|
|
1201
1316
|
_meetsMin() {
|
|
@@ -1349,15 +1464,24 @@ class InfiniteRepeat {
|
|
|
1349
1464
|
min = Math.max(this._min, 1);
|
|
1350
1465
|
}
|
|
1351
1466
|
}
|
|
1352
|
-
|
|
1467
|
+
const clone = new InfiniteRepeat(name, this._pattern, {
|
|
1353
1468
|
divider: this._divider == null ? undefined : this._divider,
|
|
1354
1469
|
min: min,
|
|
1355
1470
|
trimDivider: this._trimDivider
|
|
1356
1471
|
});
|
|
1472
|
+
clone._id = this._id;
|
|
1473
|
+
return clone;
|
|
1474
|
+
}
|
|
1475
|
+
isEqual(pattern) {
|
|
1476
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
1357
1477
|
}
|
|
1358
1478
|
}
|
|
1359
1479
|
|
|
1480
|
+
let idIndex$2 = 0;
|
|
1360
1481
|
class Repeat {
|
|
1482
|
+
get id() {
|
|
1483
|
+
return this._id;
|
|
1484
|
+
}
|
|
1361
1485
|
get type() {
|
|
1362
1486
|
return this._repeatPattern.type;
|
|
1363
1487
|
}
|
|
@@ -1377,6 +1501,7 @@ class Repeat {
|
|
|
1377
1501
|
return this._repeatPattern.isOptional;
|
|
1378
1502
|
}
|
|
1379
1503
|
constructor(name, pattern, options = {}) {
|
|
1504
|
+
this._id = `repeat-${idIndex$2++}`;
|
|
1380
1505
|
this._pattern = pattern;
|
|
1381
1506
|
this._parent = null;
|
|
1382
1507
|
this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
|
|
@@ -1408,7 +1533,9 @@ class Repeat {
|
|
|
1408
1533
|
min = Math.max(this._options.min, 1);
|
|
1409
1534
|
}
|
|
1410
1535
|
}
|
|
1411
|
-
|
|
1536
|
+
const clone = new Repeat(name, this._pattern, Object.assign(Object.assign({}, this._options), { min }));
|
|
1537
|
+
clone._id = this._id;
|
|
1538
|
+
return clone;
|
|
1412
1539
|
}
|
|
1413
1540
|
getTokens() {
|
|
1414
1541
|
return this._repeatPattern.getTokens();
|
|
@@ -1443,6 +1570,9 @@ class Repeat {
|
|
|
1443
1570
|
find(predicate) {
|
|
1444
1571
|
return this._repeatPattern.find(predicate);
|
|
1445
1572
|
}
|
|
1573
|
+
isEqual(pattern) {
|
|
1574
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
1575
|
+
}
|
|
1446
1576
|
}
|
|
1447
1577
|
|
|
1448
1578
|
const comment = new Regex("comment", "#[^\r\n]+");
|
|
@@ -1457,7 +1587,11 @@ function filterOutNull(nodes) {
|
|
|
1457
1587
|
return filteredNodes;
|
|
1458
1588
|
}
|
|
1459
1589
|
|
|
1590
|
+
let idIndex$1 = 0;
|
|
1460
1591
|
class And {
|
|
1592
|
+
get id() {
|
|
1593
|
+
return this._id;
|
|
1594
|
+
}
|
|
1461
1595
|
get type() {
|
|
1462
1596
|
return this._type;
|
|
1463
1597
|
}
|
|
@@ -1482,6 +1616,7 @@ class And {
|
|
|
1482
1616
|
}
|
|
1483
1617
|
const children = clonePatterns(sequence);
|
|
1484
1618
|
this._assignChildrenToParent(children);
|
|
1619
|
+
this._id = `and-${idIndex$1++}`;
|
|
1485
1620
|
this._type = "and";
|
|
1486
1621
|
this._name = name;
|
|
1487
1622
|
this._isOptional = isOptional;
|
|
@@ -1500,8 +1635,9 @@ class And {
|
|
|
1500
1635
|
const ast = this.parse(cursor);
|
|
1501
1636
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1502
1637
|
}
|
|
1503
|
-
exec(text) {
|
|
1638
|
+
exec(text, record = false) {
|
|
1504
1639
|
const cursor = new Cursor(text);
|
|
1640
|
+
record && cursor.startRecording();
|
|
1505
1641
|
const ast = this.parse(cursor);
|
|
1506
1642
|
return {
|
|
1507
1643
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -1509,6 +1645,7 @@ class And {
|
|
|
1509
1645
|
};
|
|
1510
1646
|
}
|
|
1511
1647
|
parse(cursor) {
|
|
1648
|
+
cursor.startParseWith(this);
|
|
1512
1649
|
this._firstIndex = cursor.index;
|
|
1513
1650
|
this._nodes = [];
|
|
1514
1651
|
const passed = this.tryToParse(cursor);
|
|
@@ -1517,11 +1654,13 @@ class And {
|
|
|
1517
1654
|
if (node !== null) {
|
|
1518
1655
|
cursor.recordMatch(this, node);
|
|
1519
1656
|
}
|
|
1657
|
+
cursor.endParse();
|
|
1520
1658
|
return node;
|
|
1521
1659
|
}
|
|
1522
1660
|
if (this._isOptional) {
|
|
1523
1661
|
cursor.resolveError();
|
|
1524
1662
|
}
|
|
1663
|
+
cursor.endParse();
|
|
1525
1664
|
return null;
|
|
1526
1665
|
}
|
|
1527
1666
|
tryToParse(cursor) {
|
|
@@ -1680,7 +1819,12 @@ class And {
|
|
|
1680
1819
|
return findPattern(this, predicate);
|
|
1681
1820
|
}
|
|
1682
1821
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
1683
|
-
|
|
1822
|
+
const clone = new And(name, this._children, isOptional);
|
|
1823
|
+
clone._id = this._id;
|
|
1824
|
+
return clone;
|
|
1825
|
+
}
|
|
1826
|
+
isEqual(pattern) {
|
|
1827
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
1684
1828
|
}
|
|
1685
1829
|
}
|
|
1686
1830
|
|
|
@@ -1697,34 +1841,45 @@ const allSpaces = new Regex("all-spaces", "\\s+", true);
|
|
|
1697
1841
|
|
|
1698
1842
|
const name$1 = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
|
|
1699
1843
|
|
|
1700
|
-
const
|
|
1701
|
-
const optionalIsOptional = new Literal("is-optional", "?", true);
|
|
1702
|
-
const patternName$1 = name$1.clone("pattern-name");
|
|
1703
|
-
const pattern = new And("pattern", [
|
|
1704
|
-
optionalNot,
|
|
1705
|
-
patternName$1,
|
|
1706
|
-
optionalIsOptional,
|
|
1707
|
-
]);
|
|
1708
|
-
|
|
1709
|
-
const divider$1 = new Regex("and-divider", "\\s*[&]\\s*");
|
|
1710
|
-
divider$1.setTokens([" & "]);
|
|
1711
|
-
const andLiteral = new Repeat("and-literal", pattern, { divider: divider$1, min: 2, trimDivider: true });
|
|
1844
|
+
const regexLiteral = new Regex("regex-literal", "/(\\\\/|[^/\\n\\r])*/");
|
|
1712
1845
|
|
|
1713
|
-
const
|
|
1714
|
-
|
|
1715
|
-
|
|
1846
|
+
const patternName$3 = name$1.clone("pattern-name");
|
|
1847
|
+
const anonymousLiterals = new Or("anonymous-literals", [
|
|
1848
|
+
literal,
|
|
1849
|
+
regexLiteral,
|
|
1850
|
+
patternName$3,
|
|
1851
|
+
new Reference("repeat-literal"),
|
|
1852
|
+
]);
|
|
1853
|
+
const anonymousWrappedLiterals = new Or("anonymous-wrapped-literals", [
|
|
1854
|
+
new Reference("or-literal"),
|
|
1855
|
+
new Reference("and-literal"),
|
|
1856
|
+
new Reference("complex-anonymous-pattern")
|
|
1857
|
+
]);
|
|
1716
1858
|
|
|
1717
|
-
const
|
|
1859
|
+
const inlinePatternOpenParen = new Literal("anonymous-pattern-open-paren", "(");
|
|
1860
|
+
const inlinePatternCloseParen = new Literal("anonymous-pattern-close-paren", ")");
|
|
1861
|
+
const optionalLineSpaces$1 = lineSpaces$1.clone(undefined, true);
|
|
1862
|
+
const complexAnonymousPattern = new And("complex-anonymous-pattern", [
|
|
1863
|
+
inlinePatternOpenParen,
|
|
1864
|
+
optionalLineSpaces$1,
|
|
1865
|
+
anonymousWrappedLiterals,
|
|
1866
|
+
optionalLineSpaces$1,
|
|
1867
|
+
inlinePatternCloseParen,
|
|
1868
|
+
]);
|
|
1869
|
+
const anonymousPattern = new Or("anonymous-pattern", [
|
|
1870
|
+
anonymousLiterals,
|
|
1871
|
+
complexAnonymousPattern
|
|
1872
|
+
]);
|
|
1718
1873
|
|
|
1719
|
-
const patternName = name$1.clone("pattern-name");
|
|
1720
1874
|
const optionalSpaces$2 = spaces$1.clone("optional-spaces", true);
|
|
1721
|
-
const dividerPattern = name$1.clone("divider-pattern");
|
|
1722
1875
|
const openBracket$1 = new Literal("open-bracket", "{");
|
|
1723
1876
|
const closeBracket$1 = new Literal("close-bracket", "}");
|
|
1724
1877
|
const comma = new Literal("comma", ",");
|
|
1725
1878
|
const integer = new Regex("integer", "([1-9][0-9]*)|0");
|
|
1726
1879
|
integer.setTokens(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
|
|
1727
1880
|
const optionalInteger = integer.clone("integer", true);
|
|
1881
|
+
const trimKeyword = new Literal("trim-keyword", "trim", true);
|
|
1882
|
+
const trimFlag = new And("trim-flag", [lineSpaces$1, trimKeyword], true);
|
|
1728
1883
|
const bounds = new And("bounds", [
|
|
1729
1884
|
openBracket$1,
|
|
1730
1885
|
optionalSpaces$2,
|
|
@@ -1733,7 +1888,6 @@ const bounds = new And("bounds", [
|
|
|
1733
1888
|
comma,
|
|
1734
1889
|
optionalSpaces$2,
|
|
1735
1890
|
optionalInteger.clone("max"),
|
|
1736
|
-
optionalSpaces$2,
|
|
1737
1891
|
closeBracket$1
|
|
1738
1892
|
]);
|
|
1739
1893
|
const exactCount = new And("exact-count", [
|
|
@@ -1750,41 +1904,67 @@ const quantifier = new Or("quantifier", [
|
|
|
1750
1904
|
exactCount,
|
|
1751
1905
|
bounds
|
|
1752
1906
|
]);
|
|
1753
|
-
const
|
|
1754
|
-
const
|
|
1755
|
-
const openParen = new Literal("open-paren", "(");
|
|
1756
|
-
const closeParen = new Literal("close-paren", ")");
|
|
1907
|
+
const openParen = new Literal("repeat-open-paren", "(");
|
|
1908
|
+
const closeParen = new Literal("repeat-close-paren", ")");
|
|
1757
1909
|
const dividerComma = new Regex("divider-comma", "\\s*,\\s*");
|
|
1758
1910
|
dividerComma.setTokens([", "]);
|
|
1911
|
+
const patternName$2 = name$1.clone("pattern-name");
|
|
1912
|
+
const patterns$3 = new Or("or-patterns", [patternName$2, anonymousPattern]);
|
|
1913
|
+
const dividerPattern = patterns$3.clone("divider-pattern");
|
|
1759
1914
|
const repeatLiteral = new And("repeat-literal", [
|
|
1760
1915
|
openParen,
|
|
1761
1916
|
optionalSpaces$2,
|
|
1762
|
-
|
|
1763
|
-
optional,
|
|
1764
|
-
new And("optional-divider-section", [dividerComma, dividerPattern], true),
|
|
1917
|
+
patterns$3,
|
|
1918
|
+
new And("optional-divider-section", [dividerComma, dividerPattern, trimFlag], true),
|
|
1765
1919
|
optionalSpaces$2,
|
|
1766
1920
|
closeParen,
|
|
1767
|
-
new And("quantifier-section", [
|
|
1768
|
-
new And("optional-trim-divider-section", [spaces$1, trimDivider], true)
|
|
1921
|
+
new And("quantifier-section", [quantifier]),
|
|
1769
1922
|
]);
|
|
1770
1923
|
|
|
1771
|
-
const
|
|
1772
|
-
const
|
|
1773
|
-
const
|
|
1924
|
+
const optionalNot = new Literal("not", "!", true);
|
|
1925
|
+
const optionalIsOptional$1 = new Literal("is-optional", "?", true);
|
|
1926
|
+
const patternName$1 = name$1.clone("pattern-name");
|
|
1927
|
+
const patterns$2 = new Or("and-patterns", [patternName$1, anonymousPattern]);
|
|
1928
|
+
const pattern$1 = new And("and-child-pattern", [
|
|
1929
|
+
optionalNot,
|
|
1930
|
+
patterns$2,
|
|
1931
|
+
optionalIsOptional$1,
|
|
1932
|
+
]);
|
|
1933
|
+
const divider$1 = new Regex("and-divider", "\\s*[+]\\s*");
|
|
1934
|
+
divider$1.setTokens([" + "]);
|
|
1935
|
+
const andLiteral = new Repeat("and-literal", pattern$1, { divider: divider$1, min: 2, trimDivider: true });
|
|
1936
|
+
|
|
1937
|
+
const patternName = name$1.clone("pattern-name");
|
|
1938
|
+
const patterns$1 = new Or("or-patterns", [patternName, anonymousPattern]);
|
|
1939
|
+
const defaultDivider = new Regex("default-divider", "\\s*[|]\\s*");
|
|
1940
|
+
const greedyDivider = new Regex("greedy-divider", "\\s*[<][|][>]\\s*");
|
|
1941
|
+
const divider = new Or("or-divider", [defaultDivider, greedyDivider]);
|
|
1942
|
+
defaultDivider.setTokens([" | "]);
|
|
1943
|
+
greedyDivider.setTokens([" <|> "]);
|
|
1944
|
+
const orLiteral = new Repeat("or-literal", patterns$1, { divider, min: 2, trimDivider: true });
|
|
1945
|
+
|
|
1946
|
+
const aliasLiteral = name$1.clone("alias-literal");
|
|
1947
|
+
const optionalIsOptional = new Literal("is-optional", "?", true);
|
|
1948
|
+
const configurableAnonymousPattern = new And("configurable-anonymous-pattern", [anonymousPattern, optionalIsOptional]);
|
|
1949
|
+
const pattern = new Or("pattern", [
|
|
1774
1950
|
literal,
|
|
1775
1951
|
regexLiteral,
|
|
1952
|
+
repeatLiteral,
|
|
1953
|
+
aliasLiteral,
|
|
1776
1954
|
orLiteral,
|
|
1777
1955
|
andLiteral,
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1956
|
+
configurableAnonymousPattern,
|
|
1957
|
+
], false, true);
|
|
1958
|
+
|
|
1959
|
+
const optionalSpaces$1 = spaces$1.clone("optional-spaces", true);
|
|
1960
|
+
const assignOperator = new Literal("assign-operator", "=");
|
|
1781
1961
|
const assignStatement = new And("assign-statement", [
|
|
1782
1962
|
optionalSpaces$1,
|
|
1783
1963
|
name$1,
|
|
1784
1964
|
optionalSpaces$1,
|
|
1785
1965
|
assignOperator,
|
|
1786
1966
|
optionalSpaces$1,
|
|
1787
|
-
|
|
1967
|
+
pattern
|
|
1788
1968
|
]);
|
|
1789
1969
|
const statement = new Or("statement", [assignStatement, name$1.clone("export-name")]);
|
|
1790
1970
|
|
|
@@ -1879,7 +2059,11 @@ const grammar = new And("grammar", [
|
|
|
1879
2059
|
allSpaces
|
|
1880
2060
|
]);
|
|
1881
2061
|
|
|
2062
|
+
let idIndex = 0;
|
|
1882
2063
|
class Not {
|
|
2064
|
+
get id() {
|
|
2065
|
+
return this._id;
|
|
2066
|
+
}
|
|
1883
2067
|
get type() {
|
|
1884
2068
|
return this._type;
|
|
1885
2069
|
}
|
|
@@ -1899,6 +2083,7 @@ class Not {
|
|
|
1899
2083
|
return false;
|
|
1900
2084
|
}
|
|
1901
2085
|
constructor(name, pattern) {
|
|
2086
|
+
this._id = `not-${idIndex++}`;
|
|
1902
2087
|
this._type = "not";
|
|
1903
2088
|
this._name = name;
|
|
1904
2089
|
this._parent = null;
|
|
@@ -1910,15 +2095,17 @@ class Not {
|
|
|
1910
2095
|
this.parse(cursor);
|
|
1911
2096
|
return !cursor.hasError;
|
|
1912
2097
|
}
|
|
1913
|
-
exec(text) {
|
|
2098
|
+
exec(text, record = false) {
|
|
1914
2099
|
const cursor = new Cursor(text);
|
|
2100
|
+
record && cursor.startRecording();
|
|
1915
2101
|
const ast = this.parse(cursor);
|
|
1916
2102
|
return {
|
|
1917
|
-
ast,
|
|
2103
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
1918
2104
|
cursor
|
|
1919
2105
|
};
|
|
1920
2106
|
}
|
|
1921
2107
|
parse(cursor) {
|
|
2108
|
+
cursor.startParseWith(this);
|
|
1922
2109
|
const firstIndex = cursor.index;
|
|
1923
2110
|
this._children[0].parse(cursor);
|
|
1924
2111
|
if (cursor.hasError) {
|
|
@@ -1930,10 +2117,12 @@ class Not {
|
|
|
1930
2117
|
cursor.resolveError();
|
|
1931
2118
|
cursor.recordErrorAt(firstIndex, firstIndex, this);
|
|
1932
2119
|
}
|
|
2120
|
+
cursor.endParse();
|
|
1933
2121
|
return null;
|
|
1934
2122
|
}
|
|
1935
2123
|
clone(name = this._name) {
|
|
1936
2124
|
const not = new Not(name, this._children[0]);
|
|
2125
|
+
not._id = this._id;
|
|
1937
2126
|
return not;
|
|
1938
2127
|
}
|
|
1939
2128
|
getTokens() {
|
|
@@ -1975,6 +2164,9 @@ class Not {
|
|
|
1975
2164
|
find(predicate) {
|
|
1976
2165
|
return predicate(this._children[0]) ? this._children[0] : null;
|
|
1977
2166
|
}
|
|
2167
|
+
isEqual(pattern) {
|
|
2168
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
2169
|
+
}
|
|
1978
2170
|
}
|
|
1979
2171
|
|
|
1980
2172
|
const defaultOptions = { greedyPatternNames: [], customTokens: {} };
|
|
@@ -2179,6 +2371,16 @@ function getFurthestOptions(options) {
|
|
|
2179
2371
|
return furthestOptions;
|
|
2180
2372
|
}
|
|
2181
2373
|
|
|
2374
|
+
let anonymousIndexId = 0;
|
|
2375
|
+
const patternNodes = {
|
|
2376
|
+
"literal": true,
|
|
2377
|
+
"regex-literal": true,
|
|
2378
|
+
"or-literal": true,
|
|
2379
|
+
"and-literal": true,
|
|
2380
|
+
"repeat-literal": true,
|
|
2381
|
+
"alias-literal": true,
|
|
2382
|
+
"configurable-anonymous-pattern": true
|
|
2383
|
+
};
|
|
2182
2384
|
class ParseContext {
|
|
2183
2385
|
constructor(params) {
|
|
2184
2386
|
this.patternsByName = new Map();
|
|
@@ -2223,7 +2425,7 @@ class Grammar {
|
|
|
2223
2425
|
const ast = this._tryToParse(expression);
|
|
2224
2426
|
yield this._resolveImports(ast);
|
|
2225
2427
|
this._buildPatterns(ast);
|
|
2226
|
-
return this._parseContext.patternsByName;
|
|
2428
|
+
return Object.fromEntries(this._parseContext.patternsByName);
|
|
2227
2429
|
});
|
|
2228
2430
|
}
|
|
2229
2431
|
parseString(expression) {
|
|
@@ -2233,7 +2435,7 @@ class Grammar {
|
|
|
2233
2435
|
throw new Error("Cannot use imports on parseString, use parse instead.");
|
|
2234
2436
|
}
|
|
2235
2437
|
this._buildPatterns(ast);
|
|
2236
|
-
return this._parseContext.patternsByName;
|
|
2438
|
+
return Object.fromEntries(this._parseContext.patternsByName);
|
|
2237
2439
|
}
|
|
2238
2440
|
_tryToParse(expression) {
|
|
2239
2441
|
const { ast, cursor, options, isComplete } = this._autoComplete.suggestFor(expression);
|
|
@@ -2263,41 +2465,207 @@ class Grammar {
|
|
|
2263
2465
|
if (body == null) {
|
|
2264
2466
|
return;
|
|
2265
2467
|
}
|
|
2266
|
-
body.findAll(n => n.name === "assign-statement"
|
|
2267
|
-
const
|
|
2268
|
-
|
|
2269
|
-
|
|
2468
|
+
body.findAll(n => n.name === "assign-statement").forEach((n) => {
|
|
2469
|
+
const patternNode = n.children.find(n => patternNodes[n.name] != null);
|
|
2470
|
+
if (patternNode == null) {
|
|
2471
|
+
return;
|
|
2472
|
+
}
|
|
2473
|
+
switch (patternNode.name) {
|
|
2270
2474
|
case "literal": {
|
|
2271
|
-
this.
|
|
2475
|
+
this._saveLiteral(n);
|
|
2272
2476
|
break;
|
|
2273
2477
|
}
|
|
2274
2478
|
case "regex-literal": {
|
|
2275
|
-
this.
|
|
2479
|
+
this._saveRegex(n);
|
|
2276
2480
|
break;
|
|
2277
2481
|
}
|
|
2278
2482
|
case "or-literal": {
|
|
2279
|
-
this.
|
|
2483
|
+
this._saveOr(n);
|
|
2280
2484
|
break;
|
|
2281
2485
|
}
|
|
2282
2486
|
case "and-literal": {
|
|
2283
|
-
this.
|
|
2487
|
+
this._saveAnd(n);
|
|
2284
2488
|
break;
|
|
2285
2489
|
}
|
|
2286
2490
|
case "repeat-literal": {
|
|
2287
|
-
this.
|
|
2491
|
+
this._saveRepeat(n);
|
|
2288
2492
|
break;
|
|
2289
2493
|
}
|
|
2290
2494
|
case "alias-literal": {
|
|
2291
|
-
this.
|
|
2495
|
+
this._saveAlias(n);
|
|
2292
2496
|
break;
|
|
2293
2497
|
}
|
|
2294
|
-
case "
|
|
2295
|
-
|
|
2296
|
-
this._parseContext.patternsByName.set(n.value, pattern);
|
|
2498
|
+
case "configurable-anonymous-pattern": {
|
|
2499
|
+
this._saveConfigurableAnonymous(n);
|
|
2297
2500
|
break;
|
|
2298
2501
|
}
|
|
2299
2502
|
}
|
|
2300
2503
|
});
|
|
2504
|
+
body.findAll(n => n.name === "export-name").forEach((n) => {
|
|
2505
|
+
const pattern = this._getPattern(n.value).clone();
|
|
2506
|
+
this._parseContext.patternsByName.set(n.value, pattern);
|
|
2507
|
+
});
|
|
2508
|
+
}
|
|
2509
|
+
_saveLiteral(statementNode) {
|
|
2510
|
+
const nameNode = statementNode.find(n => n.name === "name");
|
|
2511
|
+
const literalNode = statementNode.find(n => n.name === "literal");
|
|
2512
|
+
const name = nameNode.value;
|
|
2513
|
+
const literal = this._buildLiteral(name, literalNode);
|
|
2514
|
+
this._parseContext.patternsByName.set(name, literal);
|
|
2515
|
+
}
|
|
2516
|
+
_buildLiteral(name, node) {
|
|
2517
|
+
return new Literal(name, this._resolveStringValue(node.value));
|
|
2518
|
+
}
|
|
2519
|
+
_resolveStringValue(value) {
|
|
2520
|
+
return value.replace(/\\n/g, '\n')
|
|
2521
|
+
.replace(/\\r/g, '\r')
|
|
2522
|
+
.replace(/\\t/g, '\t')
|
|
2523
|
+
.replace(/\\b/g, '\b')
|
|
2524
|
+
.replace(/\\f/g, '\f')
|
|
2525
|
+
.replace(/\\v/g, '\v')
|
|
2526
|
+
.replace(/\\0/g, '\0')
|
|
2527
|
+
.replace(/\\x([0-9A-Fa-f]{2})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
|
|
2528
|
+
.replace(/\\u([0-9A-Fa-f]{4})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
|
|
2529
|
+
.replace(/\\(.)/g, '$1').slice(1, -1);
|
|
2530
|
+
}
|
|
2531
|
+
_saveRegex(statementNode) {
|
|
2532
|
+
const nameNode = statementNode.find(n => n.name === "name");
|
|
2533
|
+
const regexNode = statementNode.find(n => n.name === "regex-literal");
|
|
2534
|
+
const name = nameNode.value;
|
|
2535
|
+
const regex = this._buildRegex(name, regexNode);
|
|
2536
|
+
this._parseContext.patternsByName.set(name, regex);
|
|
2537
|
+
}
|
|
2538
|
+
_buildRegex(name, node) {
|
|
2539
|
+
const value = node.value.slice(1, node.value.length - 1);
|
|
2540
|
+
return new Regex(name, value);
|
|
2541
|
+
}
|
|
2542
|
+
_saveOr(statementNode) {
|
|
2543
|
+
const nameNode = statementNode.find(n => n.name === "name");
|
|
2544
|
+
const name = nameNode.value;
|
|
2545
|
+
const orNode = statementNode.find(n => n.name === "or-literal");
|
|
2546
|
+
const or = this._buildOr(name, orNode);
|
|
2547
|
+
this._parseContext.patternsByName.set(name, or);
|
|
2548
|
+
}
|
|
2549
|
+
_buildOr(name, node) {
|
|
2550
|
+
const patternNodes = node.children.filter(n => n.name !== "default-divider" && n.name !== "greedy-divider");
|
|
2551
|
+
const isGreedy = node.find(n => n.name === "greedy-divider") != null;
|
|
2552
|
+
const patterns = patternNodes.map(n => this._buildPattern(n));
|
|
2553
|
+
const or = new Or(name, patterns, false, isGreedy);
|
|
2554
|
+
return or;
|
|
2555
|
+
}
|
|
2556
|
+
_buildPattern(node) {
|
|
2557
|
+
const type = node.name;
|
|
2558
|
+
const name = `anonymous-pattern-${anonymousIndexId++}`;
|
|
2559
|
+
switch (type) {
|
|
2560
|
+
case "pattern-name": {
|
|
2561
|
+
return this._getPattern(node.value).clone();
|
|
2562
|
+
}
|
|
2563
|
+
case "literal": {
|
|
2564
|
+
return this._buildLiteral(node.value.slice(1, -1), node);
|
|
2565
|
+
}
|
|
2566
|
+
case "regex-literal": {
|
|
2567
|
+
return this._buildRegex(node.value.slice(1, -1), node);
|
|
2568
|
+
}
|
|
2569
|
+
case "repeat-literal": {
|
|
2570
|
+
return this._buildRepeat(name, node);
|
|
2571
|
+
}
|
|
2572
|
+
case "or-literal": {
|
|
2573
|
+
return this._buildOr(name, node);
|
|
2574
|
+
}
|
|
2575
|
+
case "and-literal": {
|
|
2576
|
+
return this._buildAnd(name, node);
|
|
2577
|
+
}
|
|
2578
|
+
case "complex-anonymous-pattern": {
|
|
2579
|
+
return this._buildComplexAnonymousPattern(node);
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
throw new Error(`Couldn't build node: ${node.name}.`);
|
|
2583
|
+
}
|
|
2584
|
+
_saveAnd(statementNode) {
|
|
2585
|
+
const nameNode = statementNode.find(n => n.name === "name");
|
|
2586
|
+
const name = nameNode.value;
|
|
2587
|
+
const andNode = statementNode.find(n => n.name === "and-literal");
|
|
2588
|
+
const and = this._buildAnd(name, andNode);
|
|
2589
|
+
this._parseContext.patternsByName.set(name, and);
|
|
2590
|
+
}
|
|
2591
|
+
_buildAnd(name, node) {
|
|
2592
|
+
const patternNodes = node.children.filter(n => n.name !== "and-divider");
|
|
2593
|
+
const patterns = patternNodes.map(n => {
|
|
2594
|
+
const patternNode = n.children[0].name === "not" ? n.children[1] : n.children[0];
|
|
2595
|
+
const isNot = n.find(n => n.name === "not") != null;
|
|
2596
|
+
const isOptional = n.find(n => n.name === "is-optional");
|
|
2597
|
+
const pattern = this._buildPattern(patternNode).clone(undefined, isOptional == null ? undefined : true);
|
|
2598
|
+
if (isNot) {
|
|
2599
|
+
return new Not(`not-${pattern.name}`, pattern);
|
|
2600
|
+
}
|
|
2601
|
+
return pattern;
|
|
2602
|
+
});
|
|
2603
|
+
return new And(name, patterns);
|
|
2604
|
+
}
|
|
2605
|
+
_saveRepeat(statementNode) {
|
|
2606
|
+
const nameNode = statementNode.find(n => n.name === "name");
|
|
2607
|
+
const name = nameNode.value;
|
|
2608
|
+
const repeatNode = statementNode.find(n => n.name === "repeat-literal");
|
|
2609
|
+
const repeat = this._buildRepeat(name, repeatNode);
|
|
2610
|
+
this._parseContext.patternsByName.set(name, repeat);
|
|
2611
|
+
}
|
|
2612
|
+
_buildRepeat(name, repeatNode) {
|
|
2613
|
+
const bounds = repeatNode.find(n => n.name === "bounds");
|
|
2614
|
+
const exactCount = repeatNode.find(n => n.name === "exact-count");
|
|
2615
|
+
const quantifier = repeatNode.find(n => n.name === "quantifier-shorthand");
|
|
2616
|
+
const trimDivider = repeatNode.find(n => n.name === "trim-flag") != null;
|
|
2617
|
+
const patterNode = repeatNode.children[1].type === "optional-spaces" ? repeatNode.children[2] : repeatNode.children[1];
|
|
2618
|
+
const pattern = this._buildPattern(patterNode);
|
|
2619
|
+
const dividerSectionNode = repeatNode.find(n => n.name === "optional-divider-section");
|
|
2620
|
+
const options = {
|
|
2621
|
+
min: 1,
|
|
2622
|
+
max: Infinity
|
|
2623
|
+
};
|
|
2624
|
+
if (trimDivider) {
|
|
2625
|
+
options.trimDivider = trimDivider;
|
|
2626
|
+
}
|
|
2627
|
+
if (dividerSectionNode != null) {
|
|
2628
|
+
const dividerNode = dividerSectionNode.children[1];
|
|
2629
|
+
options.divider = this._buildPattern(dividerNode);
|
|
2630
|
+
}
|
|
2631
|
+
if (bounds != null) {
|
|
2632
|
+
const minNode = bounds.find(p => p.name === "min");
|
|
2633
|
+
const maxNode = bounds.find(p => p.name === "max");
|
|
2634
|
+
const min = minNode == null ? 0 : Number(minNode.value);
|
|
2635
|
+
const max = maxNode == null ? Infinity : Number(maxNode.value);
|
|
2636
|
+
options.min = min;
|
|
2637
|
+
options.max = max;
|
|
2638
|
+
}
|
|
2639
|
+
else if (exactCount != null) {
|
|
2640
|
+
const integerNode = exactCount.find(p => p.name === "integer");
|
|
2641
|
+
const integer = Number(integerNode.value);
|
|
2642
|
+
options.min = integer;
|
|
2643
|
+
options.max = integer;
|
|
2644
|
+
}
|
|
2645
|
+
else if (quantifier != null) {
|
|
2646
|
+
const type = quantifier.value;
|
|
2647
|
+
if (type === "+") {
|
|
2648
|
+
options.min = 1;
|
|
2649
|
+
options.max = Infinity;
|
|
2650
|
+
}
|
|
2651
|
+
else {
|
|
2652
|
+
options.min = 0;
|
|
2653
|
+
options.max = Infinity;
|
|
2654
|
+
}
|
|
2655
|
+
}
|
|
2656
|
+
return new Repeat(name, pattern.clone(pattern.name), options);
|
|
2657
|
+
}
|
|
2658
|
+
_saveConfigurableAnonymous(node) {
|
|
2659
|
+
const nameNode = node.find(n => n.name === "name");
|
|
2660
|
+
const name = nameNode.value;
|
|
2661
|
+
const anonymousNode = node.find(n => n.name === "complex-anonymous-pattern");
|
|
2662
|
+
const isOptional = node.children[1] != null;
|
|
2663
|
+
const anonymous = this._buildPattern(anonymousNode).clone(name, isOptional);
|
|
2664
|
+
this._parseContext.patternsByName.set(name, anonymous);
|
|
2665
|
+
}
|
|
2666
|
+
_buildComplexAnonymousPattern(node) {
|
|
2667
|
+
const wrappedNode = node.children[1].name === "line-spaces" ? node.children[2] : node.children[1];
|
|
2668
|
+
return this._buildPattern(wrappedNode);
|
|
2301
2669
|
}
|
|
2302
2670
|
_resolveImports(ast) {
|
|
2303
2671
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -2326,7 +2694,7 @@ class Grammar {
|
|
|
2326
2694
|
if (parseContext.importedPatternsByName.has(importName)) {
|
|
2327
2695
|
throw new Error(`'${importName}' was already used within another import.`);
|
|
2328
2696
|
}
|
|
2329
|
-
const pattern = patterns
|
|
2697
|
+
const pattern = patterns[importName];
|
|
2330
2698
|
if (pattern == null) {
|
|
2331
2699
|
throw new Error(`Couldn't find pattern with name: ${importName}, from import: ${resource}.`);
|
|
2332
2700
|
}
|
|
@@ -2340,7 +2708,7 @@ class Grammar {
|
|
|
2340
2708
|
if (parseContext.importedPatternsByName.has(alias)) {
|
|
2341
2709
|
throw new Error(`'${alias}' was already used within another import.`);
|
|
2342
2710
|
}
|
|
2343
|
-
const pattern = patterns
|
|
2711
|
+
const pattern = patterns[importName];
|
|
2344
2712
|
if (pattern == null) {
|
|
2345
2713
|
throw new Error(`Couldn't find pattern with name: ${importName}, from import: ${resource}.`);
|
|
2346
2714
|
}
|
|
@@ -2371,48 +2739,11 @@ class Grammar {
|
|
|
2371
2739
|
resolveImport: this._resolveImport
|
|
2372
2740
|
});
|
|
2373
2741
|
const patterns = grammar.parseString(expression);
|
|
2374
|
-
params = Array.from(
|
|
2742
|
+
params = Array.from(Object.values(patterns));
|
|
2375
2743
|
}
|
|
2376
2744
|
}
|
|
2377
2745
|
return params;
|
|
2378
2746
|
}
|
|
2379
|
-
_buildLiteral(statementNode) {
|
|
2380
|
-
const nameNode = statementNode.find(n => n.name === "name");
|
|
2381
|
-
const literalNode = statementNode.find(n => n.name === "literal");
|
|
2382
|
-
const name = nameNode.value;
|
|
2383
|
-
const value = this._resolveStringValue(literalNode.value.slice(1, -1));
|
|
2384
|
-
const literal = new Literal(name, value);
|
|
2385
|
-
this._parseContext.patternsByName.set(name, literal);
|
|
2386
|
-
}
|
|
2387
|
-
_resolveStringValue(value) {
|
|
2388
|
-
return value.replace(/\\n/g, '\n')
|
|
2389
|
-
.replace(/\\r/g, '\r')
|
|
2390
|
-
.replace(/\\t/g, '\t')
|
|
2391
|
-
.replace(/\\b/g, '\b')
|
|
2392
|
-
.replace(/\\f/g, '\f')
|
|
2393
|
-
.replace(/\\v/g, '\v')
|
|
2394
|
-
.replace(/\\0/g, '\0')
|
|
2395
|
-
.replace(/\\x([0-9A-Fa-f]{2})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
|
|
2396
|
-
.replace(/\\u([0-9A-Fa-f]{4})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
|
|
2397
|
-
.replace(/\\(.)/g, '$1');
|
|
2398
|
-
}
|
|
2399
|
-
_buildRegex(statementNode) {
|
|
2400
|
-
const nameNode = statementNode.find(n => n.name === "name");
|
|
2401
|
-
const regexNode = statementNode.find(n => n.name === "regex-literal");
|
|
2402
|
-
const value = regexNode.value.slice(1, regexNode.value.length - 1);
|
|
2403
|
-
const name = nameNode.value;
|
|
2404
|
-
const regex = new Regex(name, value);
|
|
2405
|
-
this._parseContext.patternsByName.set(name, regex);
|
|
2406
|
-
}
|
|
2407
|
-
_buildOr(statementNode) {
|
|
2408
|
-
const nameNode = statementNode.find(n => n.name === "name");
|
|
2409
|
-
const orNode = statementNode.find(n => n.name === "or-literal");
|
|
2410
|
-
const patternNodes = orNode.children.filter(n => n.name === "pattern-name");
|
|
2411
|
-
const name = nameNode.value;
|
|
2412
|
-
const patterns = patternNodes.map(n => this._getPattern(n.value));
|
|
2413
|
-
const or = new Or(name, patterns, false, true);
|
|
2414
|
-
this._parseContext.patternsByName.set(name, or);
|
|
2415
|
-
}
|
|
2416
2747
|
_getPattern(name) {
|
|
2417
2748
|
let pattern = this._parseContext.patternsByName.get(name);
|
|
2418
2749
|
if (pattern == null) {
|
|
@@ -2426,82 +2757,12 @@ class Grammar {
|
|
|
2426
2757
|
}
|
|
2427
2758
|
return pattern;
|
|
2428
2759
|
}
|
|
2429
|
-
|
|
2430
|
-
const nameNode = statementNode.find(n => n.name === "name");
|
|
2431
|
-
const andNode = statementNode.find(n => n.name === "and-literal");
|
|
2432
|
-
const patternNodes = andNode.children.filter(n => n.name === "pattern");
|
|
2433
|
-
const name = nameNode.value;
|
|
2434
|
-
const patterns = patternNodes.map(n => {
|
|
2435
|
-
const nameNode = n.find(n => n.name === "pattern-name");
|
|
2436
|
-
const isNot = n.find(n => n.name === "not") != null;
|
|
2437
|
-
const isOptional = n.find(n => n.name === "is-optional") != null;
|
|
2438
|
-
const name = nameNode.value;
|
|
2439
|
-
const pattern = this._getPattern(name);
|
|
2440
|
-
if (isNot) {
|
|
2441
|
-
return new Not(`not-${name}`, pattern.clone(name, isOptional));
|
|
2442
|
-
}
|
|
2443
|
-
return pattern.clone(name, isOptional);
|
|
2444
|
-
});
|
|
2445
|
-
const and = new And(name, patterns);
|
|
2446
|
-
this._parseContext.patternsByName.set(name, and);
|
|
2447
|
-
}
|
|
2448
|
-
_buildRepeat(statementNode) {
|
|
2449
|
-
const nameNode = statementNode.find(n => n.name === "name");
|
|
2450
|
-
const repeatNode = statementNode.find(n => n.name === "repeat-literal");
|
|
2451
|
-
const patternNameNode = statementNode.find(n => n.name === "pattern-name");
|
|
2452
|
-
const dividerNode = repeatNode.find(n => n.name === "divider-pattern");
|
|
2453
|
-
const bounds = repeatNode.find(n => n.name === "bounds");
|
|
2454
|
-
const exactCount = repeatNode.find(n => n.name === "exact-count");
|
|
2455
|
-
const quantifier = repeatNode.find(n => n.name === "quantifier-shorthand");
|
|
2456
|
-
const isPatternOptional = repeatNode.find(n => n.name === "is-optional") != null;
|
|
2457
|
-
const trimDivider = repeatNode.find(n => n.name === "trim-divider") != null;
|
|
2458
|
-
const name = nameNode.value;
|
|
2459
|
-
const pattern = this._getPattern(patternNameNode.value);
|
|
2460
|
-
const options = {
|
|
2461
|
-
min: 1,
|
|
2462
|
-
max: Infinity
|
|
2463
|
-
};
|
|
2464
|
-
if (trimDivider) {
|
|
2465
|
-
options.trimDivider = trimDivider;
|
|
2466
|
-
}
|
|
2467
|
-
if (dividerNode != null) {
|
|
2468
|
-
options.divider = this._getPattern(dividerNode.value);
|
|
2469
|
-
}
|
|
2470
|
-
if (bounds != null) {
|
|
2471
|
-
const minNode = bounds.find(p => p.name === "min");
|
|
2472
|
-
const maxNode = bounds.find(p => p.name === "max");
|
|
2473
|
-
const min = minNode == null ? 0 : Number(minNode.value);
|
|
2474
|
-
const max = maxNode == null ? Infinity : Number(maxNode.value);
|
|
2475
|
-
options.min = min;
|
|
2476
|
-
options.max = max;
|
|
2477
|
-
}
|
|
2478
|
-
else if (exactCount != null) {
|
|
2479
|
-
const integerNode = exactCount.find(p => p.name === "integer");
|
|
2480
|
-
const integer = Number(integerNode.value);
|
|
2481
|
-
options.min = integer;
|
|
2482
|
-
options.max = integer;
|
|
2483
|
-
}
|
|
2484
|
-
else if (quantifier != null) {
|
|
2485
|
-
const type = quantifier.value;
|
|
2486
|
-
if (type === "+") {
|
|
2487
|
-
options.min = 1;
|
|
2488
|
-
options.max = Infinity;
|
|
2489
|
-
}
|
|
2490
|
-
else {
|
|
2491
|
-
options.min = 0;
|
|
2492
|
-
options.max = Infinity;
|
|
2493
|
-
}
|
|
2494
|
-
}
|
|
2495
|
-
const repeat = new Repeat(name, pattern.clone(pattern.name, isPatternOptional), options);
|
|
2496
|
-
this._parseContext.patternsByName.set(name, repeat);
|
|
2497
|
-
}
|
|
2498
|
-
_buildAlias(statementNode) {
|
|
2760
|
+
_saveAlias(statementNode) {
|
|
2499
2761
|
const nameNode = statementNode.find(n => n.name === "name");
|
|
2500
2762
|
const aliasNode = statementNode.find(n => n.name === "alias-literal");
|
|
2501
2763
|
const aliasName = aliasNode.value;
|
|
2502
2764
|
const name = nameNode.value;
|
|
2503
|
-
const
|
|
2504
|
-
const alias = pattern.clone(name);
|
|
2765
|
+
const alias = this._getPattern(aliasName).clone(name);
|
|
2505
2766
|
this._parseContext.patternsByName.set(name, alias);
|
|
2506
2767
|
}
|
|
2507
2768
|
static parse(expression, options) {
|
|
@@ -2518,5 +2779,29 @@ class Grammar {
|
|
|
2518
2779
|
}
|
|
2519
2780
|
}
|
|
2520
2781
|
|
|
2521
|
-
|
|
2782
|
+
function arePatternsEqual(a, b) {
|
|
2783
|
+
if (a === b) {
|
|
2784
|
+
return true;
|
|
2785
|
+
}
|
|
2786
|
+
else if (a == null || b == null) {
|
|
2787
|
+
return false;
|
|
2788
|
+
}
|
|
2789
|
+
return a.isEqual(b);
|
|
2790
|
+
}
|
|
2791
|
+
|
|
2792
|
+
const kebabRegex = /-([a-z])/g; // Define the regex once
|
|
2793
|
+
function kebabToCamelCase(str) {
|
|
2794
|
+
return str.replace(kebabRegex, (_, char) => char.toUpperCase());
|
|
2795
|
+
}
|
|
2796
|
+
function patterns(strings, ...values) {
|
|
2797
|
+
const combinedString = strings.reduce((result, str, i) => result + str + (values[i] || ''), '');
|
|
2798
|
+
const result = {};
|
|
2799
|
+
const patterns = Grammar.parseString(combinedString);
|
|
2800
|
+
Object.keys(patterns).forEach(k => {
|
|
2801
|
+
result[kebabToCamelCase(k)] = patterns[k];
|
|
2802
|
+
});
|
|
2803
|
+
return result;
|
|
2804
|
+
}
|
|
2805
|
+
|
|
2806
|
+
export { And, AutoComplete, Cursor, CursorHistory, Grammar, Literal, Node, Not, Or, ParseError, Reference, Regex, Repeat, arePatternsEqual, grammar, patterns };
|
|
2522
2807
|
//# sourceMappingURL=index.esm.js.map
|