clarity-pattern-parser 10.1.25 → 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.
@@ -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;
@@ -29,6 +29,8 @@ export declare class Grammar {
29
29
  private _buildRegex;
30
30
  private _saveOptions;
31
31
  private _buildOptions;
32
+ private _isRecursive;
33
+ private _isRecursivePattern;
32
34
  private _buildPattern;
33
35
  private _saveSequence;
34
36
  private _buildSequence;
@@ -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$1 = new 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$1.incrementDepth(this._id, this._firstIndex);
1043
+ depthCache$2.incrementDepth(this._id, this._firstIndex);
1035
1044
  this._firstIndex = cursor.index;
1036
1045
  const node = this._tryToParse(cursor);
1037
- depthCache$1.decrementDepth(this._id, this._firstIndex);
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$1.getDepth(this._id, this._firstIndex) > 2) {
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 = [];
@@ -1198,7 +1206,7 @@
1198
1206
  }
1199
1207
  }
1200
1208
  if (this._trimDivider && this._hasDivider) {
1201
- const isDividerLastMatch = this.children.length > 1 && nodes[nodes.length - 1].name === this.children[1].name;
1209
+ const isDividerLastMatch = this.children.length > 1 && nodes.length > 1 && nodes[nodes.length - 1].name === this.children[1].name;
1202
1210
  if (isDividerLastMatch) {
1203
1211
  const node = nodes.pop();
1204
1212
  cursor.moveTo(node.firstIndex);
@@ -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;