clarity-pattern-parser 8.4.14 → 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 +472 -185
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.esm.js +471 -186
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +472 -185
- 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 +126 -72
- 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 -3
- 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.js
CHANGED
|
@@ -247,6 +247,7 @@ class CursorHistory {
|
|
|
247
247
|
this._patterns = [];
|
|
248
248
|
this._nodes = [];
|
|
249
249
|
this._errors = [];
|
|
250
|
+
this._trace = [];
|
|
250
251
|
}
|
|
251
252
|
get isRecording() {
|
|
252
253
|
return this._isRecording;
|
|
@@ -275,6 +276,9 @@ class CursorHistory {
|
|
|
275
276
|
get patterns() {
|
|
276
277
|
return this._patterns;
|
|
277
278
|
}
|
|
279
|
+
get trace() {
|
|
280
|
+
return this._trace;
|
|
281
|
+
}
|
|
278
282
|
recordMatch(pattern, node) {
|
|
279
283
|
if (this._isRecording) {
|
|
280
284
|
this._patterns.push(pattern);
|
|
@@ -329,6 +333,11 @@ class CursorHistory {
|
|
|
329
333
|
resolveError() {
|
|
330
334
|
this._currentError = null;
|
|
331
335
|
}
|
|
336
|
+
pushStackTrace(trace) {
|
|
337
|
+
if (this._isRecording) {
|
|
338
|
+
this._trace.push(trace);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
332
341
|
}
|
|
333
342
|
|
|
334
343
|
class Cursor {
|
|
@@ -385,6 +394,7 @@ class Cursor {
|
|
|
385
394
|
this._index = 0;
|
|
386
395
|
this._length = text.length;
|
|
387
396
|
this._history = new CursorHistory();
|
|
397
|
+
this._stackTrace = [];
|
|
388
398
|
}
|
|
389
399
|
hasNext() {
|
|
390
400
|
return this._index + 1 < this._length;
|
|
@@ -434,9 +444,42 @@ class Cursor {
|
|
|
434
444
|
stopRecording() {
|
|
435
445
|
this._history.stopRecording();
|
|
436
446
|
}
|
|
447
|
+
startParseWith(pattern) {
|
|
448
|
+
const patternName = pattern.name;
|
|
449
|
+
const trace = {
|
|
450
|
+
pattern,
|
|
451
|
+
cursorIndex: this.index
|
|
452
|
+
};
|
|
453
|
+
if (this._stackTrace.find(t => t.pattern.id === pattern.id && this.index === t.cursorIndex)) {
|
|
454
|
+
throw new Error(`Cyclical Pattern: ${this._stackTrace.map(t => `${t.pattern.name}#${t.pattern.id}{${t.cursorIndex}}`).join(" -> ")} -> ${patternName}#${pattern.id}{${this.index}}.`);
|
|
455
|
+
}
|
|
456
|
+
this._history.pushStackTrace(trace);
|
|
457
|
+
this._stackTrace.push(trace);
|
|
458
|
+
}
|
|
459
|
+
endParse() {
|
|
460
|
+
this._stackTrace.pop();
|
|
461
|
+
}
|
|
462
|
+
audit() {
|
|
463
|
+
return this._history.trace.map(t => {
|
|
464
|
+
const onChar = this.getChars(t.cursorIndex, t.cursorIndex);
|
|
465
|
+
const restChars = this.getChars(t.cursorIndex + 1, t.cursorIndex + 5);
|
|
466
|
+
const context = `{${t.cursorIndex}}[${onChar}]${restChars}`;
|
|
467
|
+
return `${this._buildPatternContext(t.pattern)}-->${context}`;
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
_buildPatternContext(pattern) {
|
|
471
|
+
if (pattern.parent != null) {
|
|
472
|
+
return `${pattern.parent.name}.${pattern.name}`;
|
|
473
|
+
}
|
|
474
|
+
return pattern.name;
|
|
475
|
+
}
|
|
437
476
|
}
|
|
438
477
|
|
|
478
|
+
let idIndex$8 = 0;
|
|
439
479
|
class Literal {
|
|
480
|
+
get id() {
|
|
481
|
+
return this._id;
|
|
482
|
+
}
|
|
440
483
|
get type() {
|
|
441
484
|
return this._type;
|
|
442
485
|
}
|
|
@@ -459,9 +502,10 @@ class Literal {
|
|
|
459
502
|
if (value.length === 0) {
|
|
460
503
|
throw new Error("Value Cannot be empty.");
|
|
461
504
|
}
|
|
505
|
+
this._id = `literal-${idIndex$8++}`;
|
|
462
506
|
this._type = "literal";
|
|
463
507
|
this._name = name;
|
|
464
|
-
this.
|
|
508
|
+
this._text = value;
|
|
465
509
|
this._runes = Array.from(value);
|
|
466
510
|
this._isOptional = isOptional;
|
|
467
511
|
this._parent = null;
|
|
@@ -474,8 +518,9 @@ class Literal {
|
|
|
474
518
|
const ast = this.parse(cursor);
|
|
475
519
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
476
520
|
}
|
|
477
|
-
exec(text) {
|
|
521
|
+
exec(text, record = false) {
|
|
478
522
|
const cursor = new Cursor(text);
|
|
523
|
+
record && cursor.startRecording();
|
|
479
524
|
const ast = this.parse(cursor);
|
|
480
525
|
return {
|
|
481
526
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -483,20 +528,24 @@ class Literal {
|
|
|
483
528
|
};
|
|
484
529
|
}
|
|
485
530
|
parse(cursor) {
|
|
531
|
+
cursor.startParseWith(this);
|
|
486
532
|
this._firstIndex = cursor.index;
|
|
487
533
|
const passed = this._tryToParse(cursor);
|
|
488
534
|
if (passed) {
|
|
489
535
|
cursor.resolveError();
|
|
490
536
|
const node = this._createNode();
|
|
491
537
|
cursor.recordMatch(this, node);
|
|
538
|
+
cursor.endParse();
|
|
492
539
|
return node;
|
|
493
540
|
}
|
|
494
541
|
if (!this._isOptional) {
|
|
495
542
|
cursor.recordErrorAt(this._firstIndex, this._endIndex, this);
|
|
543
|
+
cursor.endParse();
|
|
496
544
|
return null;
|
|
497
545
|
}
|
|
498
546
|
cursor.resolveError();
|
|
499
547
|
cursor.moveTo(this._firstIndex);
|
|
548
|
+
cursor.endParse();
|
|
500
549
|
return null;
|
|
501
550
|
}
|
|
502
551
|
_tryToParse(cursor) {
|
|
@@ -510,7 +559,7 @@ class Literal {
|
|
|
510
559
|
break;
|
|
511
560
|
}
|
|
512
561
|
if (i + 1 === literalRuneLength) {
|
|
513
|
-
this._lastIndex = this._firstIndex + this.
|
|
562
|
+
this._lastIndex = this._firstIndex + this._text.length - 1;
|
|
514
563
|
passed = true;
|
|
515
564
|
break;
|
|
516
565
|
}
|
|
@@ -523,14 +572,15 @@ class Literal {
|
|
|
523
572
|
return passed;
|
|
524
573
|
}
|
|
525
574
|
_createNode() {
|
|
526
|
-
return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this.
|
|
575
|
+
return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this._text);
|
|
527
576
|
}
|
|
528
577
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
529
|
-
const clone = new Literal(name, this.
|
|
578
|
+
const clone = new Literal(name, this._text, isOptional);
|
|
579
|
+
clone._id = this._id;
|
|
530
580
|
return clone;
|
|
531
581
|
}
|
|
532
582
|
getTokens() {
|
|
533
|
-
return [this.
|
|
583
|
+
return [this._text];
|
|
534
584
|
}
|
|
535
585
|
getTokensAfter(_lastMatched) {
|
|
536
586
|
return [];
|
|
@@ -556,9 +606,16 @@ class Literal {
|
|
|
556
606
|
find(_predicate) {
|
|
557
607
|
return null;
|
|
558
608
|
}
|
|
609
|
+
isEqual(pattern) {
|
|
610
|
+
return pattern.type === this.type && pattern._text === this._text;
|
|
611
|
+
}
|
|
559
612
|
}
|
|
560
613
|
|
|
614
|
+
let idIndex$7 = 0;
|
|
561
615
|
class Regex {
|
|
616
|
+
get id() {
|
|
617
|
+
return this._id;
|
|
618
|
+
}
|
|
562
619
|
get type() {
|
|
563
620
|
return this._type;
|
|
564
621
|
}
|
|
@@ -583,6 +640,7 @@ class Regex {
|
|
|
583
640
|
this._firstIndex = -1;
|
|
584
641
|
this._substring = "";
|
|
585
642
|
this._tokens = [];
|
|
643
|
+
this._id = `regex-${idIndex$7++}`;
|
|
586
644
|
this._type = "regex";
|
|
587
645
|
this._name = name;
|
|
588
646
|
this._isOptional = isOptional;
|
|
@@ -607,8 +665,9 @@ class Regex {
|
|
|
607
665
|
const ast = this.parse(cursor);
|
|
608
666
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
609
667
|
}
|
|
610
|
-
exec(text) {
|
|
668
|
+
exec(text, record = false) {
|
|
611
669
|
const cursor = new Cursor(text);
|
|
670
|
+
record && cursor.startRecording();
|
|
612
671
|
const ast = this.parse(cursor);
|
|
613
672
|
return {
|
|
614
673
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -616,9 +675,11 @@ class Regex {
|
|
|
616
675
|
};
|
|
617
676
|
}
|
|
618
677
|
parse(cursor) {
|
|
678
|
+
cursor.startParseWith(this);
|
|
619
679
|
this._firstIndex = cursor.index;
|
|
620
680
|
this.resetState(cursor);
|
|
621
681
|
this.tryToParse(cursor);
|
|
682
|
+
cursor.endParse();
|
|
622
683
|
return this._node;
|
|
623
684
|
}
|
|
624
685
|
resetState(cursor) {
|
|
@@ -650,9 +711,10 @@ class Regex {
|
|
|
650
711
|
this._node = null;
|
|
651
712
|
}
|
|
652
713
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
714
|
+
const clone = new Regex(name, this._originalRegexString, isOptional);
|
|
715
|
+
clone._tokens = this._tokens.slice();
|
|
716
|
+
clone._id = this._id;
|
|
717
|
+
return clone;
|
|
656
718
|
}
|
|
657
719
|
getTokens() {
|
|
658
720
|
return this._tokens;
|
|
@@ -684,6 +746,9 @@ class Regex {
|
|
|
684
746
|
setTokens(tokens) {
|
|
685
747
|
this._tokens = tokens;
|
|
686
748
|
}
|
|
749
|
+
isEqual(pattern) {
|
|
750
|
+
return pattern.type === this.type && pattern._originalRegexString === this._originalRegexString;
|
|
751
|
+
}
|
|
687
752
|
}
|
|
688
753
|
|
|
689
754
|
function findPattern(pattern, predicate) {
|
|
@@ -708,7 +773,11 @@ function findPattern(pattern, predicate) {
|
|
|
708
773
|
}
|
|
709
774
|
}
|
|
710
775
|
|
|
776
|
+
let idIndex$6 = 0;
|
|
711
777
|
class Reference {
|
|
778
|
+
get id() {
|
|
779
|
+
return this._id;
|
|
780
|
+
}
|
|
712
781
|
get type() {
|
|
713
782
|
return this._type;
|
|
714
783
|
}
|
|
@@ -728,6 +797,7 @@ class Reference {
|
|
|
728
797
|
return this._isOptional;
|
|
729
798
|
}
|
|
730
799
|
constructor(name, isOptional = false) {
|
|
800
|
+
this._id = `reference-${idIndex$6++}`;
|
|
731
801
|
this._type = "reference";
|
|
732
802
|
this._name = name;
|
|
733
803
|
this._parent = null;
|
|
@@ -740,8 +810,9 @@ class Reference {
|
|
|
740
810
|
const ast = this.parse(cursor);
|
|
741
811
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
742
812
|
}
|
|
743
|
-
exec(text) {
|
|
813
|
+
exec(text, record = false) {
|
|
744
814
|
const cursor = new Cursor(text);
|
|
815
|
+
record && cursor.startRecording();
|
|
745
816
|
const ast = this.parse(cursor);
|
|
746
817
|
return {
|
|
747
818
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -817,7 +888,12 @@ class Reference {
|
|
|
817
888
|
return null;
|
|
818
889
|
}
|
|
819
890
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
820
|
-
|
|
891
|
+
const clone = new Reference(name, isOptional);
|
|
892
|
+
clone._id = this._id;
|
|
893
|
+
return clone;
|
|
894
|
+
}
|
|
895
|
+
isEqual(pattern) {
|
|
896
|
+
return pattern.type === this.type && pattern.name === this.name;
|
|
821
897
|
}
|
|
822
898
|
}
|
|
823
899
|
|
|
@@ -825,7 +901,11 @@ function clonePatterns(patterns, isOptional) {
|
|
|
825
901
|
return patterns.map(p => p.clone(p.name, isOptional));
|
|
826
902
|
}
|
|
827
903
|
|
|
904
|
+
let idIndex$5 = 0;
|
|
828
905
|
class Or {
|
|
906
|
+
get id() {
|
|
907
|
+
return this._id;
|
|
908
|
+
}
|
|
829
909
|
get type() {
|
|
830
910
|
return this._type;
|
|
831
911
|
}
|
|
@@ -850,6 +930,7 @@ class Or {
|
|
|
850
930
|
}
|
|
851
931
|
const children = clonePatterns(options, false);
|
|
852
932
|
this._assignChildrenToParent(children);
|
|
933
|
+
this._id = `or-${idIndex$5++}`;
|
|
853
934
|
this._type = "or";
|
|
854
935
|
this._name = name;
|
|
855
936
|
this._parent = null;
|
|
@@ -868,8 +949,9 @@ class Or {
|
|
|
868
949
|
const ast = this.parse(cursor);
|
|
869
950
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
870
951
|
}
|
|
871
|
-
exec(text) {
|
|
952
|
+
exec(text, record = false) {
|
|
872
953
|
const cursor = new Cursor(text);
|
|
954
|
+
record && cursor.startRecording();
|
|
873
955
|
const ast = this.parse(cursor);
|
|
874
956
|
return {
|
|
875
957
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -877,19 +959,23 @@ class Or {
|
|
|
877
959
|
};
|
|
878
960
|
}
|
|
879
961
|
parse(cursor) {
|
|
962
|
+
cursor.startParseWith(this);
|
|
880
963
|
this._firstIndex = cursor.index;
|
|
881
964
|
const node = this._tryToParse(cursor);
|
|
882
965
|
if (node != null) {
|
|
883
966
|
cursor.moveTo(node.lastIndex);
|
|
884
967
|
cursor.resolveError();
|
|
968
|
+
cursor.endParse();
|
|
885
969
|
return node;
|
|
886
970
|
}
|
|
887
971
|
if (!this._isOptional) {
|
|
888
972
|
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
973
|
+
cursor.endParse();
|
|
889
974
|
return null;
|
|
890
975
|
}
|
|
891
976
|
cursor.resolveError();
|
|
892
977
|
cursor.moveTo(this._firstIndex);
|
|
978
|
+
cursor.endParse();
|
|
893
979
|
return null;
|
|
894
980
|
}
|
|
895
981
|
_tryToParse(cursor) {
|
|
@@ -952,11 +1038,19 @@ class Or {
|
|
|
952
1038
|
}
|
|
953
1039
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
954
1040
|
const or = new Or(name, this._children, isOptional, this._isGreedy);
|
|
1041
|
+
or._id = this._id;
|
|
955
1042
|
return or;
|
|
956
1043
|
}
|
|
1044
|
+
isEqual(pattern) {
|
|
1045
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
1046
|
+
}
|
|
957
1047
|
}
|
|
958
1048
|
|
|
1049
|
+
let idIndex$4 = 0;
|
|
959
1050
|
class FiniteRepeat {
|
|
1051
|
+
get id() {
|
|
1052
|
+
return this._id;
|
|
1053
|
+
}
|
|
960
1054
|
get type() {
|
|
961
1055
|
return this._type;
|
|
962
1056
|
}
|
|
@@ -982,6 +1076,7 @@ class FiniteRepeat {
|
|
|
982
1076
|
return this._max;
|
|
983
1077
|
}
|
|
984
1078
|
constructor(name, pattern, repeatAmount, options = {}) {
|
|
1079
|
+
this._id = `finite-repeat-${idIndex$4++}`;
|
|
985
1080
|
this._type = "finite-repeat";
|
|
986
1081
|
this._name = name;
|
|
987
1082
|
this._parent = null;
|
|
@@ -998,6 +1093,7 @@ class FiniteRepeat {
|
|
|
998
1093
|
}
|
|
999
1094
|
}
|
|
1000
1095
|
parse(cursor) {
|
|
1096
|
+
cursor.startParseWith(this);
|
|
1001
1097
|
const startIndex = cursor.index;
|
|
1002
1098
|
const nodes = [];
|
|
1003
1099
|
const modulo = this._hasDivider ? 2 : 1;
|
|
@@ -1032,16 +1128,19 @@ class FiniteRepeat {
|
|
|
1032
1128
|
const lastIndex = cursor.index;
|
|
1033
1129
|
cursor.moveTo(startIndex);
|
|
1034
1130
|
cursor.recordErrorAt(startIndex, lastIndex, this);
|
|
1131
|
+
cursor.endParse();
|
|
1035
1132
|
return null;
|
|
1036
1133
|
}
|
|
1037
1134
|
else if (nodes.length === 0) {
|
|
1038
1135
|
cursor.resolveError();
|
|
1039
1136
|
cursor.moveTo(startIndex);
|
|
1137
|
+
cursor.endParse();
|
|
1040
1138
|
return null;
|
|
1041
1139
|
}
|
|
1042
1140
|
const firstIndex = nodes[0].firstIndex;
|
|
1043
1141
|
const lastIndex = nodes[nodes.length - 1].lastIndex;
|
|
1044
1142
|
cursor.moveTo(lastIndex);
|
|
1143
|
+
cursor.endParse();
|
|
1045
1144
|
return new Node(this._type, this.name, firstIndex, lastIndex, nodes);
|
|
1046
1145
|
}
|
|
1047
1146
|
test(text) {
|
|
@@ -1049,8 +1148,9 @@ class FiniteRepeat {
|
|
|
1049
1148
|
const ast = this.parse(cursor);
|
|
1050
1149
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1051
1150
|
}
|
|
1052
|
-
exec(text) {
|
|
1151
|
+
exec(text, record = false) {
|
|
1053
1152
|
const cursor = new Cursor(text);
|
|
1153
|
+
record && cursor.startRecording();
|
|
1054
1154
|
const ast = this.parse(cursor);
|
|
1055
1155
|
return {
|
|
1056
1156
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -1067,11 +1167,13 @@ class FiniteRepeat {
|
|
|
1067
1167
|
min = Math.max(this._min, 1);
|
|
1068
1168
|
}
|
|
1069
1169
|
}
|
|
1070
|
-
|
|
1170
|
+
const clone = new FiniteRepeat(name, this._children[0], this._max, {
|
|
1071
1171
|
divider: this._hasDivider ? this._children[1] : undefined,
|
|
1072
1172
|
min,
|
|
1073
1173
|
trimDivider: this._trimDivider
|
|
1074
1174
|
});
|
|
1175
|
+
clone._id = this._id;
|
|
1176
|
+
return clone;
|
|
1075
1177
|
}
|
|
1076
1178
|
getTokens() {
|
|
1077
1179
|
return this._children[0].getTokens();
|
|
@@ -1119,9 +1221,16 @@ class FiniteRepeat {
|
|
|
1119
1221
|
find(predicate) {
|
|
1120
1222
|
return findPattern(this, predicate);
|
|
1121
1223
|
}
|
|
1224
|
+
isEqual(pattern) {
|
|
1225
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
1226
|
+
}
|
|
1122
1227
|
}
|
|
1123
1228
|
|
|
1229
|
+
let idIndex$3 = 0;
|
|
1124
1230
|
class InfiniteRepeat {
|
|
1231
|
+
get id() {
|
|
1232
|
+
return this._id;
|
|
1233
|
+
}
|
|
1125
1234
|
get type() {
|
|
1126
1235
|
return this._type;
|
|
1127
1236
|
}
|
|
@@ -1154,6 +1263,7 @@ class InfiniteRepeat {
|
|
|
1154
1263
|
children = [pattern.clone(pattern.name, false)];
|
|
1155
1264
|
}
|
|
1156
1265
|
this._assignChildrenToParent(children);
|
|
1266
|
+
this._id = `infinite-repeat-${idIndex$3++}`;
|
|
1157
1267
|
this._type = "infinite-repeat";
|
|
1158
1268
|
this._name = name;
|
|
1159
1269
|
this._min = min;
|
|
@@ -1175,8 +1285,9 @@ class InfiniteRepeat {
|
|
|
1175
1285
|
const ast = this.parse(cursor);
|
|
1176
1286
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1177
1287
|
}
|
|
1178
|
-
exec(text) {
|
|
1288
|
+
exec(text, record = false) {
|
|
1179
1289
|
const cursor = new Cursor(text);
|
|
1290
|
+
record && cursor.startRecording();
|
|
1180
1291
|
const ast = this.parse(cursor);
|
|
1181
1292
|
return {
|
|
1182
1293
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -1184,6 +1295,7 @@ class InfiniteRepeat {
|
|
|
1184
1295
|
};
|
|
1185
1296
|
}
|
|
1186
1297
|
parse(cursor) {
|
|
1298
|
+
cursor.startParseWith(this);
|
|
1187
1299
|
this._firstIndex = cursor.index;
|
|
1188
1300
|
this._nodes = [];
|
|
1189
1301
|
const passed = this._tryToParse(cursor);
|
|
@@ -1194,12 +1306,15 @@ class InfiniteRepeat {
|
|
|
1194
1306
|
cursor.moveTo(node.lastIndex);
|
|
1195
1307
|
cursor.recordMatch(this, node);
|
|
1196
1308
|
}
|
|
1309
|
+
cursor.endParse();
|
|
1197
1310
|
return node;
|
|
1198
1311
|
}
|
|
1199
1312
|
if (this._min > 0) {
|
|
1313
|
+
cursor.endParse();
|
|
1200
1314
|
return null;
|
|
1201
1315
|
}
|
|
1202
1316
|
cursor.resolveError();
|
|
1317
|
+
cursor.endParse();
|
|
1203
1318
|
return null;
|
|
1204
1319
|
}
|
|
1205
1320
|
_meetsMin() {
|
|
@@ -1353,15 +1468,24 @@ class InfiniteRepeat {
|
|
|
1353
1468
|
min = Math.max(this._min, 1);
|
|
1354
1469
|
}
|
|
1355
1470
|
}
|
|
1356
|
-
|
|
1471
|
+
const clone = new InfiniteRepeat(name, this._pattern, {
|
|
1357
1472
|
divider: this._divider == null ? undefined : this._divider,
|
|
1358
1473
|
min: min,
|
|
1359
1474
|
trimDivider: this._trimDivider
|
|
1360
1475
|
});
|
|
1476
|
+
clone._id = this._id;
|
|
1477
|
+
return clone;
|
|
1478
|
+
}
|
|
1479
|
+
isEqual(pattern) {
|
|
1480
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
1361
1481
|
}
|
|
1362
1482
|
}
|
|
1363
1483
|
|
|
1484
|
+
let idIndex$2 = 0;
|
|
1364
1485
|
class Repeat {
|
|
1486
|
+
get id() {
|
|
1487
|
+
return this._id;
|
|
1488
|
+
}
|
|
1365
1489
|
get type() {
|
|
1366
1490
|
return this._repeatPattern.type;
|
|
1367
1491
|
}
|
|
@@ -1381,6 +1505,7 @@ class Repeat {
|
|
|
1381
1505
|
return this._repeatPattern.isOptional;
|
|
1382
1506
|
}
|
|
1383
1507
|
constructor(name, pattern, options = {}) {
|
|
1508
|
+
this._id = `repeat-${idIndex$2++}`;
|
|
1384
1509
|
this._pattern = pattern;
|
|
1385
1510
|
this._parent = null;
|
|
1386
1511
|
this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
|
|
@@ -1412,7 +1537,9 @@ class Repeat {
|
|
|
1412
1537
|
min = Math.max(this._options.min, 1);
|
|
1413
1538
|
}
|
|
1414
1539
|
}
|
|
1415
|
-
|
|
1540
|
+
const clone = new Repeat(name, this._pattern, Object.assign(Object.assign({}, this._options), { min }));
|
|
1541
|
+
clone._id = this._id;
|
|
1542
|
+
return clone;
|
|
1416
1543
|
}
|
|
1417
1544
|
getTokens() {
|
|
1418
1545
|
return this._repeatPattern.getTokens();
|
|
@@ -1447,6 +1574,9 @@ class Repeat {
|
|
|
1447
1574
|
find(predicate) {
|
|
1448
1575
|
return this._repeatPattern.find(predicate);
|
|
1449
1576
|
}
|
|
1577
|
+
isEqual(pattern) {
|
|
1578
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
1579
|
+
}
|
|
1450
1580
|
}
|
|
1451
1581
|
|
|
1452
1582
|
const comment = new Regex("comment", "#[^\r\n]+");
|
|
@@ -1461,7 +1591,11 @@ function filterOutNull(nodes) {
|
|
|
1461
1591
|
return filteredNodes;
|
|
1462
1592
|
}
|
|
1463
1593
|
|
|
1594
|
+
let idIndex$1 = 0;
|
|
1464
1595
|
class And {
|
|
1596
|
+
get id() {
|
|
1597
|
+
return this._id;
|
|
1598
|
+
}
|
|
1465
1599
|
get type() {
|
|
1466
1600
|
return this._type;
|
|
1467
1601
|
}
|
|
@@ -1486,6 +1620,7 @@ class And {
|
|
|
1486
1620
|
}
|
|
1487
1621
|
const children = clonePatterns(sequence);
|
|
1488
1622
|
this._assignChildrenToParent(children);
|
|
1623
|
+
this._id = `and-${idIndex$1++}`;
|
|
1489
1624
|
this._type = "and";
|
|
1490
1625
|
this._name = name;
|
|
1491
1626
|
this._isOptional = isOptional;
|
|
@@ -1504,8 +1639,9 @@ class And {
|
|
|
1504
1639
|
const ast = this.parse(cursor);
|
|
1505
1640
|
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
1506
1641
|
}
|
|
1507
|
-
exec(text) {
|
|
1642
|
+
exec(text, record = false) {
|
|
1508
1643
|
const cursor = new Cursor(text);
|
|
1644
|
+
record && cursor.startRecording();
|
|
1509
1645
|
const ast = this.parse(cursor);
|
|
1510
1646
|
return {
|
|
1511
1647
|
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
@@ -1513,6 +1649,7 @@ class And {
|
|
|
1513
1649
|
};
|
|
1514
1650
|
}
|
|
1515
1651
|
parse(cursor) {
|
|
1652
|
+
cursor.startParseWith(this);
|
|
1516
1653
|
this._firstIndex = cursor.index;
|
|
1517
1654
|
this._nodes = [];
|
|
1518
1655
|
const passed = this.tryToParse(cursor);
|
|
@@ -1521,11 +1658,13 @@ class And {
|
|
|
1521
1658
|
if (node !== null) {
|
|
1522
1659
|
cursor.recordMatch(this, node);
|
|
1523
1660
|
}
|
|
1661
|
+
cursor.endParse();
|
|
1524
1662
|
return node;
|
|
1525
1663
|
}
|
|
1526
1664
|
if (this._isOptional) {
|
|
1527
1665
|
cursor.resolveError();
|
|
1528
1666
|
}
|
|
1667
|
+
cursor.endParse();
|
|
1529
1668
|
return null;
|
|
1530
1669
|
}
|
|
1531
1670
|
tryToParse(cursor) {
|
|
@@ -1684,11 +1823,16 @@ class And {
|
|
|
1684
1823
|
return findPattern(this, predicate);
|
|
1685
1824
|
}
|
|
1686
1825
|
clone(name = this._name, isOptional = this._isOptional) {
|
|
1687
|
-
|
|
1826
|
+
const clone = new And(name, this._children, isOptional);
|
|
1827
|
+
clone._id = this._id;
|
|
1828
|
+
return clone;
|
|
1829
|
+
}
|
|
1830
|
+
isEqual(pattern) {
|
|
1831
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
1688
1832
|
}
|
|
1689
1833
|
}
|
|
1690
1834
|
|
|
1691
|
-
const literal = new Regex("literal", '"(
|
|
1835
|
+
const literal = new Regex("literal", '"(?:\\\\.|[^"\\\\])*"');
|
|
1692
1836
|
|
|
1693
1837
|
const tabs$1 = new Regex("tabs", "\\t+");
|
|
1694
1838
|
const spaces$1 = new Regex("spaces", "[ ]+");
|
|
@@ -1701,34 +1845,45 @@ const allSpaces = new Regex("all-spaces", "\\s+", true);
|
|
|
1701
1845
|
|
|
1702
1846
|
const name$1 = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
|
|
1703
1847
|
|
|
1704
|
-
const
|
|
1705
|
-
const optionalIsOptional = new Literal("is-optional", "?", true);
|
|
1706
|
-
const patternName$1 = name$1.clone("pattern-name");
|
|
1707
|
-
const pattern = new And("pattern", [
|
|
1708
|
-
optionalNot,
|
|
1709
|
-
patternName$1,
|
|
1710
|
-
optionalIsOptional,
|
|
1711
|
-
]);
|
|
1712
|
-
|
|
1713
|
-
const divider$1 = new Regex("and-divider", "\\s*[&]\\s*");
|
|
1714
|
-
divider$1.setTokens([" & "]);
|
|
1715
|
-
const andLiteral = new Repeat("and-literal", pattern, { divider: divider$1, min: 2, trimDivider: true });
|
|
1848
|
+
const regexLiteral = new Regex("regex-literal", "/(\\\\/|[^/\\n\\r])*/");
|
|
1716
1849
|
|
|
1717
|
-
const
|
|
1718
|
-
|
|
1719
|
-
|
|
1850
|
+
const patternName$3 = name$1.clone("pattern-name");
|
|
1851
|
+
const anonymousLiterals = new Or("anonymous-literals", [
|
|
1852
|
+
literal,
|
|
1853
|
+
regexLiteral,
|
|
1854
|
+
patternName$3,
|
|
1855
|
+
new Reference("repeat-literal"),
|
|
1856
|
+
]);
|
|
1857
|
+
const anonymousWrappedLiterals = new Or("anonymous-wrapped-literals", [
|
|
1858
|
+
new Reference("or-literal"),
|
|
1859
|
+
new Reference("and-literal"),
|
|
1860
|
+
new Reference("complex-anonymous-pattern")
|
|
1861
|
+
]);
|
|
1720
1862
|
|
|
1721
|
-
const
|
|
1863
|
+
const inlinePatternOpenParen = new Literal("anonymous-pattern-open-paren", "(");
|
|
1864
|
+
const inlinePatternCloseParen = new Literal("anonymous-pattern-close-paren", ")");
|
|
1865
|
+
const optionalLineSpaces$1 = lineSpaces$1.clone(undefined, true);
|
|
1866
|
+
const complexAnonymousPattern = new And("complex-anonymous-pattern", [
|
|
1867
|
+
inlinePatternOpenParen,
|
|
1868
|
+
optionalLineSpaces$1,
|
|
1869
|
+
anonymousWrappedLiterals,
|
|
1870
|
+
optionalLineSpaces$1,
|
|
1871
|
+
inlinePatternCloseParen,
|
|
1872
|
+
]);
|
|
1873
|
+
const anonymousPattern = new Or("anonymous-pattern", [
|
|
1874
|
+
anonymousLiterals,
|
|
1875
|
+
complexAnonymousPattern
|
|
1876
|
+
]);
|
|
1722
1877
|
|
|
1723
|
-
const patternName = name$1.clone("pattern-name");
|
|
1724
1878
|
const optionalSpaces$2 = spaces$1.clone("optional-spaces", true);
|
|
1725
|
-
const dividerPattern = name$1.clone("divider-pattern");
|
|
1726
1879
|
const openBracket$1 = new Literal("open-bracket", "{");
|
|
1727
1880
|
const closeBracket$1 = new Literal("close-bracket", "}");
|
|
1728
1881
|
const comma = new Literal("comma", ",");
|
|
1729
1882
|
const integer = new Regex("integer", "([1-9][0-9]*)|0");
|
|
1730
1883
|
integer.setTokens(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
|
|
1731
1884
|
const optionalInteger = integer.clone("integer", true);
|
|
1885
|
+
const trimKeyword = new Literal("trim-keyword", "trim", true);
|
|
1886
|
+
const trimFlag = new And("trim-flag", [lineSpaces$1, trimKeyword], true);
|
|
1732
1887
|
const bounds = new And("bounds", [
|
|
1733
1888
|
openBracket$1,
|
|
1734
1889
|
optionalSpaces$2,
|
|
@@ -1737,7 +1892,6 @@ const bounds = new And("bounds", [
|
|
|
1737
1892
|
comma,
|
|
1738
1893
|
optionalSpaces$2,
|
|
1739
1894
|
optionalInteger.clone("max"),
|
|
1740
|
-
optionalSpaces$2,
|
|
1741
1895
|
closeBracket$1
|
|
1742
1896
|
]);
|
|
1743
1897
|
const exactCount = new And("exact-count", [
|
|
@@ -1754,41 +1908,67 @@ const quantifier = new Or("quantifier", [
|
|
|
1754
1908
|
exactCount,
|
|
1755
1909
|
bounds
|
|
1756
1910
|
]);
|
|
1757
|
-
const
|
|
1758
|
-
const
|
|
1759
|
-
const openParen = new Literal("open-paren", "(");
|
|
1760
|
-
const closeParen = new Literal("close-paren", ")");
|
|
1911
|
+
const openParen = new Literal("repeat-open-paren", "(");
|
|
1912
|
+
const closeParen = new Literal("repeat-close-paren", ")");
|
|
1761
1913
|
const dividerComma = new Regex("divider-comma", "\\s*,\\s*");
|
|
1762
1914
|
dividerComma.setTokens([", "]);
|
|
1915
|
+
const patternName$2 = name$1.clone("pattern-name");
|
|
1916
|
+
const patterns$3 = new Or("or-patterns", [patternName$2, anonymousPattern]);
|
|
1917
|
+
const dividerPattern = patterns$3.clone("divider-pattern");
|
|
1763
1918
|
const repeatLiteral = new And("repeat-literal", [
|
|
1764
1919
|
openParen,
|
|
1765
1920
|
optionalSpaces$2,
|
|
1766
|
-
|
|
1767
|
-
optional,
|
|
1768
|
-
new And("optional-divider-section", [dividerComma, dividerPattern], true),
|
|
1921
|
+
patterns$3,
|
|
1922
|
+
new And("optional-divider-section", [dividerComma, dividerPattern, trimFlag], true),
|
|
1769
1923
|
optionalSpaces$2,
|
|
1770
1924
|
closeParen,
|
|
1771
|
-
new And("quantifier-section", [
|
|
1772
|
-
new And("optional-trim-divider-section", [spaces$1, trimDivider], true)
|
|
1925
|
+
new And("quantifier-section", [quantifier]),
|
|
1773
1926
|
]);
|
|
1774
1927
|
|
|
1775
|
-
const
|
|
1776
|
-
const
|
|
1777
|
-
const
|
|
1928
|
+
const optionalNot = new Literal("not", "!", true);
|
|
1929
|
+
const optionalIsOptional$1 = new Literal("is-optional", "?", true);
|
|
1930
|
+
const patternName$1 = name$1.clone("pattern-name");
|
|
1931
|
+
const patterns$2 = new Or("and-patterns", [patternName$1, anonymousPattern]);
|
|
1932
|
+
const pattern$1 = new And("and-child-pattern", [
|
|
1933
|
+
optionalNot,
|
|
1934
|
+
patterns$2,
|
|
1935
|
+
optionalIsOptional$1,
|
|
1936
|
+
]);
|
|
1937
|
+
const divider$1 = new Regex("and-divider", "\\s*[+]\\s*");
|
|
1938
|
+
divider$1.setTokens([" + "]);
|
|
1939
|
+
const andLiteral = new Repeat("and-literal", pattern$1, { divider: divider$1, min: 2, trimDivider: true });
|
|
1940
|
+
|
|
1941
|
+
const patternName = name$1.clone("pattern-name");
|
|
1942
|
+
const patterns$1 = new Or("or-patterns", [patternName, anonymousPattern]);
|
|
1943
|
+
const defaultDivider = new Regex("default-divider", "\\s*[|]\\s*");
|
|
1944
|
+
const greedyDivider = new Regex("greedy-divider", "\\s*[<][|][>]\\s*");
|
|
1945
|
+
const divider = new Or("or-divider", [defaultDivider, greedyDivider]);
|
|
1946
|
+
defaultDivider.setTokens([" | "]);
|
|
1947
|
+
greedyDivider.setTokens([" <|> "]);
|
|
1948
|
+
const orLiteral = new Repeat("or-literal", patterns$1, { divider, min: 2, trimDivider: true });
|
|
1949
|
+
|
|
1950
|
+
const aliasLiteral = name$1.clone("alias-literal");
|
|
1951
|
+
const optionalIsOptional = new Literal("is-optional", "?", true);
|
|
1952
|
+
const configurableAnonymousPattern = new And("configurable-anonymous-pattern", [anonymousPattern, optionalIsOptional]);
|
|
1953
|
+
const pattern = new Or("pattern", [
|
|
1778
1954
|
literal,
|
|
1779
1955
|
regexLiteral,
|
|
1956
|
+
repeatLiteral,
|
|
1957
|
+
aliasLiteral,
|
|
1780
1958
|
orLiteral,
|
|
1781
1959
|
andLiteral,
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1960
|
+
configurableAnonymousPattern,
|
|
1961
|
+
], false, true);
|
|
1962
|
+
|
|
1963
|
+
const optionalSpaces$1 = spaces$1.clone("optional-spaces", true);
|
|
1964
|
+
const assignOperator = new Literal("assign-operator", "=");
|
|
1785
1965
|
const assignStatement = new And("assign-statement", [
|
|
1786
1966
|
optionalSpaces$1,
|
|
1787
1967
|
name$1,
|
|
1788
1968
|
optionalSpaces$1,
|
|
1789
1969
|
assignOperator,
|
|
1790
1970
|
optionalSpaces$1,
|
|
1791
|
-
|
|
1971
|
+
pattern
|
|
1792
1972
|
]);
|
|
1793
1973
|
const statement = new Or("statement", [assignStatement, name$1.clone("export-name")]);
|
|
1794
1974
|
|
|
@@ -1883,7 +2063,11 @@ const grammar = new And("grammar", [
|
|
|
1883
2063
|
allSpaces
|
|
1884
2064
|
]);
|
|
1885
2065
|
|
|
2066
|
+
let idIndex = 0;
|
|
1886
2067
|
class Not {
|
|
2068
|
+
get id() {
|
|
2069
|
+
return this._id;
|
|
2070
|
+
}
|
|
1887
2071
|
get type() {
|
|
1888
2072
|
return this._type;
|
|
1889
2073
|
}
|
|
@@ -1903,6 +2087,7 @@ class Not {
|
|
|
1903
2087
|
return false;
|
|
1904
2088
|
}
|
|
1905
2089
|
constructor(name, pattern) {
|
|
2090
|
+
this._id = `not-${idIndex++}`;
|
|
1906
2091
|
this._type = "not";
|
|
1907
2092
|
this._name = name;
|
|
1908
2093
|
this._parent = null;
|
|
@@ -1914,15 +2099,17 @@ class Not {
|
|
|
1914
2099
|
this.parse(cursor);
|
|
1915
2100
|
return !cursor.hasError;
|
|
1916
2101
|
}
|
|
1917
|
-
exec(text) {
|
|
2102
|
+
exec(text, record = false) {
|
|
1918
2103
|
const cursor = new Cursor(text);
|
|
2104
|
+
record && cursor.startRecording();
|
|
1919
2105
|
const ast = this.parse(cursor);
|
|
1920
2106
|
return {
|
|
1921
|
-
ast,
|
|
2107
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
1922
2108
|
cursor
|
|
1923
2109
|
};
|
|
1924
2110
|
}
|
|
1925
2111
|
parse(cursor) {
|
|
2112
|
+
cursor.startParseWith(this);
|
|
1926
2113
|
const firstIndex = cursor.index;
|
|
1927
2114
|
this._children[0].parse(cursor);
|
|
1928
2115
|
if (cursor.hasError) {
|
|
@@ -1934,10 +2121,12 @@ class Not {
|
|
|
1934
2121
|
cursor.resolveError();
|
|
1935
2122
|
cursor.recordErrorAt(firstIndex, firstIndex, this);
|
|
1936
2123
|
}
|
|
2124
|
+
cursor.endParse();
|
|
1937
2125
|
return null;
|
|
1938
2126
|
}
|
|
1939
2127
|
clone(name = this._name) {
|
|
1940
2128
|
const not = new Not(name, this._children[0]);
|
|
2129
|
+
not._id = this._id;
|
|
1941
2130
|
return not;
|
|
1942
2131
|
}
|
|
1943
2132
|
getTokens() {
|
|
@@ -1979,6 +2168,9 @@ class Not {
|
|
|
1979
2168
|
find(predicate) {
|
|
1980
2169
|
return predicate(this._children[0]) ? this._children[0] : null;
|
|
1981
2170
|
}
|
|
2171
|
+
isEqual(pattern) {
|
|
2172
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
2173
|
+
}
|
|
1982
2174
|
}
|
|
1983
2175
|
|
|
1984
2176
|
const defaultOptions = { greedyPatternNames: [], customTokens: {} };
|
|
@@ -2183,6 +2375,16 @@ function getFurthestOptions(options) {
|
|
|
2183
2375
|
return furthestOptions;
|
|
2184
2376
|
}
|
|
2185
2377
|
|
|
2378
|
+
let anonymousIndexId = 0;
|
|
2379
|
+
const patternNodes = {
|
|
2380
|
+
"literal": true,
|
|
2381
|
+
"regex-literal": true,
|
|
2382
|
+
"or-literal": true,
|
|
2383
|
+
"and-literal": true,
|
|
2384
|
+
"repeat-literal": true,
|
|
2385
|
+
"alias-literal": true,
|
|
2386
|
+
"configurable-anonymous-pattern": true
|
|
2387
|
+
};
|
|
2186
2388
|
class ParseContext {
|
|
2187
2389
|
constructor(params) {
|
|
2188
2390
|
this.patternsByName = new Map();
|
|
@@ -2227,7 +2429,7 @@ class Grammar {
|
|
|
2227
2429
|
const ast = this._tryToParse(expression);
|
|
2228
2430
|
yield this._resolveImports(ast);
|
|
2229
2431
|
this._buildPatterns(ast);
|
|
2230
|
-
return this._parseContext.patternsByName;
|
|
2432
|
+
return Object.fromEntries(this._parseContext.patternsByName);
|
|
2231
2433
|
});
|
|
2232
2434
|
}
|
|
2233
2435
|
parseString(expression) {
|
|
@@ -2237,7 +2439,7 @@ class Grammar {
|
|
|
2237
2439
|
throw new Error("Cannot use imports on parseString, use parse instead.");
|
|
2238
2440
|
}
|
|
2239
2441
|
this._buildPatterns(ast);
|
|
2240
|
-
return this._parseContext.patternsByName;
|
|
2442
|
+
return Object.fromEntries(this._parseContext.patternsByName);
|
|
2241
2443
|
}
|
|
2242
2444
|
_tryToParse(expression) {
|
|
2243
2445
|
const { ast, cursor, options, isComplete } = this._autoComplete.suggestFor(expression);
|
|
@@ -2267,41 +2469,207 @@ class Grammar {
|
|
|
2267
2469
|
if (body == null) {
|
|
2268
2470
|
return;
|
|
2269
2471
|
}
|
|
2270
|
-
body.findAll(n => n.name === "assign-statement"
|
|
2271
|
-
const
|
|
2272
|
-
|
|
2273
|
-
|
|
2472
|
+
body.findAll(n => n.name === "assign-statement").forEach((n) => {
|
|
2473
|
+
const patternNode = n.children.find(n => patternNodes[n.name] != null);
|
|
2474
|
+
if (patternNode == null) {
|
|
2475
|
+
return;
|
|
2476
|
+
}
|
|
2477
|
+
switch (patternNode.name) {
|
|
2274
2478
|
case "literal": {
|
|
2275
|
-
this.
|
|
2479
|
+
this._saveLiteral(n);
|
|
2276
2480
|
break;
|
|
2277
2481
|
}
|
|
2278
2482
|
case "regex-literal": {
|
|
2279
|
-
this.
|
|
2483
|
+
this._saveRegex(n);
|
|
2280
2484
|
break;
|
|
2281
2485
|
}
|
|
2282
2486
|
case "or-literal": {
|
|
2283
|
-
this.
|
|
2487
|
+
this._saveOr(n);
|
|
2284
2488
|
break;
|
|
2285
2489
|
}
|
|
2286
2490
|
case "and-literal": {
|
|
2287
|
-
this.
|
|
2491
|
+
this._saveAnd(n);
|
|
2288
2492
|
break;
|
|
2289
2493
|
}
|
|
2290
2494
|
case "repeat-literal": {
|
|
2291
|
-
this.
|
|
2495
|
+
this._saveRepeat(n);
|
|
2292
2496
|
break;
|
|
2293
2497
|
}
|
|
2294
2498
|
case "alias-literal": {
|
|
2295
|
-
this.
|
|
2499
|
+
this._saveAlias(n);
|
|
2296
2500
|
break;
|
|
2297
2501
|
}
|
|
2298
|
-
case "
|
|
2299
|
-
|
|
2300
|
-
this._parseContext.patternsByName.set(n.value, pattern);
|
|
2502
|
+
case "configurable-anonymous-pattern": {
|
|
2503
|
+
this._saveConfigurableAnonymous(n);
|
|
2301
2504
|
break;
|
|
2302
2505
|
}
|
|
2303
2506
|
}
|
|
2304
2507
|
});
|
|
2508
|
+
body.findAll(n => n.name === "export-name").forEach((n) => {
|
|
2509
|
+
const pattern = this._getPattern(n.value).clone();
|
|
2510
|
+
this._parseContext.patternsByName.set(n.value, pattern);
|
|
2511
|
+
});
|
|
2512
|
+
}
|
|
2513
|
+
_saveLiteral(statementNode) {
|
|
2514
|
+
const nameNode = statementNode.find(n => n.name === "name");
|
|
2515
|
+
const literalNode = statementNode.find(n => n.name === "literal");
|
|
2516
|
+
const name = nameNode.value;
|
|
2517
|
+
const literal = this._buildLiteral(name, literalNode);
|
|
2518
|
+
this._parseContext.patternsByName.set(name, literal);
|
|
2519
|
+
}
|
|
2520
|
+
_buildLiteral(name, node) {
|
|
2521
|
+
return new Literal(name, this._resolveStringValue(node.value));
|
|
2522
|
+
}
|
|
2523
|
+
_resolveStringValue(value) {
|
|
2524
|
+
return value.replace(/\\n/g, '\n')
|
|
2525
|
+
.replace(/\\r/g, '\r')
|
|
2526
|
+
.replace(/\\t/g, '\t')
|
|
2527
|
+
.replace(/\\b/g, '\b')
|
|
2528
|
+
.replace(/\\f/g, '\f')
|
|
2529
|
+
.replace(/\\v/g, '\v')
|
|
2530
|
+
.replace(/\\0/g, '\0')
|
|
2531
|
+
.replace(/\\x([0-9A-Fa-f]{2})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
|
|
2532
|
+
.replace(/\\u([0-9A-Fa-f]{4})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
|
|
2533
|
+
.replace(/\\(.)/g, '$1').slice(1, -1);
|
|
2534
|
+
}
|
|
2535
|
+
_saveRegex(statementNode) {
|
|
2536
|
+
const nameNode = statementNode.find(n => n.name === "name");
|
|
2537
|
+
const regexNode = statementNode.find(n => n.name === "regex-literal");
|
|
2538
|
+
const name = nameNode.value;
|
|
2539
|
+
const regex = this._buildRegex(name, regexNode);
|
|
2540
|
+
this._parseContext.patternsByName.set(name, regex);
|
|
2541
|
+
}
|
|
2542
|
+
_buildRegex(name, node) {
|
|
2543
|
+
const value = node.value.slice(1, node.value.length - 1);
|
|
2544
|
+
return new Regex(name, value);
|
|
2545
|
+
}
|
|
2546
|
+
_saveOr(statementNode) {
|
|
2547
|
+
const nameNode = statementNode.find(n => n.name === "name");
|
|
2548
|
+
const name = nameNode.value;
|
|
2549
|
+
const orNode = statementNode.find(n => n.name === "or-literal");
|
|
2550
|
+
const or = this._buildOr(name, orNode);
|
|
2551
|
+
this._parseContext.patternsByName.set(name, or);
|
|
2552
|
+
}
|
|
2553
|
+
_buildOr(name, node) {
|
|
2554
|
+
const patternNodes = node.children.filter(n => n.name !== "default-divider" && n.name !== "greedy-divider");
|
|
2555
|
+
const isGreedy = node.find(n => n.name === "greedy-divider") != null;
|
|
2556
|
+
const patterns = patternNodes.map(n => this._buildPattern(n));
|
|
2557
|
+
const or = new Or(name, patterns, false, isGreedy);
|
|
2558
|
+
return or;
|
|
2559
|
+
}
|
|
2560
|
+
_buildPattern(node) {
|
|
2561
|
+
const type = node.name;
|
|
2562
|
+
const name = `anonymous-pattern-${anonymousIndexId++}`;
|
|
2563
|
+
switch (type) {
|
|
2564
|
+
case "pattern-name": {
|
|
2565
|
+
return this._getPattern(node.value).clone();
|
|
2566
|
+
}
|
|
2567
|
+
case "literal": {
|
|
2568
|
+
return this._buildLiteral(node.value.slice(1, -1), node);
|
|
2569
|
+
}
|
|
2570
|
+
case "regex-literal": {
|
|
2571
|
+
return this._buildRegex(node.value.slice(1, -1), node);
|
|
2572
|
+
}
|
|
2573
|
+
case "repeat-literal": {
|
|
2574
|
+
return this._buildRepeat(name, node);
|
|
2575
|
+
}
|
|
2576
|
+
case "or-literal": {
|
|
2577
|
+
return this._buildOr(name, node);
|
|
2578
|
+
}
|
|
2579
|
+
case "and-literal": {
|
|
2580
|
+
return this._buildAnd(name, node);
|
|
2581
|
+
}
|
|
2582
|
+
case "complex-anonymous-pattern": {
|
|
2583
|
+
return this._buildComplexAnonymousPattern(node);
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
throw new Error(`Couldn't build node: ${node.name}.`);
|
|
2587
|
+
}
|
|
2588
|
+
_saveAnd(statementNode) {
|
|
2589
|
+
const nameNode = statementNode.find(n => n.name === "name");
|
|
2590
|
+
const name = nameNode.value;
|
|
2591
|
+
const andNode = statementNode.find(n => n.name === "and-literal");
|
|
2592
|
+
const and = this._buildAnd(name, andNode);
|
|
2593
|
+
this._parseContext.patternsByName.set(name, and);
|
|
2594
|
+
}
|
|
2595
|
+
_buildAnd(name, node) {
|
|
2596
|
+
const patternNodes = node.children.filter(n => n.name !== "and-divider");
|
|
2597
|
+
const patterns = patternNodes.map(n => {
|
|
2598
|
+
const patternNode = n.children[0].name === "not" ? n.children[1] : n.children[0];
|
|
2599
|
+
const isNot = n.find(n => n.name === "not") != null;
|
|
2600
|
+
const isOptional = n.find(n => n.name === "is-optional");
|
|
2601
|
+
const pattern = this._buildPattern(patternNode).clone(undefined, isOptional == null ? undefined : true);
|
|
2602
|
+
if (isNot) {
|
|
2603
|
+
return new Not(`not-${pattern.name}`, pattern);
|
|
2604
|
+
}
|
|
2605
|
+
return pattern;
|
|
2606
|
+
});
|
|
2607
|
+
return new And(name, patterns);
|
|
2608
|
+
}
|
|
2609
|
+
_saveRepeat(statementNode) {
|
|
2610
|
+
const nameNode = statementNode.find(n => n.name === "name");
|
|
2611
|
+
const name = nameNode.value;
|
|
2612
|
+
const repeatNode = statementNode.find(n => n.name === "repeat-literal");
|
|
2613
|
+
const repeat = this._buildRepeat(name, repeatNode);
|
|
2614
|
+
this._parseContext.patternsByName.set(name, repeat);
|
|
2615
|
+
}
|
|
2616
|
+
_buildRepeat(name, repeatNode) {
|
|
2617
|
+
const bounds = repeatNode.find(n => n.name === "bounds");
|
|
2618
|
+
const exactCount = repeatNode.find(n => n.name === "exact-count");
|
|
2619
|
+
const quantifier = repeatNode.find(n => n.name === "quantifier-shorthand");
|
|
2620
|
+
const trimDivider = repeatNode.find(n => n.name === "trim-flag") != null;
|
|
2621
|
+
const patterNode = repeatNode.children[1].type === "optional-spaces" ? repeatNode.children[2] : repeatNode.children[1];
|
|
2622
|
+
const pattern = this._buildPattern(patterNode);
|
|
2623
|
+
const dividerSectionNode = repeatNode.find(n => n.name === "optional-divider-section");
|
|
2624
|
+
const options = {
|
|
2625
|
+
min: 1,
|
|
2626
|
+
max: Infinity
|
|
2627
|
+
};
|
|
2628
|
+
if (trimDivider) {
|
|
2629
|
+
options.trimDivider = trimDivider;
|
|
2630
|
+
}
|
|
2631
|
+
if (dividerSectionNode != null) {
|
|
2632
|
+
const dividerNode = dividerSectionNode.children[1];
|
|
2633
|
+
options.divider = this._buildPattern(dividerNode);
|
|
2634
|
+
}
|
|
2635
|
+
if (bounds != null) {
|
|
2636
|
+
const minNode = bounds.find(p => p.name === "min");
|
|
2637
|
+
const maxNode = bounds.find(p => p.name === "max");
|
|
2638
|
+
const min = minNode == null ? 0 : Number(minNode.value);
|
|
2639
|
+
const max = maxNode == null ? Infinity : Number(maxNode.value);
|
|
2640
|
+
options.min = min;
|
|
2641
|
+
options.max = max;
|
|
2642
|
+
}
|
|
2643
|
+
else if (exactCount != null) {
|
|
2644
|
+
const integerNode = exactCount.find(p => p.name === "integer");
|
|
2645
|
+
const integer = Number(integerNode.value);
|
|
2646
|
+
options.min = integer;
|
|
2647
|
+
options.max = integer;
|
|
2648
|
+
}
|
|
2649
|
+
else if (quantifier != null) {
|
|
2650
|
+
const type = quantifier.value;
|
|
2651
|
+
if (type === "+") {
|
|
2652
|
+
options.min = 1;
|
|
2653
|
+
options.max = Infinity;
|
|
2654
|
+
}
|
|
2655
|
+
else {
|
|
2656
|
+
options.min = 0;
|
|
2657
|
+
options.max = Infinity;
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
return new Repeat(name, pattern.clone(pattern.name), options);
|
|
2661
|
+
}
|
|
2662
|
+
_saveConfigurableAnonymous(node) {
|
|
2663
|
+
const nameNode = node.find(n => n.name === "name");
|
|
2664
|
+
const name = nameNode.value;
|
|
2665
|
+
const anonymousNode = node.find(n => n.name === "complex-anonymous-pattern");
|
|
2666
|
+
const isOptional = node.children[1] != null;
|
|
2667
|
+
const anonymous = this._buildPattern(anonymousNode).clone(name, isOptional);
|
|
2668
|
+
this._parseContext.patternsByName.set(name, anonymous);
|
|
2669
|
+
}
|
|
2670
|
+
_buildComplexAnonymousPattern(node) {
|
|
2671
|
+
const wrappedNode = node.children[1].name === "line-spaces" ? node.children[2] : node.children[1];
|
|
2672
|
+
return this._buildPattern(wrappedNode);
|
|
2305
2673
|
}
|
|
2306
2674
|
_resolveImports(ast) {
|
|
2307
2675
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -2330,7 +2698,7 @@ class Grammar {
|
|
|
2330
2698
|
if (parseContext.importedPatternsByName.has(importName)) {
|
|
2331
2699
|
throw new Error(`'${importName}' was already used within another import.`);
|
|
2332
2700
|
}
|
|
2333
|
-
const pattern = patterns
|
|
2701
|
+
const pattern = patterns[importName];
|
|
2334
2702
|
if (pattern == null) {
|
|
2335
2703
|
throw new Error(`Couldn't find pattern with name: ${importName}, from import: ${resource}.`);
|
|
2336
2704
|
}
|
|
@@ -2344,7 +2712,7 @@ class Grammar {
|
|
|
2344
2712
|
if (parseContext.importedPatternsByName.has(alias)) {
|
|
2345
2713
|
throw new Error(`'${alias}' was already used within another import.`);
|
|
2346
2714
|
}
|
|
2347
|
-
const pattern = patterns
|
|
2715
|
+
const pattern = patterns[importName];
|
|
2348
2716
|
if (pattern == null) {
|
|
2349
2717
|
throw new Error(`Couldn't find pattern with name: ${importName}, from import: ${resource}.`);
|
|
2350
2718
|
}
|
|
@@ -2375,48 +2743,11 @@ class Grammar {
|
|
|
2375
2743
|
resolveImport: this._resolveImport
|
|
2376
2744
|
});
|
|
2377
2745
|
const patterns = grammar.parseString(expression);
|
|
2378
|
-
params = Array.from(
|
|
2746
|
+
params = Array.from(Object.values(patterns));
|
|
2379
2747
|
}
|
|
2380
2748
|
}
|
|
2381
2749
|
return params;
|
|
2382
2750
|
}
|
|
2383
|
-
_buildLiteral(statementNode) {
|
|
2384
|
-
const nameNode = statementNode.find(n => n.name === "name");
|
|
2385
|
-
const literalNode = statementNode.find(n => n.name === "literal");
|
|
2386
|
-
const name = nameNode.value;
|
|
2387
|
-
const value = this._resolveStringValue(literalNode.value.slice(1, -1));
|
|
2388
|
-
const literal = new Literal(name, value);
|
|
2389
|
-
this._parseContext.patternsByName.set(name, literal);
|
|
2390
|
-
}
|
|
2391
|
-
_resolveStringValue(value) {
|
|
2392
|
-
return value.replace(/\\n/g, '\n')
|
|
2393
|
-
.replace(/\\r/g, '\r')
|
|
2394
|
-
.replace(/\\t/g, '\t')
|
|
2395
|
-
.replace(/\\b/g, '\b')
|
|
2396
|
-
.replace(/\\f/g, '\f')
|
|
2397
|
-
.replace(/\\v/g, '\v')
|
|
2398
|
-
.replace(/\\0/g, '\0')
|
|
2399
|
-
.replace(/\\x([0-9A-Fa-f]{2})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
|
|
2400
|
-
.replace(/\\u([0-9A-Fa-f]{4})/g, (_, hex) => String.fromCharCode(parseInt(hex, 16)))
|
|
2401
|
-
.replace(/\\(.)/g, '$1');
|
|
2402
|
-
}
|
|
2403
|
-
_buildRegex(statementNode) {
|
|
2404
|
-
const nameNode = statementNode.find(n => n.name === "name");
|
|
2405
|
-
const regexNode = statementNode.find(n => n.name === "regex-literal");
|
|
2406
|
-
const value = regexNode.value.slice(1, regexNode.value.length - 1);
|
|
2407
|
-
const name = nameNode.value;
|
|
2408
|
-
const regex = new Regex(name, value);
|
|
2409
|
-
this._parseContext.patternsByName.set(name, regex);
|
|
2410
|
-
}
|
|
2411
|
-
_buildOr(statementNode) {
|
|
2412
|
-
const nameNode = statementNode.find(n => n.name === "name");
|
|
2413
|
-
const orNode = statementNode.find(n => n.name === "or-literal");
|
|
2414
|
-
const patternNodes = orNode.children.filter(n => n.name === "pattern-name");
|
|
2415
|
-
const name = nameNode.value;
|
|
2416
|
-
const patterns = patternNodes.map(n => this._getPattern(n.value));
|
|
2417
|
-
const or = new Or(name, patterns, false, true);
|
|
2418
|
-
this._parseContext.patternsByName.set(name, or);
|
|
2419
|
-
}
|
|
2420
2751
|
_getPattern(name) {
|
|
2421
2752
|
let pattern = this._parseContext.patternsByName.get(name);
|
|
2422
2753
|
if (pattern == null) {
|
|
@@ -2430,82 +2761,12 @@ class Grammar {
|
|
|
2430
2761
|
}
|
|
2431
2762
|
return pattern;
|
|
2432
2763
|
}
|
|
2433
|
-
|
|
2434
|
-
const nameNode = statementNode.find(n => n.name === "name");
|
|
2435
|
-
const andNode = statementNode.find(n => n.name === "and-literal");
|
|
2436
|
-
const patternNodes = andNode.children.filter(n => n.name === "pattern");
|
|
2437
|
-
const name = nameNode.value;
|
|
2438
|
-
const patterns = patternNodes.map(n => {
|
|
2439
|
-
const nameNode = n.find(n => n.name === "pattern-name");
|
|
2440
|
-
const isNot = n.find(n => n.name === "not") != null;
|
|
2441
|
-
const isOptional = n.find(n => n.name === "is-optional") != null;
|
|
2442
|
-
const name = nameNode.value;
|
|
2443
|
-
const pattern = this._getPattern(name);
|
|
2444
|
-
if (isNot) {
|
|
2445
|
-
return new Not(`not-${name}`, pattern.clone(name, isOptional));
|
|
2446
|
-
}
|
|
2447
|
-
return pattern.clone(name, isOptional);
|
|
2448
|
-
});
|
|
2449
|
-
const and = new And(name, patterns);
|
|
2450
|
-
this._parseContext.patternsByName.set(name, and);
|
|
2451
|
-
}
|
|
2452
|
-
_buildRepeat(statementNode) {
|
|
2453
|
-
const nameNode = statementNode.find(n => n.name === "name");
|
|
2454
|
-
const repeatNode = statementNode.find(n => n.name === "repeat-literal");
|
|
2455
|
-
const patternNameNode = statementNode.find(n => n.name === "pattern-name");
|
|
2456
|
-
const dividerNode = repeatNode.find(n => n.name === "divider-pattern");
|
|
2457
|
-
const bounds = repeatNode.find(n => n.name === "bounds");
|
|
2458
|
-
const exactCount = repeatNode.find(n => n.name === "exact-count");
|
|
2459
|
-
const quantifier = repeatNode.find(n => n.name === "quantifier-shorthand");
|
|
2460
|
-
const isPatternOptional = repeatNode.find(n => n.name === "is-optional") != null;
|
|
2461
|
-
const trimDivider = repeatNode.find(n => n.name === "trim-divider") != null;
|
|
2462
|
-
const name = nameNode.value;
|
|
2463
|
-
const pattern = this._getPattern(patternNameNode.value);
|
|
2464
|
-
const options = {
|
|
2465
|
-
min: 1,
|
|
2466
|
-
max: Infinity
|
|
2467
|
-
};
|
|
2468
|
-
if (trimDivider) {
|
|
2469
|
-
options.trimDivider = trimDivider;
|
|
2470
|
-
}
|
|
2471
|
-
if (dividerNode != null) {
|
|
2472
|
-
options.divider = this._getPattern(dividerNode.value);
|
|
2473
|
-
}
|
|
2474
|
-
if (bounds != null) {
|
|
2475
|
-
const minNode = bounds.find(p => p.name === "min");
|
|
2476
|
-
const maxNode = bounds.find(p => p.name === "max");
|
|
2477
|
-
const min = minNode == null ? 0 : Number(minNode.value);
|
|
2478
|
-
const max = maxNode == null ? Infinity : Number(maxNode.value);
|
|
2479
|
-
options.min = min;
|
|
2480
|
-
options.max = max;
|
|
2481
|
-
}
|
|
2482
|
-
else if (exactCount != null) {
|
|
2483
|
-
const integerNode = exactCount.find(p => p.name === "integer");
|
|
2484
|
-
const integer = Number(integerNode.value);
|
|
2485
|
-
options.min = integer;
|
|
2486
|
-
options.max = integer;
|
|
2487
|
-
}
|
|
2488
|
-
else if (quantifier != null) {
|
|
2489
|
-
const type = quantifier.value;
|
|
2490
|
-
if (type === "+") {
|
|
2491
|
-
options.min = 1;
|
|
2492
|
-
options.max = Infinity;
|
|
2493
|
-
}
|
|
2494
|
-
else {
|
|
2495
|
-
options.min = 0;
|
|
2496
|
-
options.max = Infinity;
|
|
2497
|
-
}
|
|
2498
|
-
}
|
|
2499
|
-
const repeat = new Repeat(name, pattern.clone(pattern.name, isPatternOptional), options);
|
|
2500
|
-
this._parseContext.patternsByName.set(name, repeat);
|
|
2501
|
-
}
|
|
2502
|
-
_buildAlias(statementNode) {
|
|
2764
|
+
_saveAlias(statementNode) {
|
|
2503
2765
|
const nameNode = statementNode.find(n => n.name === "name");
|
|
2504
2766
|
const aliasNode = statementNode.find(n => n.name === "alias-literal");
|
|
2505
2767
|
const aliasName = aliasNode.value;
|
|
2506
2768
|
const name = nameNode.value;
|
|
2507
|
-
const
|
|
2508
|
-
const alias = pattern.clone(name);
|
|
2769
|
+
const alias = this._getPattern(aliasName).clone(name);
|
|
2509
2770
|
this._parseContext.patternsByName.set(name, alias);
|
|
2510
2771
|
}
|
|
2511
2772
|
static parse(expression, options) {
|
|
@@ -2522,6 +2783,30 @@ class Grammar {
|
|
|
2522
2783
|
}
|
|
2523
2784
|
}
|
|
2524
2785
|
|
|
2786
|
+
function arePatternsEqual(a, b) {
|
|
2787
|
+
if (a === b) {
|
|
2788
|
+
return true;
|
|
2789
|
+
}
|
|
2790
|
+
else if (a == null || b == null) {
|
|
2791
|
+
return false;
|
|
2792
|
+
}
|
|
2793
|
+
return a.isEqual(b);
|
|
2794
|
+
}
|
|
2795
|
+
|
|
2796
|
+
const kebabRegex = /-([a-z])/g; // Define the regex once
|
|
2797
|
+
function kebabToCamelCase(str) {
|
|
2798
|
+
return str.replace(kebabRegex, (_, char) => char.toUpperCase());
|
|
2799
|
+
}
|
|
2800
|
+
function patterns(strings, ...values) {
|
|
2801
|
+
const combinedString = strings.reduce((result, str, i) => result + str + (values[i] || ''), '');
|
|
2802
|
+
const result = {};
|
|
2803
|
+
const patterns = Grammar.parseString(combinedString);
|
|
2804
|
+
Object.keys(patterns).forEach(k => {
|
|
2805
|
+
result[kebabToCamelCase(k)] = patterns[k];
|
|
2806
|
+
});
|
|
2807
|
+
return result;
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2525
2810
|
exports.And = And;
|
|
2526
2811
|
exports.AutoComplete = AutoComplete;
|
|
2527
2812
|
exports.Cursor = Cursor;
|
|
@@ -2535,5 +2820,7 @@ exports.ParseError = ParseError;
|
|
|
2535
2820
|
exports.Reference = Reference;
|
|
2536
2821
|
exports.Regex = Regex;
|
|
2537
2822
|
exports.Repeat = Repeat;
|
|
2823
|
+
exports.arePatternsEqual = arePatternsEqual;
|
|
2538
2824
|
exports.grammar = grammar;
|
|
2825
|
+
exports.patterns = patterns;
|
|
2539
2826
|
//# sourceMappingURL=index.js.map
|