clarity-pattern-parser 10.1.26 → 10.2.1

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/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$1 = new 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$1.incrementDepth(this._id, this._firstIndex);
1041
+ depthCache$2.incrementDepth(this._id, this._firstIndex);
1033
1042
  this._firstIndex = cursor.index;
1034
1043
  const node = this._tryToParse(cursor);
1035
- depthCache$1.decrementDepth(this._id, this._firstIndex);
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$1.getDepth(this._id, this._firstIndex) > 2) {
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,387 @@ 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
+ let ancestor = lastBinaryNode.parent;
2932
+ let root = lastBinaryNode;
2933
+ while (ancestor != null) {
2934
+ const nodePrecedence = this._precedenceMap[ancestor.name];
2935
+ if (nodePrecedence > precedence) {
2936
+ break;
2937
+ }
2938
+ root = ancestor;
2939
+ ancestor = ancestor.parent;
2940
+ }
2941
+ lastBinaryNode.appendChild(lastUnaryNode);
2942
+ if (root != null) {
2943
+ const node = createNode(name, []);
2944
+ root.replaceWith(node);
2945
+ node.append(root, delimiterNode);
2946
+ lastBinaryNode = node;
2947
+ }
2948
+ else {
2949
+ const node = createNode(name, [lastUnaryNode, delimiterNode]);
2950
+ lastBinaryNode = node;
2951
+ }
2952
+ }
2953
+ else {
2954
+ const node = createNode(name, [lastUnaryNode, delimiterNode]);
2955
+ lastBinaryNode.appendChild(node);
2956
+ lastBinaryNode = node;
2957
+ }
2958
+ }
2959
+ if (cursor.hasNext()) {
2960
+ cursor.next();
2961
+ }
2962
+ else {
2963
+ break outer;
2964
+ }
2965
+ break;
2966
+ }
2967
+ if (lastBinaryNode == null) {
2968
+ break;
2969
+ }
2970
+ }
2971
+ if (lastBinaryNode == null) {
2972
+ return lastUnaryNode;
2973
+ }
2974
+ else {
2975
+ const root = lastBinaryNode.findAncestor(n => n.parent == null) || lastBinaryNode;
2976
+ if (lastBinaryNode.children.length < 3) {
2977
+ lastBinaryNode.remove();
2978
+ if (lastBinaryNode === root) {
2979
+ return lastUnaryNode;
2980
+ }
2981
+ }
2982
+ root.normalize(this._firstIndex);
2983
+ return root;
2984
+ }
2985
+ }
2986
+ test(text) {
2987
+ const cursor = new Cursor(text);
2988
+ const ast = this.parse(cursor);
2989
+ return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
2990
+ }
2991
+ exec(text, record = false) {
2992
+ const cursor = new Cursor(text);
2993
+ record && cursor.startRecording();
2994
+ const ast = this.parse(cursor);
2995
+ return {
2996
+ ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
2997
+ cursor
2998
+ };
2999
+ }
3000
+ getTokens() {
3001
+ return this.unaryPatterns.map(p => p.getTokens()).flat();
3002
+ }
3003
+ getTokensAfter(childReference) {
3004
+ if (this.unaryPatterns.indexOf(childReference)) {
3005
+ const recursiveTokens = this._recursivePatterns.map(p => p.getTokens()).flat();
3006
+ const binaryTokens = this._binaryPatterns.map(p => p.getTokens()).flat();
3007
+ return [...recursiveTokens, ...binaryTokens];
3008
+ }
3009
+ if (this.recursivePatterns.indexOf(childReference)) {
3010
+ return this._binaryPatterns.map(p => p.getTokens()).flat();
3011
+ }
3012
+ if (this.binaryPatterns.indexOf(childReference)) {
3013
+ const unaryTokens = this._unaryPatterns.map(p => p.getTokens()).flat();
3014
+ if (this._parent != null) {
3015
+ const nextTokens = this._parent.getTokensAfter(this);
3016
+ return [...unaryTokens, ...nextTokens];
3017
+ }
3018
+ return unaryTokens;
3019
+ }
3020
+ return [];
3021
+ }
3022
+ getNextTokens() {
3023
+ if (this._parent == null) {
3024
+ return [];
3025
+ }
3026
+ return this._parent.getTokensAfter(this);
3027
+ }
3028
+ getPatterns() {
3029
+ return this.unaryPatterns.map(p => p.getPatterns()).flat();
3030
+ }
3031
+ getPatternsAfter(childReference) {
3032
+ if (this.unaryPatterns.indexOf(childReference)) {
3033
+ const recursivePatterns = this._recursivePatterns.map(p => p.getPatterns()).flat();
3034
+ const binaryPatterns = this._binaryPatterns.map(p => p.getPatterns()).flat();
3035
+ return [...recursivePatterns, ...binaryPatterns];
3036
+ }
3037
+ if (this.recursivePatterns.indexOf(childReference)) {
3038
+ return this._binaryPatterns.map(p => p.getPatterns()).flat();
3039
+ }
3040
+ if (this.binaryPatterns.indexOf(childReference)) {
3041
+ const unaryPatterns = this._unaryPatterns.map(p => p.getPatterns()).flat();
3042
+ if (this._parent != null) {
3043
+ const nextPatterns = this._parent.getPatternsAfter(this);
3044
+ return [...unaryPatterns, ...nextPatterns];
3045
+ }
3046
+ return unaryPatterns;
3047
+ }
3048
+ return [];
3049
+ }
3050
+ getNextPatterns() {
3051
+ if (this._parent == null) {
3052
+ return [];
3053
+ }
3054
+ return this._parent.getPatternsAfter(this);
3055
+ }
3056
+ find(predicate) {
3057
+ return findPattern(this, predicate);
3058
+ }
3059
+ clone(name = this._name) {
3060
+ const clone = new ExpressionPattern(name, this._originalPatterns);
3061
+ clone._id = this._id;
3062
+ return clone;
3063
+ }
3064
+ isEqual(pattern) {
3065
+ return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
3066
+ }
3067
+ }
3068
+
2680
3069
  let anonymousIndexId = 0;
2681
3070
  const patternNodes = {
2682
3071
  "literal": true,
@@ -2859,9 +3248,29 @@ class Grammar {
2859
3248
  const patternNodes = node.children.filter(n => n.name !== "default-divider" && n.name !== "greedy-divider");
2860
3249
  const isGreedy = node.find(n => n.name === "greedy-divider") != null;
2861
3250
  const patterns = patternNodes.map(n => this._buildPattern(n));
3251
+ const hasRecursivePattern = patterns.some(p => this._isRecursive(name, p));
3252
+ if (hasRecursivePattern && !isGreedy) {
3253
+ try {
3254
+ const expression = new ExpressionPattern(name, patterns);
3255
+ return expression;
3256
+ }
3257
+ catch (_a) { }
3258
+ }
2862
3259
  const or = new Options(name, patterns, isGreedy);
2863
3260
  return or;
2864
3261
  }
3262
+ _isRecursive(name, pattern) {
3263
+ if (pattern.type === "right-associated" && this._isRecursivePattern(name, pattern.children[0])) {
3264
+ return true;
3265
+ }
3266
+ return this._isRecursivePattern(name, pattern);
3267
+ }
3268
+ _isRecursivePattern(name, pattern) {
3269
+ return pattern.type === "sequence" &&
3270
+ pattern.children[0].type === "reference" &&
3271
+ pattern.children[0].name === name &&
3272
+ pattern.children.length > 2;
3273
+ }
2865
3274
  _buildPattern(node) {
2866
3275
  const type = node.name;
2867
3276
  const name = `anonymous-pattern-${anonymousIndexId++}`;
@@ -3107,6 +3516,7 @@ exports.AutoComplete = AutoComplete;
3107
3516
  exports.Context = Context;
3108
3517
  exports.Cursor = Cursor;
3109
3518
  exports.CursorHistory = CursorHistory;
3519
+ exports.ExpressionPattern = ExpressionPattern;
3110
3520
  exports.Grammar = Grammar;
3111
3521
  exports.Literal = Literal;
3112
3522
  exports.Node = Node;