clarity-pattern-parser 10.1.26 → 10.2.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/dist/ast/Node.d.ts +1 -0
- package/dist/grammar/Grammar.d.ts +2 -0
- package/dist/index.browser.js +409 -10
- package/dist/index.browser.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.esm.js +409 -11
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +409 -10
- package/dist/index.js.map +1 -1
- package/dist/patterns/ExpressionPattern.d.ts +51 -0
- package/package.json +1 -1
- package/src/ast/Node.ts +12 -1
- package/src/grammar/Grammar.test.ts +15 -0
- package/src/grammar/Grammar.ts +25 -1
- package/src/index.ts +2 -0
- package/src/patterns/ExpressionPattern.test.ts +132 -0
- package/src/patterns/ExpressionPattern.ts +283 -57
- package/src/patterns/Options.ts +0 -1
- package/src/patterns/RightAssociatedPattern.ts +29 -11
package/dist/ast/Node.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ export declare class Node {
|
|
|
38
38
|
nextSibling(): Node | null;
|
|
39
39
|
previousSibling(): Node | null;
|
|
40
40
|
find(predicate: (node: Node) => boolean): Node | null;
|
|
41
|
+
findRoot(): Node;
|
|
41
42
|
findAll(predicate: (node: Node) => boolean): Node[];
|
|
42
43
|
findAncestor(predicate: (node: Node) => boolean): Node | null;
|
|
43
44
|
walkUp(callback: (node: Node) => void): void;
|
package/dist/index.browser.js
CHANGED
|
@@ -126,6 +126,15 @@
|
|
|
126
126
|
find(predicate) {
|
|
127
127
|
return this.findAll(predicate)[0] || null;
|
|
128
128
|
}
|
|
129
|
+
findRoot() {
|
|
130
|
+
let pattern = this;
|
|
131
|
+
while (true) {
|
|
132
|
+
if (pattern.parent == null) {
|
|
133
|
+
return pattern;
|
|
134
|
+
}
|
|
135
|
+
pattern = pattern.parent;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
129
138
|
findAll(predicate) {
|
|
130
139
|
const matches = [];
|
|
131
140
|
this.walkUp(n => {
|
|
@@ -200,7 +209,7 @@
|
|
|
200
209
|
length = this._value.length;
|
|
201
210
|
}
|
|
202
211
|
else {
|
|
203
|
-
length = this.children.reduce((acc, c) => acc + c.normalize(acc + startIndex), startIndex);
|
|
212
|
+
length = this.children.reduce((acc, c) => acc + c.normalize(acc + startIndex), startIndex) - startIndex;
|
|
204
213
|
}
|
|
205
214
|
this._firstIndex = startIndex;
|
|
206
215
|
this._lastIndex = Math.max(startIndex + length - 1, 0);
|
|
@@ -974,7 +983,7 @@
|
|
|
974
983
|
/*
|
|
975
984
|
The following is created to reduce the overhead of recursion check.
|
|
976
985
|
*/
|
|
977
|
-
const depthCache$
|
|
986
|
+
const depthCache$2 = new DepthCache();
|
|
978
987
|
let idIndex$6 = 0;
|
|
979
988
|
class Options {
|
|
980
989
|
get id() {
|
|
@@ -1031,10 +1040,10 @@
|
|
|
1031
1040
|
parse(cursor) {
|
|
1032
1041
|
// This is a cache to help with speed
|
|
1033
1042
|
this._firstIndex = cursor.index;
|
|
1034
|
-
depthCache$
|
|
1043
|
+
depthCache$2.incrementDepth(this._id, this._firstIndex);
|
|
1035
1044
|
this._firstIndex = cursor.index;
|
|
1036
1045
|
const node = this._tryToParse(cursor);
|
|
1037
|
-
depthCache$
|
|
1046
|
+
depthCache$2.decrementDepth(this._id, this._firstIndex);
|
|
1038
1047
|
if (node != null) {
|
|
1039
1048
|
cursor.moveTo(node.lastIndex);
|
|
1040
1049
|
cursor.resolveError();
|
|
@@ -1044,8 +1053,7 @@
|
|
|
1044
1053
|
return null;
|
|
1045
1054
|
}
|
|
1046
1055
|
_tryToParse(cursor) {
|
|
1047
|
-
if (depthCache$
|
|
1048
|
-
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
1056
|
+
if (depthCache$2.getDepth(this._id, this._firstIndex) > 2) {
|
|
1049
1057
|
return null;
|
|
1050
1058
|
}
|
|
1051
1059
|
const results = [];
|
|
@@ -1663,7 +1671,7 @@
|
|
|
1663
1671
|
return filteredNodes;
|
|
1664
1672
|
}
|
|
1665
1673
|
|
|
1666
|
-
const depthCache = new DepthCache();
|
|
1674
|
+
const depthCache$1 = new DepthCache();
|
|
1667
1675
|
let idIndex$2 = 0;
|
|
1668
1676
|
class Sequence {
|
|
1669
1677
|
get id() {
|
|
@@ -1720,10 +1728,10 @@
|
|
|
1720
1728
|
parse(cursor) {
|
|
1721
1729
|
// This is a cache to help with speed
|
|
1722
1730
|
this._firstIndex = cursor.index;
|
|
1723
|
-
depthCache.incrementDepth(this._id, this._firstIndex);
|
|
1731
|
+
depthCache$1.incrementDepth(this._id, this._firstIndex);
|
|
1724
1732
|
this._nodes = [];
|
|
1725
1733
|
const passed = this.tryToParse(cursor);
|
|
1726
|
-
depthCache.decrementDepth(this._id, this._firstIndex);
|
|
1734
|
+
depthCache$1.decrementDepth(this._id, this._firstIndex);
|
|
1727
1735
|
if (passed) {
|
|
1728
1736
|
const node = this.createNode(cursor);
|
|
1729
1737
|
if (node !== null) {
|
|
@@ -1734,7 +1742,7 @@
|
|
|
1734
1742
|
return null;
|
|
1735
1743
|
}
|
|
1736
1744
|
tryToParse(cursor) {
|
|
1737
|
-
if (depthCache.getDepth(this._id, this._firstIndex) > 1) {
|
|
1745
|
+
if (depthCache$1.getDepth(this._id, this._firstIndex) > 1) {
|
|
1738
1746
|
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
1739
1747
|
return false;
|
|
1740
1748
|
}
|
|
@@ -2679,6 +2687,376 @@
|
|
|
2679
2687
|
}
|
|
2680
2688
|
}
|
|
2681
2689
|
|
|
2690
|
+
let indexId = 0;
|
|
2691
|
+
const depthCache = new DepthCache();
|
|
2692
|
+
function createNode(name, children) {
|
|
2693
|
+
return new Node("expression", name, 0, 0, children, "");
|
|
2694
|
+
}
|
|
2695
|
+
var Association;
|
|
2696
|
+
(function (Association) {
|
|
2697
|
+
Association[Association["left"] = 0] = "left";
|
|
2698
|
+
Association[Association["right"] = 1] = "right";
|
|
2699
|
+
})(Association || (Association = {}));
|
|
2700
|
+
class ExpressionPattern {
|
|
2701
|
+
get id() {
|
|
2702
|
+
return this._id;
|
|
2703
|
+
}
|
|
2704
|
+
get type() {
|
|
2705
|
+
return this._type;
|
|
2706
|
+
}
|
|
2707
|
+
get name() {
|
|
2708
|
+
return this._name;
|
|
2709
|
+
}
|
|
2710
|
+
get parent() {
|
|
2711
|
+
return this._parent;
|
|
2712
|
+
}
|
|
2713
|
+
set parent(pattern) {
|
|
2714
|
+
this._parent = pattern;
|
|
2715
|
+
}
|
|
2716
|
+
get children() {
|
|
2717
|
+
return this._patterns;
|
|
2718
|
+
}
|
|
2719
|
+
get unaryPatterns() {
|
|
2720
|
+
return this._unaryPatterns;
|
|
2721
|
+
}
|
|
2722
|
+
get binaryPatterns() {
|
|
2723
|
+
return this._binaryPatterns;
|
|
2724
|
+
}
|
|
2725
|
+
get recursivePatterns() {
|
|
2726
|
+
return this._recursivePatterns;
|
|
2727
|
+
}
|
|
2728
|
+
constructor(name, patterns) {
|
|
2729
|
+
if (patterns.length === 0) {
|
|
2730
|
+
throw new Error("Need at least one pattern with an 'expression' pattern.");
|
|
2731
|
+
}
|
|
2732
|
+
this._id = `expression-${indexId++}`;
|
|
2733
|
+
this._type = "expression";
|
|
2734
|
+
this._name = name;
|
|
2735
|
+
this._parent = null;
|
|
2736
|
+
this._firstIndex = -1;
|
|
2737
|
+
this._unaryPatterns = [];
|
|
2738
|
+
this._binaryPatterns = [];
|
|
2739
|
+
this._recursivePatterns = [];
|
|
2740
|
+
this._recursiveNames = [];
|
|
2741
|
+
this._binaryNames = [];
|
|
2742
|
+
this._binaryAssociation = [];
|
|
2743
|
+
this._precedenceMap = {};
|
|
2744
|
+
this._originalPatterns = patterns;
|
|
2745
|
+
this._patterns = this._organizePatterns(patterns);
|
|
2746
|
+
if (this._unaryPatterns.length === 0) {
|
|
2747
|
+
throw new Error("Need at least one operand pattern with an 'expression' pattern.");
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2750
|
+
_organizePatterns(patterns) {
|
|
2751
|
+
const finalPatterns = [];
|
|
2752
|
+
patterns.forEach((pattern) => {
|
|
2753
|
+
if (this._isBinary(pattern)) {
|
|
2754
|
+
const binaryName = this._extractName(pattern);
|
|
2755
|
+
const clone = this._extractDelimiter(pattern).clone();
|
|
2756
|
+
clone.parent = this;
|
|
2757
|
+
this._precedenceMap[binaryName] = this._binaryPatterns.length;
|
|
2758
|
+
this._binaryPatterns.push(clone);
|
|
2759
|
+
this._binaryNames.push(binaryName);
|
|
2760
|
+
if (pattern.type === "right-associated") {
|
|
2761
|
+
this._binaryAssociation.push(Association.right);
|
|
2762
|
+
}
|
|
2763
|
+
else {
|
|
2764
|
+
this._binaryAssociation.push(Association.left);
|
|
2765
|
+
}
|
|
2766
|
+
finalPatterns.push(clone);
|
|
2767
|
+
}
|
|
2768
|
+
else if (this._isRecursive(pattern)) {
|
|
2769
|
+
const name = this._extractName(pattern);
|
|
2770
|
+
const tail = this._extractRecursiveTail(pattern);
|
|
2771
|
+
tail.parent = this;
|
|
2772
|
+
this._recursivePatterns.push(tail);
|
|
2773
|
+
this._recursiveNames.push(name);
|
|
2774
|
+
finalPatterns.push(tail);
|
|
2775
|
+
}
|
|
2776
|
+
else {
|
|
2777
|
+
const clone = pattern.clone();
|
|
2778
|
+
clone.parent = this;
|
|
2779
|
+
this._unaryPatterns.push(clone);
|
|
2780
|
+
finalPatterns.push(clone);
|
|
2781
|
+
}
|
|
2782
|
+
});
|
|
2783
|
+
return finalPatterns;
|
|
2784
|
+
}
|
|
2785
|
+
_isBinary(pattern) {
|
|
2786
|
+
if (pattern.type === "right-associated" && this._isBinaryPattern(pattern.children[0])) {
|
|
2787
|
+
return true;
|
|
2788
|
+
}
|
|
2789
|
+
return this._isBinaryPattern(pattern);
|
|
2790
|
+
}
|
|
2791
|
+
_isBinaryPattern(pattern) {
|
|
2792
|
+
return pattern.type === "sequence" &&
|
|
2793
|
+
pattern.children[0].type === "reference" &&
|
|
2794
|
+
pattern.children[0].name === this.name &&
|
|
2795
|
+
pattern.children[2].type === "reference" &&
|
|
2796
|
+
pattern.children[2].name === this.name &&
|
|
2797
|
+
pattern.children.length === 3;
|
|
2798
|
+
}
|
|
2799
|
+
_extractDelimiter(pattern) {
|
|
2800
|
+
if (pattern.type === "right-associated") {
|
|
2801
|
+
return pattern.children[0].children[1];
|
|
2802
|
+
}
|
|
2803
|
+
return pattern.children[1];
|
|
2804
|
+
}
|
|
2805
|
+
_extractName(pattern) {
|
|
2806
|
+
if (pattern.type === "right-associated") {
|
|
2807
|
+
return pattern.children[0].name;
|
|
2808
|
+
}
|
|
2809
|
+
return pattern.name;
|
|
2810
|
+
}
|
|
2811
|
+
_isRecursive(pattern) {
|
|
2812
|
+
if (pattern.type === "right-associated" && this._isRecursivePattern(pattern.children[0])) {
|
|
2813
|
+
return true;
|
|
2814
|
+
}
|
|
2815
|
+
return this._isRecursivePattern(pattern);
|
|
2816
|
+
}
|
|
2817
|
+
_isRecursivePattern(pattern) {
|
|
2818
|
+
return pattern.type === "sequence" &&
|
|
2819
|
+
pattern.children[0].type === "reference" &&
|
|
2820
|
+
pattern.children[0].name === this.name &&
|
|
2821
|
+
pattern.children.length > 2;
|
|
2822
|
+
}
|
|
2823
|
+
_extractRecursiveTail(pattern) {
|
|
2824
|
+
if (pattern.type === "right-associated") {
|
|
2825
|
+
return new Sequence(`${pattern.children[0].name}-tail`, pattern.children[0].children.slice(1));
|
|
2826
|
+
}
|
|
2827
|
+
return new Sequence(`${pattern.name}-tail`, pattern.children.slice(1));
|
|
2828
|
+
}
|
|
2829
|
+
parse(cursor) {
|
|
2830
|
+
// This is a cache to help with speed
|
|
2831
|
+
this._firstIndex = cursor.index;
|
|
2832
|
+
depthCache.incrementDepth(this._id, this._firstIndex);
|
|
2833
|
+
this._firstIndex = cursor.index;
|
|
2834
|
+
const node = this._tryToParse(cursor);
|
|
2835
|
+
depthCache.decrementDepth(this._id, this._firstIndex);
|
|
2836
|
+
if (node != null) {
|
|
2837
|
+
cursor.moveTo(node.lastIndex);
|
|
2838
|
+
cursor.resolveError();
|
|
2839
|
+
return node;
|
|
2840
|
+
}
|
|
2841
|
+
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
2842
|
+
return null;
|
|
2843
|
+
}
|
|
2844
|
+
_tryToParse(cursor) {
|
|
2845
|
+
if (depthCache.getDepth(this._id, this._firstIndex) > 2) {
|
|
2846
|
+
cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
|
|
2847
|
+
return null;
|
|
2848
|
+
}
|
|
2849
|
+
let lastUnaryNode = null;
|
|
2850
|
+
let lastBinaryNode = null;
|
|
2851
|
+
let onIndex = cursor.index;
|
|
2852
|
+
outer: while (true) {
|
|
2853
|
+
onIndex = cursor.index;
|
|
2854
|
+
for (let i = 0; i < this._unaryPatterns.length; i++) {
|
|
2855
|
+
cursor.moveTo(onIndex);
|
|
2856
|
+
const pattern = this._unaryPatterns[i];
|
|
2857
|
+
const node = pattern.parse(cursor);
|
|
2858
|
+
if (node != null) {
|
|
2859
|
+
lastUnaryNode = node;
|
|
2860
|
+
break;
|
|
2861
|
+
}
|
|
2862
|
+
else {
|
|
2863
|
+
lastUnaryNode = null;
|
|
2864
|
+
cursor.resolveError();
|
|
2865
|
+
}
|
|
2866
|
+
}
|
|
2867
|
+
if (lastUnaryNode == null) {
|
|
2868
|
+
break;
|
|
2869
|
+
}
|
|
2870
|
+
if (cursor.hasNext()) {
|
|
2871
|
+
cursor.next();
|
|
2872
|
+
}
|
|
2873
|
+
else {
|
|
2874
|
+
if (lastBinaryNode != null && lastUnaryNode != null) {
|
|
2875
|
+
lastBinaryNode.appendChild(lastUnaryNode);
|
|
2876
|
+
}
|
|
2877
|
+
break;
|
|
2878
|
+
}
|
|
2879
|
+
onIndex = cursor.index;
|
|
2880
|
+
for (let i = 0; i < this._recursivePatterns.length; i++) {
|
|
2881
|
+
const pattern = this._recursivePatterns[i];
|
|
2882
|
+
const node = pattern.parse(cursor);
|
|
2883
|
+
if (node != null) {
|
|
2884
|
+
if (lastBinaryNode != null && lastUnaryNode != null) {
|
|
2885
|
+
lastBinaryNode.appendChild(lastUnaryNode);
|
|
2886
|
+
}
|
|
2887
|
+
const frontExpression = lastBinaryNode == null ? lastUnaryNode : lastBinaryNode.findRoot();
|
|
2888
|
+
const name = this._recursiveNames[i];
|
|
2889
|
+
const recursiveNode = createNode(name, [frontExpression, ...node.children]);
|
|
2890
|
+
recursiveNode.normalize(this._firstIndex);
|
|
2891
|
+
return recursiveNode;
|
|
2892
|
+
}
|
|
2893
|
+
cursor.moveTo(onIndex);
|
|
2894
|
+
}
|
|
2895
|
+
onIndex = cursor.index;
|
|
2896
|
+
for (let i = 0; i < this._binaryPatterns.length; i++) {
|
|
2897
|
+
cursor.moveTo(onIndex);
|
|
2898
|
+
const pattern = this._binaryPatterns[i];
|
|
2899
|
+
const name = this._binaryNames[i];
|
|
2900
|
+
const delimiterNode = pattern.parse(cursor);
|
|
2901
|
+
if (delimiterNode == null) {
|
|
2902
|
+
if (i === this._binaryPatterns.length - 1) {
|
|
2903
|
+
if (lastBinaryNode == null) {
|
|
2904
|
+
return lastUnaryNode;
|
|
2905
|
+
}
|
|
2906
|
+
else if (lastUnaryNode != null) {
|
|
2907
|
+
lastBinaryNode.appendChild(lastUnaryNode);
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
continue;
|
|
2911
|
+
}
|
|
2912
|
+
if (lastBinaryNode == null && lastUnaryNode != null && delimiterNode != null) {
|
|
2913
|
+
const node = createNode(name, [lastUnaryNode, delimiterNode]);
|
|
2914
|
+
lastBinaryNode = node;
|
|
2915
|
+
}
|
|
2916
|
+
else if (lastBinaryNode != null && lastUnaryNode != null && delimiterNode != null) {
|
|
2917
|
+
const precedence = this._precedenceMap[name];
|
|
2918
|
+
const lastPrecendece = lastBinaryNode == null ? 0 : this._precedenceMap[lastBinaryNode.name];
|
|
2919
|
+
const association = this._binaryAssociation[i];
|
|
2920
|
+
if (precedence === lastPrecendece && association === Association.right) {
|
|
2921
|
+
const node = createNode(name, [lastUnaryNode, delimiterNode]);
|
|
2922
|
+
lastBinaryNode.appendChild(node);
|
|
2923
|
+
lastBinaryNode = node;
|
|
2924
|
+
}
|
|
2925
|
+
else if (precedence === lastPrecendece) {
|
|
2926
|
+
const node = createNode(name, []);
|
|
2927
|
+
lastBinaryNode.replaceWith(node);
|
|
2928
|
+
lastBinaryNode.appendChild(lastUnaryNode);
|
|
2929
|
+
node.append(lastBinaryNode, delimiterNode);
|
|
2930
|
+
lastBinaryNode = node;
|
|
2931
|
+
}
|
|
2932
|
+
else if (precedence > lastPrecendece) {
|
|
2933
|
+
const root = lastBinaryNode.findRoot();
|
|
2934
|
+
lastBinaryNode.appendChild(lastUnaryNode);
|
|
2935
|
+
if (root != null) {
|
|
2936
|
+
const node = createNode(name, [root, delimiterNode]);
|
|
2937
|
+
lastBinaryNode = node;
|
|
2938
|
+
}
|
|
2939
|
+
else {
|
|
2940
|
+
const node = createNode(name, [lastUnaryNode, delimiterNode]);
|
|
2941
|
+
lastBinaryNode = node;
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
else {
|
|
2945
|
+
const node = createNode(name, [lastUnaryNode, delimiterNode]);
|
|
2946
|
+
lastBinaryNode.appendChild(node);
|
|
2947
|
+
lastBinaryNode = node;
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
if (cursor.hasNext()) {
|
|
2951
|
+
cursor.next();
|
|
2952
|
+
}
|
|
2953
|
+
else {
|
|
2954
|
+
break outer;
|
|
2955
|
+
}
|
|
2956
|
+
break;
|
|
2957
|
+
}
|
|
2958
|
+
if (lastBinaryNode == null) {
|
|
2959
|
+
break;
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
if (lastBinaryNode == null) {
|
|
2963
|
+
return lastUnaryNode;
|
|
2964
|
+
}
|
|
2965
|
+
else {
|
|
2966
|
+
const root = lastBinaryNode.findAncestor(n => n.parent == null) || lastBinaryNode;
|
|
2967
|
+
if (lastBinaryNode.children.length < 3) {
|
|
2968
|
+
lastBinaryNode.remove();
|
|
2969
|
+
if (lastBinaryNode === root) {
|
|
2970
|
+
return lastUnaryNode;
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
root.normalize(this._firstIndex);
|
|
2974
|
+
return root;
|
|
2975
|
+
}
|
|
2976
|
+
}
|
|
2977
|
+
test(text) {
|
|
2978
|
+
const cursor = new Cursor(text);
|
|
2979
|
+
const ast = this.parse(cursor);
|
|
2980
|
+
return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
|
|
2981
|
+
}
|
|
2982
|
+
exec(text, record = false) {
|
|
2983
|
+
const cursor = new Cursor(text);
|
|
2984
|
+
record && cursor.startRecording();
|
|
2985
|
+
const ast = this.parse(cursor);
|
|
2986
|
+
return {
|
|
2987
|
+
ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
|
|
2988
|
+
cursor
|
|
2989
|
+
};
|
|
2990
|
+
}
|
|
2991
|
+
getTokens() {
|
|
2992
|
+
return this.unaryPatterns.map(p => p.getTokens()).flat();
|
|
2993
|
+
}
|
|
2994
|
+
getTokensAfter(childReference) {
|
|
2995
|
+
if (this.unaryPatterns.indexOf(childReference)) {
|
|
2996
|
+
const recursiveTokens = this._recursivePatterns.map(p => p.getTokens()).flat();
|
|
2997
|
+
const binaryTokens = this._binaryPatterns.map(p => p.getTokens()).flat();
|
|
2998
|
+
return [...recursiveTokens, ...binaryTokens];
|
|
2999
|
+
}
|
|
3000
|
+
if (this.recursivePatterns.indexOf(childReference)) {
|
|
3001
|
+
return this._binaryPatterns.map(p => p.getTokens()).flat();
|
|
3002
|
+
}
|
|
3003
|
+
if (this.binaryPatterns.indexOf(childReference)) {
|
|
3004
|
+
const unaryTokens = this._unaryPatterns.map(p => p.getTokens()).flat();
|
|
3005
|
+
if (this._parent != null) {
|
|
3006
|
+
const nextTokens = this._parent.getTokensAfter(this);
|
|
3007
|
+
return [...unaryTokens, ...nextTokens];
|
|
3008
|
+
}
|
|
3009
|
+
return unaryTokens;
|
|
3010
|
+
}
|
|
3011
|
+
return [];
|
|
3012
|
+
}
|
|
3013
|
+
getNextTokens() {
|
|
3014
|
+
if (this._parent == null) {
|
|
3015
|
+
return [];
|
|
3016
|
+
}
|
|
3017
|
+
return this._parent.getTokensAfter(this);
|
|
3018
|
+
}
|
|
3019
|
+
getPatterns() {
|
|
3020
|
+
return this.unaryPatterns.map(p => p.getPatterns()).flat();
|
|
3021
|
+
}
|
|
3022
|
+
getPatternsAfter(childReference) {
|
|
3023
|
+
if (this.unaryPatterns.indexOf(childReference)) {
|
|
3024
|
+
const recursivePatterns = this._recursivePatterns.map(p => p.getPatterns()).flat();
|
|
3025
|
+
const binaryPatterns = this._binaryPatterns.map(p => p.getPatterns()).flat();
|
|
3026
|
+
return [...recursivePatterns, ...binaryPatterns];
|
|
3027
|
+
}
|
|
3028
|
+
if (this.recursivePatterns.indexOf(childReference)) {
|
|
3029
|
+
return this._binaryPatterns.map(p => p.getPatterns()).flat();
|
|
3030
|
+
}
|
|
3031
|
+
if (this.binaryPatterns.indexOf(childReference)) {
|
|
3032
|
+
const unaryPatterns = this._unaryPatterns.map(p => p.getPatterns()).flat();
|
|
3033
|
+
if (this._parent != null) {
|
|
3034
|
+
const nextPatterns = this._parent.getPatternsAfter(this);
|
|
3035
|
+
return [...unaryPatterns, ...nextPatterns];
|
|
3036
|
+
}
|
|
3037
|
+
return unaryPatterns;
|
|
3038
|
+
}
|
|
3039
|
+
return [];
|
|
3040
|
+
}
|
|
3041
|
+
getNextPatterns() {
|
|
3042
|
+
if (this._parent == null) {
|
|
3043
|
+
return [];
|
|
3044
|
+
}
|
|
3045
|
+
return this._parent.getPatternsAfter(this);
|
|
3046
|
+
}
|
|
3047
|
+
find(predicate) {
|
|
3048
|
+
return findPattern(this, predicate);
|
|
3049
|
+
}
|
|
3050
|
+
clone(name = this._name) {
|
|
3051
|
+
const clone = new ExpressionPattern(name, this._originalPatterns);
|
|
3052
|
+
clone._id = this._id;
|
|
3053
|
+
return clone;
|
|
3054
|
+
}
|
|
3055
|
+
isEqual(pattern) {
|
|
3056
|
+
return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
|
|
2682
3060
|
let anonymousIndexId = 0;
|
|
2683
3061
|
const patternNodes = {
|
|
2684
3062
|
"literal": true,
|
|
@@ -2861,9 +3239,29 @@
|
|
|
2861
3239
|
const patternNodes = node.children.filter(n => n.name !== "default-divider" && n.name !== "greedy-divider");
|
|
2862
3240
|
const isGreedy = node.find(n => n.name === "greedy-divider") != null;
|
|
2863
3241
|
const patterns = patternNodes.map(n => this._buildPattern(n));
|
|
3242
|
+
const hasRecursivePattern = patterns.some(p => this._isRecursive(name, p));
|
|
3243
|
+
if (hasRecursivePattern && !isGreedy) {
|
|
3244
|
+
try {
|
|
3245
|
+
const expression = new ExpressionPattern(name, patterns);
|
|
3246
|
+
return expression;
|
|
3247
|
+
}
|
|
3248
|
+
catch (_a) { }
|
|
3249
|
+
}
|
|
2864
3250
|
const or = new Options(name, patterns, isGreedy);
|
|
2865
3251
|
return or;
|
|
2866
3252
|
}
|
|
3253
|
+
_isRecursive(name, pattern) {
|
|
3254
|
+
if (pattern.type === "right-associated" && this._isRecursivePattern(name, pattern.children[0])) {
|
|
3255
|
+
return true;
|
|
3256
|
+
}
|
|
3257
|
+
return this._isRecursivePattern(name, pattern);
|
|
3258
|
+
}
|
|
3259
|
+
_isRecursivePattern(name, pattern) {
|
|
3260
|
+
return pattern.type === "sequence" &&
|
|
3261
|
+
pattern.children[0].type === "reference" &&
|
|
3262
|
+
pattern.children[0].name === name &&
|
|
3263
|
+
pattern.children.length > 2;
|
|
3264
|
+
}
|
|
2867
3265
|
_buildPattern(node) {
|
|
2868
3266
|
const type = node.name;
|
|
2869
3267
|
const name = `anonymous-pattern-${anonymousIndexId++}`;
|
|
@@ -3109,6 +3507,7 @@
|
|
|
3109
3507
|
exports.Context = Context;
|
|
3110
3508
|
exports.Cursor = Cursor;
|
|
3111
3509
|
exports.CursorHistory = CursorHistory;
|
|
3510
|
+
exports.ExpressionPattern = ExpressionPattern;
|
|
3112
3511
|
exports.Grammar = Grammar;
|
|
3113
3512
|
exports.Literal = Literal;
|
|
3114
3513
|
exports.Node = Node;
|