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