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