clarity-pattern-parser 10.3.1 → 10.3.3

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.esm.js CHANGED
@@ -528,6 +528,9 @@ class Literal {
528
528
  get children() {
529
529
  return [];
530
530
  }
531
+ get startedOnIndex() {
532
+ return this._firstIndex;
533
+ }
531
534
  constructor(name, value) {
532
535
  this.shouldCompactAst = false;
533
536
  if (value.length === 0) {
@@ -657,10 +660,13 @@ class Regex {
657
660
  get children() {
658
661
  return [];
659
662
  }
663
+ get startedOnIndex() {
664
+ return this._firstIndex;
665
+ }
660
666
  constructor(name, regex) {
661
667
  this._node = null;
662
668
  this._cursor = null;
663
- this._firstIndex = -1;
669
+ this._firstIndex = 0;
664
670
  this._substring = "";
665
671
  this._tokens = [];
666
672
  this.shouldCompactAst = false;
@@ -813,6 +819,9 @@ class Reference {
813
819
  get children() {
814
820
  return this._children;
815
821
  }
822
+ get startedOnIndex() {
823
+ return this._firstIndex;
824
+ }
816
825
  constructor(name) {
817
826
  this.shouldCompactAst = false;
818
827
  this._id = `reference-${idIndex$7++}`;
@@ -822,6 +831,7 @@ class Reference {
822
831
  this._pattern = null;
823
832
  this._cachedPattern = null;
824
833
  this._children = [];
834
+ this._firstIndex = 0;
825
835
  }
826
836
  test(text) {
827
837
  const cursor = new Cursor(text);
@@ -838,6 +848,7 @@ class Reference {
838
848
  };
839
849
  }
840
850
  parse(cursor) {
851
+ this._firstIndex = cursor.index;
841
852
  return this.getReferencePatternSafely().parse(cursor);
842
853
  }
843
854
  getReferencePatternSafely() {
@@ -951,29 +962,6 @@ function clonePatterns(patterns) {
951
962
  return patterns.map(p => p.clone());
952
963
  }
953
964
 
954
- class DepthCache {
955
- constructor() {
956
- this._depthMap = {};
957
- }
958
- getDepth(name, cursorIndex) {
959
- if (this._depthMap[name] == null) {
960
- this._depthMap[name] = {};
961
- }
962
- if (this._depthMap[name][cursorIndex] == null) {
963
- this._depthMap[name][cursorIndex] = 0;
964
- }
965
- return this._depthMap[name][cursorIndex];
966
- }
967
- incrementDepth(name, cursorIndex) {
968
- const depth = this.getDepth(name, cursorIndex);
969
- this._depthMap[name][cursorIndex] = depth + 1;
970
- }
971
- decrementDepth(name, cursorIndex) {
972
- const depth = this.getDepth(name, cursorIndex);
973
- this._depthMap[name][cursorIndex] = depth - 1;
974
- }
975
- }
976
-
977
965
  function isRecursivePattern(pattern) {
978
966
  let onPattern = pattern.parent;
979
967
  let depth = 0;
@@ -989,10 +977,6 @@ function isRecursivePattern(pattern) {
989
977
  return false;
990
978
  }
991
979
 
992
- /*
993
- The following is created to reduce the overhead of recursion check.
994
- */
995
- const depthCache$2 = new DepthCache();
996
980
  let idIndex$6 = 0;
997
981
  class Options {
998
982
  get id() {
@@ -1013,6 +997,9 @@ class Options {
1013
997
  get children() {
1014
998
  return this._children;
1015
999
  }
1000
+ get startedOnIndex() {
1001
+ return this._firstIndex;
1002
+ }
1016
1003
  constructor(name, options, isGreedy = false) {
1017
1004
  this.shouldCompactAst = false;
1018
1005
  if (options.length === 0) {
@@ -1048,12 +1035,8 @@ class Options {
1048
1035
  };
1049
1036
  }
1050
1037
  parse(cursor) {
1051
- // This is a cache to help with speed
1052
- this._firstIndex = cursor.index;
1053
- depthCache$2.incrementDepth(this._id, this._firstIndex);
1054
1038
  this._firstIndex = cursor.index;
1055
1039
  const node = this._tryToParse(cursor);
1056
- depthCache$2.decrementDepth(this._id, this._firstIndex);
1057
1040
  if (node != null) {
1058
1041
  cursor.moveTo(node.lastIndex);
1059
1042
  cursor.resolveError();
@@ -1066,7 +1049,7 @@ class Options {
1066
1049
  return null;
1067
1050
  }
1068
1051
  _tryToParse(cursor) {
1069
- if (depthCache$2.getDepth(this._id, this._firstIndex) > 2) {
1052
+ if (this._isBeyondRecursiveAllowance()) {
1070
1053
  return null;
1071
1054
  }
1072
1055
  const results = [];
@@ -1086,6 +1069,20 @@ class Options {
1086
1069
  nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
1087
1070
  return nonNullResults[0] || null;
1088
1071
  }
1072
+ _isBeyondRecursiveAllowance() {
1073
+ let depth = 0;
1074
+ let pattern = this;
1075
+ while (pattern != null) {
1076
+ if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
1077
+ depth++;
1078
+ }
1079
+ if (depth > 2) {
1080
+ return true;
1081
+ }
1082
+ pattern = pattern.parent;
1083
+ }
1084
+ return false;
1085
+ }
1089
1086
  getTokens() {
1090
1087
  const tokens = [];
1091
1088
  for (const pattern of this._children) {
@@ -1170,6 +1167,9 @@ class FiniteRepeat {
1170
1167
  get max() {
1171
1168
  return this._max;
1172
1169
  }
1170
+ get startedOnIndex() {
1171
+ return this._firstIndex;
1172
+ }
1173
1173
  constructor(name, pattern, options = {}) {
1174
1174
  this.shouldCompactAst = false;
1175
1175
  this._id = `finite-repeat-${idIndex$5++}`;
@@ -1181,6 +1181,7 @@ class FiniteRepeat {
1181
1181
  this._min = options.min != null ? Math.max(options.min, 1) : 1;
1182
1182
  this._max = Math.max(this.min, options.max || this.min);
1183
1183
  this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
1184
+ this._firstIndex = 0;
1184
1185
  for (let i = 0; i < this._max; i++) {
1185
1186
  const child = pattern.clone();
1186
1187
  child.parent = this;
@@ -1193,6 +1194,7 @@ class FiniteRepeat {
1193
1194
  }
1194
1195
  }
1195
1196
  parse(cursor) {
1197
+ this._firstIndex = cursor.index;
1196
1198
  const startIndex = cursor.index;
1197
1199
  const nodes = [];
1198
1200
  const modulo = this._hasDivider ? 2 : 1;
@@ -1348,6 +1350,9 @@ class InfiniteRepeat {
1348
1350
  get min() {
1349
1351
  return this._min;
1350
1352
  }
1353
+ get startedOnIndex() {
1354
+ return this._firstIndex;
1355
+ }
1351
1356
  constructor(name, pattern, options = {}) {
1352
1357
  this.shouldCompactAst = false;
1353
1358
  const min = options.min != null ? Math.max(options.min, 1) : 1;
@@ -1623,6 +1628,9 @@ class Repeat {
1623
1628
  get max() {
1624
1629
  return this._options.max;
1625
1630
  }
1631
+ get startedOnIndex() {
1632
+ return this._repeatPattern.startedOnIndex;
1633
+ }
1626
1634
  constructor(name, pattern, options = {}) {
1627
1635
  this._id = `repeat-${idIndex$3++}`;
1628
1636
  this._pattern = pattern;
@@ -1705,7 +1713,6 @@ function filterOutNull(nodes) {
1705
1713
  return filteredNodes;
1706
1714
  }
1707
1715
 
1708
- const depthCache$1 = new DepthCache();
1709
1716
  let idIndex$2 = 0;
1710
1717
  class Sequence {
1711
1718
  get id() {
@@ -1726,6 +1733,9 @@ class Sequence {
1726
1733
  get children() {
1727
1734
  return this._children;
1728
1735
  }
1736
+ get startedOnIndex() {
1737
+ return this._firstIndex;
1738
+ }
1729
1739
  constructor(name, sequence) {
1730
1740
  this.shouldCompactAst = false;
1731
1741
  if (sequence.length === 0) {
@@ -1761,12 +1771,9 @@ class Sequence {
1761
1771
  };
1762
1772
  }
1763
1773
  parse(cursor) {
1764
- // This is a cache to help with speed
1765
1774
  this._firstIndex = cursor.index;
1766
- depthCache$1.incrementDepth(this._id, this._firstIndex);
1767
1775
  this._nodes = [];
1768
1776
  const passed = this.tryToParse(cursor);
1769
- depthCache$1.decrementDepth(this._id, this._firstIndex);
1770
1777
  if (passed) {
1771
1778
  const node = this.createNode(cursor);
1772
1779
  if (node !== null) {
@@ -1780,7 +1787,7 @@ class Sequence {
1780
1787
  return null;
1781
1788
  }
1782
1789
  tryToParse(cursor) {
1783
- if (depthCache$1.getDepth(this._id, this._firstIndex) > 1) {
1790
+ if (this._isBeyondRecursiveAllowance()) {
1784
1791
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
1785
1792
  return false;
1786
1793
  }
@@ -1847,6 +1854,20 @@ class Sequence {
1847
1854
  }
1848
1855
  return nodes[nodes.length - 1];
1849
1856
  }
1857
+ _isBeyondRecursiveAllowance() {
1858
+ let depth = 0;
1859
+ let pattern = this;
1860
+ while (pattern != null) {
1861
+ if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
1862
+ depth++;
1863
+ }
1864
+ if (depth > 1) {
1865
+ return true;
1866
+ }
1867
+ pattern = pattern.parent;
1868
+ }
1869
+ return false;
1870
+ }
1850
1871
  areRemainingPatternsOptional(fromIndex) {
1851
1872
  const startOnIndex = fromIndex + 1;
1852
1873
  const length = this._children.length;
@@ -2006,6 +2027,9 @@ class Optional {
2006
2027
  get children() {
2007
2028
  return this._children;
2008
2029
  }
2030
+ get startedOnIndex() {
2031
+ return this._children[0].startedOnIndex;
2032
+ }
2009
2033
  constructor(name, pattern) {
2010
2034
  this.shouldCompactAst = false;
2011
2035
  this._id = `optional-${idIndex$1++}`;
@@ -2327,6 +2351,9 @@ class Not {
2327
2351
  get children() {
2328
2352
  return this._children;
2329
2353
  }
2354
+ get startedOnIndex() {
2355
+ return this.children[0].startedOnIndex;
2356
+ }
2330
2357
  constructor(name, pattern) {
2331
2358
  this.shouldCompactAst = false;
2332
2359
  this._id = `not-${idIndex++}`;
@@ -2666,6 +2693,9 @@ class Context {
2666
2693
  get children() {
2667
2694
  return this._children;
2668
2695
  }
2696
+ get startedOnIndex() {
2697
+ return this.children[0].startedOnIndex;
2698
+ }
2669
2699
  getPatternWithinContext(name) {
2670
2700
  return this._patterns[name] || null;
2671
2701
  }
@@ -2739,7 +2769,6 @@ class Context {
2739
2769
  }
2740
2770
 
2741
2771
  let indexId = 0;
2742
- const depthCache = new DepthCache();
2743
2772
  function createNode(name, children) {
2744
2773
  return new Node("expression", name, 0, 0, children, "");
2745
2774
  }
@@ -2768,7 +2797,7 @@ class ExpressionPattern {
2768
2797
  return this._patterns;
2769
2798
  }
2770
2799
  get unaryPatterns() {
2771
- return this._unaryPatterns;
2800
+ return this._atomPatterns;
2772
2801
  }
2773
2802
  get binaryPatterns() {
2774
2803
  return this._binaryPatterns;
@@ -2776,6 +2805,9 @@ class ExpressionPattern {
2776
2805
  get recursivePatterns() {
2777
2806
  return this._recursivePatterns;
2778
2807
  }
2808
+ get startedOnIndex() {
2809
+ return this._firstIndex;
2810
+ }
2779
2811
  constructor(name, patterns) {
2780
2812
  this.shouldCompactAst = false;
2781
2813
  if (patterns.length === 0) {
@@ -2786,7 +2818,9 @@ class ExpressionPattern {
2786
2818
  this._name = name;
2787
2819
  this._parent = null;
2788
2820
  this._firstIndex = -1;
2789
- this._unaryPatterns = [];
2821
+ this._atomPatterns = [];
2822
+ this._unaryPrefixPatterns = [];
2823
+ this._unaryPrefixNames = [];
2790
2824
  this._binaryPatterns = [];
2791
2825
  this._recursivePatterns = [];
2792
2826
  this._recursiveNames = [];
@@ -2797,7 +2831,7 @@ class ExpressionPattern {
2797
2831
  this._originalPatterns = patterns;
2798
2832
  this._shouldCompactPatternsMap = {};
2799
2833
  this._patterns = this._organizePatterns(patterns);
2800
- if (this._unaryPatterns.length === 0) {
2834
+ if (this._atomPatterns.length === 0) {
2801
2835
  throw new Error("Need at least one operand pattern with an 'expression' pattern.");
2802
2836
  }
2803
2837
  }
@@ -2805,7 +2839,13 @@ class ExpressionPattern {
2805
2839
  const finalPatterns = [];
2806
2840
  patterns.forEach((pattern) => {
2807
2841
  this._shouldCompactPatternsMap[pattern.name] = pattern.shouldCompactAst;
2808
- if (this._isBinary(pattern)) {
2842
+ if (this._isUnary(pattern)) {
2843
+ const unaryPrefix = this._extractUnaryPrefixPattern(pattern).clone();
2844
+ this._unaryPrefixPatterns.push(pattern);
2845
+ this._unaryPrefixNames.push(pattern.name);
2846
+ finalPatterns.push(unaryPrefix);
2847
+ }
2848
+ else if (this._isBinary(pattern)) {
2809
2849
  const binaryName = this._extractName(pattern);
2810
2850
  const clone = this._extractDelimiter(pattern).clone();
2811
2851
  clone.parent = this;
@@ -2832,7 +2872,7 @@ class ExpressionPattern {
2832
2872
  else {
2833
2873
  const clone = pattern.clone();
2834
2874
  clone.parent = this;
2835
- this._unaryPatterns.push(clone);
2875
+ this._atomPatterns.push(clone);
2836
2876
  finalPatterns.push(clone);
2837
2877
  }
2838
2878
  });
@@ -2864,6 +2904,26 @@ class ExpressionPattern {
2864
2904
  }
2865
2905
  return pattern.name;
2866
2906
  }
2907
+ _isUnary(pattern) {
2908
+ if (pattern.type === "right-associated" && this._isUnaryPattern(pattern.children[0])) {
2909
+ return true;
2910
+ }
2911
+ return this._isUnaryPattern(pattern);
2912
+ }
2913
+ _isUnaryPattern(pattern) {
2914
+ return pattern.type === "sequence" &&
2915
+ pattern.children[0].type !== "reference" &&
2916
+ pattern.children[0].name !== this.name &&
2917
+ pattern.children[1].type === "reference" &&
2918
+ pattern.children[1].name === this.name &&
2919
+ pattern.children.length === 2;
2920
+ }
2921
+ _extractUnaryPrefixPattern(pattern) {
2922
+ if (pattern.type === "right-associated") {
2923
+ return pattern.children[0].children[0];
2924
+ }
2925
+ return pattern.children[0];
2926
+ }
2867
2927
  _isRecursive(pattern) {
2868
2928
  if (pattern.type === "right-associated" && this._isRecursivePattern(pattern.children[0])) {
2869
2929
  return true;
@@ -2874,7 +2934,7 @@ class ExpressionPattern {
2874
2934
  return pattern.type === "sequence" &&
2875
2935
  pattern.children[0].type === "reference" &&
2876
2936
  pattern.children[0].name === this.name &&
2877
- pattern.children.length > 1;
2937
+ pattern.children.length > 2;
2878
2938
  }
2879
2939
  _extractRecursiveTail(pattern) {
2880
2940
  if (pattern.type === "right-associated") {
@@ -2893,11 +2953,8 @@ class ExpressionPattern {
2893
2953
  lastChild.name === this.name;
2894
2954
  }
2895
2955
  parse(cursor) {
2896
- this._firstIndex = cursor.index;
2897
- depthCache.incrementDepth(this._id, this._firstIndex);
2898
2956
  this._firstIndex = cursor.index;
2899
2957
  const node = this._tryToParse(cursor);
2900
- depthCache.decrementDepth(this._id, this._firstIndex);
2901
2958
  if (node != null) {
2902
2959
  cursor.moveTo(node.lastIndex);
2903
2960
  cursor.resolveError();
@@ -2927,38 +2984,63 @@ class ExpressionPattern {
2927
2984
  }
2928
2985
  }
2929
2986
  _tryToParse(cursor) {
2930
- if (depthCache.getDepth(this._id, this._firstIndex) > 2) {
2987
+ if (this._isBeyondRecursiveAllowance()) {
2931
2988
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
2932
2989
  return null;
2933
2990
  }
2934
- let lastUnaryNode = null;
2991
+ let lastAtomNode = null;
2935
2992
  let lastBinaryNode = null;
2936
2993
  let onIndex = cursor.index;
2937
2994
  outer: while (true) {
2938
2995
  cursor.resolveError();
2939
2996
  onIndex = cursor.index;
2940
- for (let i = 0; i < this._unaryPatterns.length; i++) {
2997
+ let prefix = null;
2998
+ let prefixName = "";
2999
+ for (let i = 0; i < this._unaryPrefixPatterns.length; i++) {
3000
+ cursor.moveTo(onIndex);
3001
+ const pattern = this._unaryPrefixPatterns[i];
3002
+ const node = pattern.parse(cursor);
3003
+ if (node != null) {
3004
+ prefix = node;
3005
+ prefixName = this._unaryPrefixNames[i];
3006
+ if (cursor.hasNext()) {
3007
+ cursor.next();
3008
+ }
3009
+ else {
3010
+ break outer;
3011
+ }
3012
+ break;
3013
+ }
3014
+ else {
3015
+ cursor.resolveError();
3016
+ }
3017
+ }
3018
+ onIndex = cursor.index;
3019
+ for (let i = 0; i < this._atomPatterns.length; i++) {
2941
3020
  cursor.moveTo(onIndex);
2942
- const pattern = this._unaryPatterns[i];
3021
+ const pattern = this._atomPatterns[i];
2943
3022
  const node = pattern.parse(cursor);
2944
3023
  if (node != null) {
2945
- lastUnaryNode = node;
3024
+ lastAtomNode = node;
2946
3025
  break;
2947
3026
  }
2948
3027
  else {
2949
- lastUnaryNode = null;
3028
+ lastAtomNode = null;
2950
3029
  cursor.resolveError();
2951
3030
  }
2952
3031
  }
2953
- if (lastUnaryNode == null) {
3032
+ if (lastAtomNode == null) {
2954
3033
  break;
2955
3034
  }
2956
3035
  if (cursor.hasNext()) {
2957
3036
  cursor.next();
2958
3037
  }
2959
3038
  else {
2960
- if (lastBinaryNode != null && lastUnaryNode != null) {
2961
- lastBinaryNode.appendChild(lastUnaryNode);
3039
+ if (lastBinaryNode != null && lastAtomNode != null) {
3040
+ if (prefix != null) {
3041
+ lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3042
+ }
3043
+ lastBinaryNode.appendChild(lastAtomNode);
2962
3044
  }
2963
3045
  break;
2964
3046
  }
@@ -2969,24 +3051,30 @@ class ExpressionPattern {
2969
3051
  if (node != null) {
2970
3052
  const name = this._recursiveNames[i];
2971
3053
  if (this._endsInRecursion[i]) {
2972
- if (lastBinaryNode != null && lastUnaryNode != null) {
2973
- lastBinaryNode.appendChild(lastUnaryNode);
3054
+ if (lastBinaryNode != null && lastAtomNode != null) {
3055
+ if (prefix != null) {
3056
+ lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3057
+ }
3058
+ lastBinaryNode.appendChild(lastAtomNode);
2974
3059
  }
2975
- const frontExpression = lastBinaryNode == null ? lastUnaryNode : lastBinaryNode.findRoot();
3060
+ const frontExpression = lastBinaryNode == null ? lastAtomNode : lastBinaryNode.findRoot();
2976
3061
  const recursiveNode = createNode(name, [frontExpression, ...node.children]);
2977
3062
  recursiveNode.normalize(this._firstIndex);
2978
3063
  return recursiveNode;
2979
3064
  }
2980
3065
  else {
2981
- const recursiveNode = createNode(name, [lastUnaryNode, ...node.children]);
2982
- recursiveNode.normalize(lastUnaryNode.startIndex);
2983
- lastUnaryNode = recursiveNode;
3066
+ if (prefix != null) {
3067
+ lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3068
+ }
3069
+ const recursiveNode = createNode(name, [lastAtomNode, ...node.children]);
3070
+ recursiveNode.normalize(lastAtomNode.startIndex);
3071
+ lastAtomNode = recursiveNode;
2984
3072
  if (cursor.hasNext()) {
2985
3073
  cursor.next();
2986
3074
  }
2987
3075
  else {
2988
- if (lastBinaryNode != null) {
2989
- lastBinaryNode.appendChild(lastUnaryNode);
3076
+ if (lastBinaryNode != null && lastAtomNode != null) {
3077
+ lastBinaryNode.appendChild(lastAtomNode);
2990
3078
  }
2991
3079
  break outer;
2992
3080
  }
@@ -3008,31 +3096,31 @@ class ExpressionPattern {
3008
3096
  if (delimiterNode == null) {
3009
3097
  if (i === this._binaryPatterns.length - 1) {
3010
3098
  if (lastBinaryNode == null) {
3011
- return lastUnaryNode;
3099
+ return lastAtomNode;
3012
3100
  }
3013
- else if (lastUnaryNode != null) {
3014
- lastBinaryNode.appendChild(lastUnaryNode);
3101
+ else if (lastAtomNode != null) {
3102
+ lastBinaryNode.appendChild(lastAtomNode);
3015
3103
  }
3016
3104
  }
3017
3105
  continue;
3018
3106
  }
3019
- if (lastBinaryNode == null && lastUnaryNode != null && delimiterNode != null) {
3020
- const node = createNode(name, [lastUnaryNode, delimiterNode]);
3107
+ if (lastBinaryNode == null && lastAtomNode != null && delimiterNode != null) {
3108
+ const node = createNode(name, [lastAtomNode, delimiterNode]);
3021
3109
  lastBinaryNode = node;
3022
3110
  }
3023
- else if (lastBinaryNode != null && lastUnaryNode != null && delimiterNode != null) {
3111
+ else if (lastBinaryNode != null && lastAtomNode != null && delimiterNode != null) {
3024
3112
  const precedence = this._precedenceMap[name];
3025
3113
  const lastPrecendece = lastBinaryNode == null ? 0 : this._precedenceMap[lastBinaryNode.name] == null ? -1 : this._precedenceMap[lastBinaryNode.name];
3026
3114
  const association = this._binaryAssociation[i];
3027
3115
  if (precedence === lastPrecendece && association === Association.right) {
3028
- const node = createNode(name, [lastUnaryNode, delimiterNode]);
3116
+ const node = createNode(name, [lastAtomNode, delimiterNode]);
3029
3117
  lastBinaryNode.appendChild(node);
3030
3118
  lastBinaryNode = node;
3031
3119
  }
3032
3120
  else if (precedence === lastPrecendece) {
3033
3121
  const node = createNode(name, []);
3034
3122
  lastBinaryNode.replaceWith(node);
3035
- lastBinaryNode.appendChild(lastUnaryNode);
3123
+ lastBinaryNode.appendChild(lastAtomNode);
3036
3124
  node.append(lastBinaryNode, delimiterNode);
3037
3125
  lastBinaryNode = node;
3038
3126
  }
@@ -3047,7 +3135,7 @@ class ExpressionPattern {
3047
3135
  root = ancestor;
3048
3136
  ancestor = ancestor.parent;
3049
3137
  }
3050
- lastBinaryNode.appendChild(lastUnaryNode);
3138
+ lastBinaryNode.appendChild(lastAtomNode);
3051
3139
  if (root != null) {
3052
3140
  const node = createNode(name, []);
3053
3141
  root.replaceWith(node);
@@ -3055,12 +3143,12 @@ class ExpressionPattern {
3055
3143
  lastBinaryNode = node;
3056
3144
  }
3057
3145
  else {
3058
- const node = createNode(name, [lastUnaryNode, delimiterNode]);
3146
+ const node = createNode(name, [lastAtomNode, delimiterNode]);
3059
3147
  lastBinaryNode = node;
3060
3148
  }
3061
3149
  }
3062
3150
  else {
3063
- const node = createNode(name, [lastUnaryNode, delimiterNode]);
3151
+ const node = createNode(name, [lastAtomNode, delimiterNode]);
3064
3152
  lastBinaryNode.appendChild(node);
3065
3153
  lastBinaryNode = node;
3066
3154
  }
@@ -3078,20 +3166,34 @@ class ExpressionPattern {
3078
3166
  }
3079
3167
  }
3080
3168
  if (lastBinaryNode == null) {
3081
- return lastUnaryNode;
3169
+ return lastAtomNode;
3082
3170
  }
3083
3171
  else {
3084
3172
  const root = lastBinaryNode.findAncestor(n => n.parent == null) || lastBinaryNode;
3085
3173
  if (lastBinaryNode.children.length < 3) {
3086
3174
  lastBinaryNode.remove();
3087
3175
  if (lastBinaryNode === root) {
3088
- return lastUnaryNode;
3176
+ return lastAtomNode;
3089
3177
  }
3090
3178
  }
3091
3179
  root.normalize(this._firstIndex);
3092
3180
  return root;
3093
3181
  }
3094
3182
  }
3183
+ _isBeyondRecursiveAllowance() {
3184
+ let depth = 0;
3185
+ let pattern = this;
3186
+ while (pattern != null) {
3187
+ if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
3188
+ depth++;
3189
+ }
3190
+ if (depth > 2) {
3191
+ return true;
3192
+ }
3193
+ pattern = pattern.parent;
3194
+ }
3195
+ return false;
3196
+ }
3095
3197
  test(text) {
3096
3198
  const cursor = new Cursor(text);
3097
3199
  const ast = this.parse(cursor);
@@ -3119,7 +3221,7 @@ class ExpressionPattern {
3119
3221
  return this._binaryPatterns.map(p => p.getTokens()).flat();
3120
3222
  }
3121
3223
  if (this.binaryPatterns.indexOf(childReference)) {
3122
- const unaryTokens = this._unaryPatterns.map(p => p.getTokens()).flat();
3224
+ const unaryTokens = this._atomPatterns.map(p => p.getTokens()).flat();
3123
3225
  if (this._parent != null) {
3124
3226
  const nextTokens = this._parent.getTokensAfter(this);
3125
3227
  return [...unaryTokens, ...nextTokens];
@@ -3147,7 +3249,7 @@ class ExpressionPattern {
3147
3249
  return this._binaryPatterns.map(p => p.getPatterns()).flat();
3148
3250
  }
3149
3251
  if (this.binaryPatterns.indexOf(childReference)) {
3150
- const unaryPatterns = this._unaryPatterns.map(p => p.getPatterns()).flat();
3252
+ const unaryPatterns = this._atomPatterns.map(p => p.getPatterns()).flat();
3151
3253
  if (this._parent != null) {
3152
3254
  const nextPatterns = this._parent.getPatternsAfter(this);
3153
3255
  return [...unaryPatterns, ...nextPatterns];