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.js CHANGED
@@ -532,6 +532,9 @@ class Literal {
532
532
  get children() {
533
533
  return [];
534
534
  }
535
+ get startedOnIndex() {
536
+ return this._firstIndex;
537
+ }
535
538
  constructor(name, value) {
536
539
  this.shouldCompactAst = false;
537
540
  if (value.length === 0) {
@@ -661,10 +664,13 @@ class Regex {
661
664
  get children() {
662
665
  return [];
663
666
  }
667
+ get startedOnIndex() {
668
+ return this._firstIndex;
669
+ }
664
670
  constructor(name, regex) {
665
671
  this._node = null;
666
672
  this._cursor = null;
667
- this._firstIndex = -1;
673
+ this._firstIndex = 0;
668
674
  this._substring = "";
669
675
  this._tokens = [];
670
676
  this.shouldCompactAst = false;
@@ -817,6 +823,9 @@ class Reference {
817
823
  get children() {
818
824
  return this._children;
819
825
  }
826
+ get startedOnIndex() {
827
+ return this._firstIndex;
828
+ }
820
829
  constructor(name) {
821
830
  this.shouldCompactAst = false;
822
831
  this._id = `reference-${idIndex$7++}`;
@@ -826,6 +835,7 @@ class Reference {
826
835
  this._pattern = null;
827
836
  this._cachedPattern = null;
828
837
  this._children = [];
838
+ this._firstIndex = 0;
829
839
  }
830
840
  test(text) {
831
841
  const cursor = new Cursor(text);
@@ -842,6 +852,7 @@ class Reference {
842
852
  };
843
853
  }
844
854
  parse(cursor) {
855
+ this._firstIndex = cursor.index;
845
856
  return this.getReferencePatternSafely().parse(cursor);
846
857
  }
847
858
  getReferencePatternSafely() {
@@ -955,29 +966,6 @@ function clonePatterns(patterns) {
955
966
  return patterns.map(p => p.clone());
956
967
  }
957
968
 
958
- class DepthCache {
959
- constructor() {
960
- this._depthMap = {};
961
- }
962
- getDepth(name, cursorIndex) {
963
- if (this._depthMap[name] == null) {
964
- this._depthMap[name] = {};
965
- }
966
- if (this._depthMap[name][cursorIndex] == null) {
967
- this._depthMap[name][cursorIndex] = 0;
968
- }
969
- return this._depthMap[name][cursorIndex];
970
- }
971
- incrementDepth(name, cursorIndex) {
972
- const depth = this.getDepth(name, cursorIndex);
973
- this._depthMap[name][cursorIndex] = depth + 1;
974
- }
975
- decrementDepth(name, cursorIndex) {
976
- const depth = this.getDepth(name, cursorIndex);
977
- this._depthMap[name][cursorIndex] = depth - 1;
978
- }
979
- }
980
-
981
969
  function isRecursivePattern(pattern) {
982
970
  let onPattern = pattern.parent;
983
971
  let depth = 0;
@@ -993,10 +981,6 @@ function isRecursivePattern(pattern) {
993
981
  return false;
994
982
  }
995
983
 
996
- /*
997
- The following is created to reduce the overhead of recursion check.
998
- */
999
- const depthCache$2 = new DepthCache();
1000
984
  let idIndex$6 = 0;
1001
985
  class Options {
1002
986
  get id() {
@@ -1017,6 +1001,9 @@ class Options {
1017
1001
  get children() {
1018
1002
  return this._children;
1019
1003
  }
1004
+ get startedOnIndex() {
1005
+ return this._firstIndex;
1006
+ }
1020
1007
  constructor(name, options, isGreedy = false) {
1021
1008
  this.shouldCompactAst = false;
1022
1009
  if (options.length === 0) {
@@ -1052,12 +1039,8 @@ class Options {
1052
1039
  };
1053
1040
  }
1054
1041
  parse(cursor) {
1055
- // This is a cache to help with speed
1056
- this._firstIndex = cursor.index;
1057
- depthCache$2.incrementDepth(this._id, this._firstIndex);
1058
1042
  this._firstIndex = cursor.index;
1059
1043
  const node = this._tryToParse(cursor);
1060
- depthCache$2.decrementDepth(this._id, this._firstIndex);
1061
1044
  if (node != null) {
1062
1045
  cursor.moveTo(node.lastIndex);
1063
1046
  cursor.resolveError();
@@ -1070,7 +1053,7 @@ class Options {
1070
1053
  return null;
1071
1054
  }
1072
1055
  _tryToParse(cursor) {
1073
- if (depthCache$2.getDepth(this._id, this._firstIndex) > 2) {
1056
+ if (this._isBeyondRecursiveAllowance()) {
1074
1057
  return null;
1075
1058
  }
1076
1059
  const results = [];
@@ -1090,6 +1073,20 @@ class Options {
1090
1073
  nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
1091
1074
  return nonNullResults[0] || null;
1092
1075
  }
1076
+ _isBeyondRecursiveAllowance() {
1077
+ let depth = 0;
1078
+ let pattern = this;
1079
+ while (pattern != null) {
1080
+ if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
1081
+ depth++;
1082
+ }
1083
+ if (depth > 2) {
1084
+ return true;
1085
+ }
1086
+ pattern = pattern.parent;
1087
+ }
1088
+ return false;
1089
+ }
1093
1090
  getTokens() {
1094
1091
  const tokens = [];
1095
1092
  for (const pattern of this._children) {
@@ -1174,6 +1171,9 @@ class FiniteRepeat {
1174
1171
  get max() {
1175
1172
  return this._max;
1176
1173
  }
1174
+ get startedOnIndex() {
1175
+ return this._firstIndex;
1176
+ }
1177
1177
  constructor(name, pattern, options = {}) {
1178
1178
  this.shouldCompactAst = false;
1179
1179
  this._id = `finite-repeat-${idIndex$5++}`;
@@ -1185,6 +1185,7 @@ class FiniteRepeat {
1185
1185
  this._min = options.min != null ? Math.max(options.min, 1) : 1;
1186
1186
  this._max = Math.max(this.min, options.max || this.min);
1187
1187
  this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
1188
+ this._firstIndex = 0;
1188
1189
  for (let i = 0; i < this._max; i++) {
1189
1190
  const child = pattern.clone();
1190
1191
  child.parent = this;
@@ -1197,6 +1198,7 @@ class FiniteRepeat {
1197
1198
  }
1198
1199
  }
1199
1200
  parse(cursor) {
1201
+ this._firstIndex = cursor.index;
1200
1202
  const startIndex = cursor.index;
1201
1203
  const nodes = [];
1202
1204
  const modulo = this._hasDivider ? 2 : 1;
@@ -1352,6 +1354,9 @@ class InfiniteRepeat {
1352
1354
  get min() {
1353
1355
  return this._min;
1354
1356
  }
1357
+ get startedOnIndex() {
1358
+ return this._firstIndex;
1359
+ }
1355
1360
  constructor(name, pattern, options = {}) {
1356
1361
  this.shouldCompactAst = false;
1357
1362
  const min = options.min != null ? Math.max(options.min, 1) : 1;
@@ -1627,6 +1632,9 @@ class Repeat {
1627
1632
  get max() {
1628
1633
  return this._options.max;
1629
1634
  }
1635
+ get startedOnIndex() {
1636
+ return this._repeatPattern.startedOnIndex;
1637
+ }
1630
1638
  constructor(name, pattern, options = {}) {
1631
1639
  this._id = `repeat-${idIndex$3++}`;
1632
1640
  this._pattern = pattern;
@@ -1709,7 +1717,6 @@ function filterOutNull(nodes) {
1709
1717
  return filteredNodes;
1710
1718
  }
1711
1719
 
1712
- const depthCache$1 = new DepthCache();
1713
1720
  let idIndex$2 = 0;
1714
1721
  class Sequence {
1715
1722
  get id() {
@@ -1730,6 +1737,9 @@ class Sequence {
1730
1737
  get children() {
1731
1738
  return this._children;
1732
1739
  }
1740
+ get startedOnIndex() {
1741
+ return this._firstIndex;
1742
+ }
1733
1743
  constructor(name, sequence) {
1734
1744
  this.shouldCompactAst = false;
1735
1745
  if (sequence.length === 0) {
@@ -1765,12 +1775,9 @@ class Sequence {
1765
1775
  };
1766
1776
  }
1767
1777
  parse(cursor) {
1768
- // This is a cache to help with speed
1769
1778
  this._firstIndex = cursor.index;
1770
- depthCache$1.incrementDepth(this._id, this._firstIndex);
1771
1779
  this._nodes = [];
1772
1780
  const passed = this.tryToParse(cursor);
1773
- depthCache$1.decrementDepth(this._id, this._firstIndex);
1774
1781
  if (passed) {
1775
1782
  const node = this.createNode(cursor);
1776
1783
  if (node !== null) {
@@ -1784,7 +1791,7 @@ class Sequence {
1784
1791
  return null;
1785
1792
  }
1786
1793
  tryToParse(cursor) {
1787
- if (depthCache$1.getDepth(this._id, this._firstIndex) > 1) {
1794
+ if (this._isBeyondRecursiveAllowance()) {
1788
1795
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
1789
1796
  return false;
1790
1797
  }
@@ -1851,6 +1858,20 @@ class Sequence {
1851
1858
  }
1852
1859
  return nodes[nodes.length - 1];
1853
1860
  }
1861
+ _isBeyondRecursiveAllowance() {
1862
+ let depth = 0;
1863
+ let pattern = this;
1864
+ while (pattern != null) {
1865
+ if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
1866
+ depth++;
1867
+ }
1868
+ if (depth > 1) {
1869
+ return true;
1870
+ }
1871
+ pattern = pattern.parent;
1872
+ }
1873
+ return false;
1874
+ }
1854
1875
  areRemainingPatternsOptional(fromIndex) {
1855
1876
  const startOnIndex = fromIndex + 1;
1856
1877
  const length = this._children.length;
@@ -2010,6 +2031,9 @@ class Optional {
2010
2031
  get children() {
2011
2032
  return this._children;
2012
2033
  }
2034
+ get startedOnIndex() {
2035
+ return this._children[0].startedOnIndex;
2036
+ }
2013
2037
  constructor(name, pattern) {
2014
2038
  this.shouldCompactAst = false;
2015
2039
  this._id = `optional-${idIndex$1++}`;
@@ -2331,6 +2355,9 @@ class Not {
2331
2355
  get children() {
2332
2356
  return this._children;
2333
2357
  }
2358
+ get startedOnIndex() {
2359
+ return this.children[0].startedOnIndex;
2360
+ }
2334
2361
  constructor(name, pattern) {
2335
2362
  this.shouldCompactAst = false;
2336
2363
  this._id = `not-${idIndex++}`;
@@ -2670,6 +2697,9 @@ class Context {
2670
2697
  get children() {
2671
2698
  return this._children;
2672
2699
  }
2700
+ get startedOnIndex() {
2701
+ return this.children[0].startedOnIndex;
2702
+ }
2673
2703
  getPatternWithinContext(name) {
2674
2704
  return this._patterns[name] || null;
2675
2705
  }
@@ -2743,7 +2773,6 @@ class Context {
2743
2773
  }
2744
2774
 
2745
2775
  let indexId = 0;
2746
- const depthCache = new DepthCache();
2747
2776
  function createNode(name, children) {
2748
2777
  return new Node("expression", name, 0, 0, children, "");
2749
2778
  }
@@ -2772,7 +2801,7 @@ class ExpressionPattern {
2772
2801
  return this._patterns;
2773
2802
  }
2774
2803
  get unaryPatterns() {
2775
- return this._unaryPatterns;
2804
+ return this._atomPatterns;
2776
2805
  }
2777
2806
  get binaryPatterns() {
2778
2807
  return this._binaryPatterns;
@@ -2780,6 +2809,9 @@ class ExpressionPattern {
2780
2809
  get recursivePatterns() {
2781
2810
  return this._recursivePatterns;
2782
2811
  }
2812
+ get startedOnIndex() {
2813
+ return this._firstIndex;
2814
+ }
2783
2815
  constructor(name, patterns) {
2784
2816
  this.shouldCompactAst = false;
2785
2817
  if (patterns.length === 0) {
@@ -2790,7 +2822,9 @@ class ExpressionPattern {
2790
2822
  this._name = name;
2791
2823
  this._parent = null;
2792
2824
  this._firstIndex = -1;
2793
- this._unaryPatterns = [];
2825
+ this._atomPatterns = [];
2826
+ this._unaryPrefixPatterns = [];
2827
+ this._unaryPrefixNames = [];
2794
2828
  this._binaryPatterns = [];
2795
2829
  this._recursivePatterns = [];
2796
2830
  this._recursiveNames = [];
@@ -2801,7 +2835,7 @@ class ExpressionPattern {
2801
2835
  this._originalPatterns = patterns;
2802
2836
  this._shouldCompactPatternsMap = {};
2803
2837
  this._patterns = this._organizePatterns(patterns);
2804
- if (this._unaryPatterns.length === 0) {
2838
+ if (this._atomPatterns.length === 0) {
2805
2839
  throw new Error("Need at least one operand pattern with an 'expression' pattern.");
2806
2840
  }
2807
2841
  }
@@ -2809,7 +2843,13 @@ class ExpressionPattern {
2809
2843
  const finalPatterns = [];
2810
2844
  patterns.forEach((pattern) => {
2811
2845
  this._shouldCompactPatternsMap[pattern.name] = pattern.shouldCompactAst;
2812
- if (this._isBinary(pattern)) {
2846
+ if (this._isUnary(pattern)) {
2847
+ const unaryPrefix = this._extractUnaryPrefixPattern(pattern).clone();
2848
+ this._unaryPrefixPatterns.push(pattern);
2849
+ this._unaryPrefixNames.push(pattern.name);
2850
+ finalPatterns.push(unaryPrefix);
2851
+ }
2852
+ else if (this._isBinary(pattern)) {
2813
2853
  const binaryName = this._extractName(pattern);
2814
2854
  const clone = this._extractDelimiter(pattern).clone();
2815
2855
  clone.parent = this;
@@ -2836,7 +2876,7 @@ class ExpressionPattern {
2836
2876
  else {
2837
2877
  const clone = pattern.clone();
2838
2878
  clone.parent = this;
2839
- this._unaryPatterns.push(clone);
2879
+ this._atomPatterns.push(clone);
2840
2880
  finalPatterns.push(clone);
2841
2881
  }
2842
2882
  });
@@ -2868,6 +2908,26 @@ class ExpressionPattern {
2868
2908
  }
2869
2909
  return pattern.name;
2870
2910
  }
2911
+ _isUnary(pattern) {
2912
+ if (pattern.type === "right-associated" && this._isUnaryPattern(pattern.children[0])) {
2913
+ return true;
2914
+ }
2915
+ return this._isUnaryPattern(pattern);
2916
+ }
2917
+ _isUnaryPattern(pattern) {
2918
+ return pattern.type === "sequence" &&
2919
+ pattern.children[0].type !== "reference" &&
2920
+ pattern.children[0].name !== this.name &&
2921
+ pattern.children[1].type === "reference" &&
2922
+ pattern.children[1].name === this.name &&
2923
+ pattern.children.length === 2;
2924
+ }
2925
+ _extractUnaryPrefixPattern(pattern) {
2926
+ if (pattern.type === "right-associated") {
2927
+ return pattern.children[0].children[0];
2928
+ }
2929
+ return pattern.children[0];
2930
+ }
2871
2931
  _isRecursive(pattern) {
2872
2932
  if (pattern.type === "right-associated" && this._isRecursivePattern(pattern.children[0])) {
2873
2933
  return true;
@@ -2878,7 +2938,7 @@ class ExpressionPattern {
2878
2938
  return pattern.type === "sequence" &&
2879
2939
  pattern.children[0].type === "reference" &&
2880
2940
  pattern.children[0].name === this.name &&
2881
- pattern.children.length > 1;
2941
+ pattern.children.length > 2;
2882
2942
  }
2883
2943
  _extractRecursiveTail(pattern) {
2884
2944
  if (pattern.type === "right-associated") {
@@ -2897,11 +2957,8 @@ class ExpressionPattern {
2897
2957
  lastChild.name === this.name;
2898
2958
  }
2899
2959
  parse(cursor) {
2900
- this._firstIndex = cursor.index;
2901
- depthCache.incrementDepth(this._id, this._firstIndex);
2902
2960
  this._firstIndex = cursor.index;
2903
2961
  const node = this._tryToParse(cursor);
2904
- depthCache.decrementDepth(this._id, this._firstIndex);
2905
2962
  if (node != null) {
2906
2963
  cursor.moveTo(node.lastIndex);
2907
2964
  cursor.resolveError();
@@ -2931,38 +2988,63 @@ class ExpressionPattern {
2931
2988
  }
2932
2989
  }
2933
2990
  _tryToParse(cursor) {
2934
- if (depthCache.getDepth(this._id, this._firstIndex) > 2) {
2991
+ if (this._isBeyondRecursiveAllowance()) {
2935
2992
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
2936
2993
  return null;
2937
2994
  }
2938
- let lastUnaryNode = null;
2995
+ let lastAtomNode = null;
2939
2996
  let lastBinaryNode = null;
2940
2997
  let onIndex = cursor.index;
2941
2998
  outer: while (true) {
2942
2999
  cursor.resolveError();
2943
3000
  onIndex = cursor.index;
2944
- for (let i = 0; i < this._unaryPatterns.length; i++) {
3001
+ let prefix = null;
3002
+ let prefixName = "";
3003
+ for (let i = 0; i < this._unaryPrefixPatterns.length; i++) {
3004
+ cursor.moveTo(onIndex);
3005
+ const pattern = this._unaryPrefixPatterns[i];
3006
+ const node = pattern.parse(cursor);
3007
+ if (node != null) {
3008
+ prefix = node;
3009
+ prefixName = this._unaryPrefixNames[i];
3010
+ if (cursor.hasNext()) {
3011
+ cursor.next();
3012
+ }
3013
+ else {
3014
+ break outer;
3015
+ }
3016
+ break;
3017
+ }
3018
+ else {
3019
+ cursor.resolveError();
3020
+ }
3021
+ }
3022
+ onIndex = cursor.index;
3023
+ for (let i = 0; i < this._atomPatterns.length; i++) {
2945
3024
  cursor.moveTo(onIndex);
2946
- const pattern = this._unaryPatterns[i];
3025
+ const pattern = this._atomPatterns[i];
2947
3026
  const node = pattern.parse(cursor);
2948
3027
  if (node != null) {
2949
- lastUnaryNode = node;
3028
+ lastAtomNode = node;
2950
3029
  break;
2951
3030
  }
2952
3031
  else {
2953
- lastUnaryNode = null;
3032
+ lastAtomNode = null;
2954
3033
  cursor.resolveError();
2955
3034
  }
2956
3035
  }
2957
- if (lastUnaryNode == null) {
3036
+ if (lastAtomNode == null) {
2958
3037
  break;
2959
3038
  }
2960
3039
  if (cursor.hasNext()) {
2961
3040
  cursor.next();
2962
3041
  }
2963
3042
  else {
2964
- if (lastBinaryNode != null && lastUnaryNode != null) {
2965
- lastBinaryNode.appendChild(lastUnaryNode);
3043
+ if (lastBinaryNode != null && lastAtomNode != null) {
3044
+ if (prefix != null) {
3045
+ lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3046
+ }
3047
+ lastBinaryNode.appendChild(lastAtomNode);
2966
3048
  }
2967
3049
  break;
2968
3050
  }
@@ -2973,24 +3055,30 @@ class ExpressionPattern {
2973
3055
  if (node != null) {
2974
3056
  const name = this._recursiveNames[i];
2975
3057
  if (this._endsInRecursion[i]) {
2976
- if (lastBinaryNode != null && lastUnaryNode != null) {
2977
- lastBinaryNode.appendChild(lastUnaryNode);
3058
+ if (lastBinaryNode != null && lastAtomNode != null) {
3059
+ if (prefix != null) {
3060
+ lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3061
+ }
3062
+ lastBinaryNode.appendChild(lastAtomNode);
2978
3063
  }
2979
- const frontExpression = lastBinaryNode == null ? lastUnaryNode : lastBinaryNode.findRoot();
3064
+ const frontExpression = lastBinaryNode == null ? lastAtomNode : lastBinaryNode.findRoot();
2980
3065
  const recursiveNode = createNode(name, [frontExpression, ...node.children]);
2981
3066
  recursiveNode.normalize(this._firstIndex);
2982
3067
  return recursiveNode;
2983
3068
  }
2984
3069
  else {
2985
- const recursiveNode = createNode(name, [lastUnaryNode, ...node.children]);
2986
- recursiveNode.normalize(lastUnaryNode.startIndex);
2987
- lastUnaryNode = recursiveNode;
3070
+ if (prefix != null) {
3071
+ lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3072
+ }
3073
+ const recursiveNode = createNode(name, [lastAtomNode, ...node.children]);
3074
+ recursiveNode.normalize(lastAtomNode.startIndex);
3075
+ lastAtomNode = recursiveNode;
2988
3076
  if (cursor.hasNext()) {
2989
3077
  cursor.next();
2990
3078
  }
2991
3079
  else {
2992
- if (lastBinaryNode != null) {
2993
- lastBinaryNode.appendChild(lastUnaryNode);
3080
+ if (lastBinaryNode != null && lastAtomNode != null) {
3081
+ lastBinaryNode.appendChild(lastAtomNode);
2994
3082
  }
2995
3083
  break outer;
2996
3084
  }
@@ -3012,31 +3100,31 @@ class ExpressionPattern {
3012
3100
  if (delimiterNode == null) {
3013
3101
  if (i === this._binaryPatterns.length - 1) {
3014
3102
  if (lastBinaryNode == null) {
3015
- return lastUnaryNode;
3103
+ return lastAtomNode;
3016
3104
  }
3017
- else if (lastUnaryNode != null) {
3018
- lastBinaryNode.appendChild(lastUnaryNode);
3105
+ else if (lastAtomNode != null) {
3106
+ lastBinaryNode.appendChild(lastAtomNode);
3019
3107
  }
3020
3108
  }
3021
3109
  continue;
3022
3110
  }
3023
- if (lastBinaryNode == null && lastUnaryNode != null && delimiterNode != null) {
3024
- const node = createNode(name, [lastUnaryNode, delimiterNode]);
3111
+ if (lastBinaryNode == null && lastAtomNode != null && delimiterNode != null) {
3112
+ const node = createNode(name, [lastAtomNode, delimiterNode]);
3025
3113
  lastBinaryNode = node;
3026
3114
  }
3027
- else if (lastBinaryNode != null && lastUnaryNode != null && delimiterNode != null) {
3115
+ else if (lastBinaryNode != null && lastAtomNode != null && delimiterNode != null) {
3028
3116
  const precedence = this._precedenceMap[name];
3029
3117
  const lastPrecendece = lastBinaryNode == null ? 0 : this._precedenceMap[lastBinaryNode.name] == null ? -1 : this._precedenceMap[lastBinaryNode.name];
3030
3118
  const association = this._binaryAssociation[i];
3031
3119
  if (precedence === lastPrecendece && association === Association.right) {
3032
- const node = createNode(name, [lastUnaryNode, delimiterNode]);
3120
+ const node = createNode(name, [lastAtomNode, delimiterNode]);
3033
3121
  lastBinaryNode.appendChild(node);
3034
3122
  lastBinaryNode = node;
3035
3123
  }
3036
3124
  else if (precedence === lastPrecendece) {
3037
3125
  const node = createNode(name, []);
3038
3126
  lastBinaryNode.replaceWith(node);
3039
- lastBinaryNode.appendChild(lastUnaryNode);
3127
+ lastBinaryNode.appendChild(lastAtomNode);
3040
3128
  node.append(lastBinaryNode, delimiterNode);
3041
3129
  lastBinaryNode = node;
3042
3130
  }
@@ -3051,7 +3139,7 @@ class ExpressionPattern {
3051
3139
  root = ancestor;
3052
3140
  ancestor = ancestor.parent;
3053
3141
  }
3054
- lastBinaryNode.appendChild(lastUnaryNode);
3142
+ lastBinaryNode.appendChild(lastAtomNode);
3055
3143
  if (root != null) {
3056
3144
  const node = createNode(name, []);
3057
3145
  root.replaceWith(node);
@@ -3059,12 +3147,12 @@ class ExpressionPattern {
3059
3147
  lastBinaryNode = node;
3060
3148
  }
3061
3149
  else {
3062
- const node = createNode(name, [lastUnaryNode, delimiterNode]);
3150
+ const node = createNode(name, [lastAtomNode, delimiterNode]);
3063
3151
  lastBinaryNode = node;
3064
3152
  }
3065
3153
  }
3066
3154
  else {
3067
- const node = createNode(name, [lastUnaryNode, delimiterNode]);
3155
+ const node = createNode(name, [lastAtomNode, delimiterNode]);
3068
3156
  lastBinaryNode.appendChild(node);
3069
3157
  lastBinaryNode = node;
3070
3158
  }
@@ -3082,20 +3170,34 @@ class ExpressionPattern {
3082
3170
  }
3083
3171
  }
3084
3172
  if (lastBinaryNode == null) {
3085
- return lastUnaryNode;
3173
+ return lastAtomNode;
3086
3174
  }
3087
3175
  else {
3088
3176
  const root = lastBinaryNode.findAncestor(n => n.parent == null) || lastBinaryNode;
3089
3177
  if (lastBinaryNode.children.length < 3) {
3090
3178
  lastBinaryNode.remove();
3091
3179
  if (lastBinaryNode === root) {
3092
- return lastUnaryNode;
3180
+ return lastAtomNode;
3093
3181
  }
3094
3182
  }
3095
3183
  root.normalize(this._firstIndex);
3096
3184
  return root;
3097
3185
  }
3098
3186
  }
3187
+ _isBeyondRecursiveAllowance() {
3188
+ let depth = 0;
3189
+ let pattern = this;
3190
+ while (pattern != null) {
3191
+ if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
3192
+ depth++;
3193
+ }
3194
+ if (depth > 2) {
3195
+ return true;
3196
+ }
3197
+ pattern = pattern.parent;
3198
+ }
3199
+ return false;
3200
+ }
3099
3201
  test(text) {
3100
3202
  const cursor = new Cursor(text);
3101
3203
  const ast = this.parse(cursor);
@@ -3123,7 +3225,7 @@ class ExpressionPattern {
3123
3225
  return this._binaryPatterns.map(p => p.getTokens()).flat();
3124
3226
  }
3125
3227
  if (this.binaryPatterns.indexOf(childReference)) {
3126
- const unaryTokens = this._unaryPatterns.map(p => p.getTokens()).flat();
3228
+ const unaryTokens = this._atomPatterns.map(p => p.getTokens()).flat();
3127
3229
  if (this._parent != null) {
3128
3230
  const nextTokens = this._parent.getTokensAfter(this);
3129
3231
  return [...unaryTokens, ...nextTokens];
@@ -3151,7 +3253,7 @@ class ExpressionPattern {
3151
3253
  return this._binaryPatterns.map(p => p.getPatterns()).flat();
3152
3254
  }
3153
3255
  if (this.binaryPatterns.indexOf(childReference)) {
3154
- const unaryPatterns = this._unaryPatterns.map(p => p.getPatterns()).flat();
3256
+ const unaryPatterns = this._atomPatterns.map(p => p.getPatterns()).flat();
3155
3257
  if (this._parent != null) {
3156
3258
  const nextPatterns = this._parent.getPatternsAfter(this);
3157
3259
  return [...unaryPatterns, ...nextPatterns];