clarity-pattern-parser 11.0.6 → 11.0.8

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
@@ -12,6 +12,9 @@ class Node {
12
12
  get name() {
13
13
  return this._name;
14
14
  }
15
+ get value() {
16
+ return this.toString();
17
+ }
15
18
  get firstIndex() {
16
19
  return this._firstIndex;
17
20
  }
@@ -36,9 +39,6 @@ class Node {
36
39
  get isLeaf() {
37
40
  return !this.hasChildren;
38
41
  }
39
- get value() {
40
- return this.toString();
41
- }
42
42
  constructor(type, name, firstIndex, lastIndex, children = [], value = "") {
43
43
  this._type = type;
44
44
  this._name = name;
@@ -126,15 +126,6 @@ class Node {
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
- }
138
129
  findAll(predicate) {
139
130
  const matches = [];
140
131
  this.walkUp(n => {
@@ -144,6 +135,15 @@ class Node {
144
135
  });
145
136
  return matches;
146
137
  }
138
+ findRoot() {
139
+ let pattern = this;
140
+ while (true) {
141
+ if (pattern.parent == null) {
142
+ return pattern;
143
+ }
144
+ pattern = pattern.parent;
145
+ }
146
+ }
147
147
  findAncestor(predicate) {
148
148
  let parent = this._parent;
149
149
  while (parent != null) {
@@ -189,7 +189,7 @@ class Node {
189
189
  });
190
190
  return nodes;
191
191
  }
192
- reduce() {
192
+ compact() {
193
193
  const value = this.toString();
194
194
  this.removeAllChildren();
195
195
  this._value = value;
@@ -220,10 +220,6 @@ class Node {
220
220
  this._lastIndex = Math.max(startIndex + length - 1, 0);
221
221
  return length;
222
222
  }
223
- compact() {
224
- this._value = this.toString();
225
- this._children.length = 0;
226
- }
227
223
  toString() {
228
224
  if (this._children.length === 0) {
229
225
  return this._value;
@@ -395,10 +391,10 @@ class CursorHistory {
395
391
  }
396
392
  }
397
393
  }
398
- recordErrorAt(startIndex, endIndex, pattern) {
399
- const error = new ParseError(startIndex, endIndex, pattern);
394
+ recordErrorAt(startIndex, lastIndex, pattern) {
395
+ const error = new ParseError(startIndex, lastIndex, pattern);
400
396
  this._currentError = error;
401
- if (this._furthestError === null || endIndex > this._furthestError.lastIndex) {
397
+ if (this._furthestError === null || lastIndex > this._furthestError.lastIndex) {
402
398
  this._furthestError = error;
403
399
  }
404
400
  if (this._isRecording) {
@@ -852,6 +848,8 @@ class Reference {
852
848
  this._cachedPattern = null;
853
849
  this._children = [];
854
850
  this._firstIndex = 0;
851
+ this._cachedAncestors = false;
852
+ this._recursiveAncestors = [];
855
853
  }
856
854
  test(text, record = false) {
857
855
  return testPattern(this, text, record);
@@ -861,8 +859,36 @@ class Reference {
861
859
  }
862
860
  parse(cursor) {
863
861
  this._firstIndex = cursor.index;
862
+ this._cacheAncestors();
863
+ if (this._isBeyondRecursiveAllowance()) {
864
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
865
+ return null;
866
+ }
864
867
  return this.getReferencePatternSafely().parse(cursor);
865
868
  }
869
+ _cacheAncestors() {
870
+ if (!this._cachedAncestors) {
871
+ let pattern = this.parent;
872
+ while (pattern != null) {
873
+ if (pattern.type === this.type && pattern.id === this._id) {
874
+ this._recursiveAncestors.push(pattern);
875
+ }
876
+ pattern = pattern.parent;
877
+ }
878
+ }
879
+ }
880
+ _isBeyondRecursiveAllowance() {
881
+ let depth = 0;
882
+ for (let pattern of this._recursiveAncestors) {
883
+ if (pattern._firstIndex === this._firstIndex) {
884
+ depth++;
885
+ if (depth > 2) {
886
+ return true;
887
+ }
888
+ }
889
+ }
890
+ return false;
891
+ }
866
892
  getReferencePatternSafely() {
867
893
  if (this._pattern === null) {
868
894
  let pattern = null;
@@ -1048,9 +1074,6 @@ class Options {
1048
1074
  return null;
1049
1075
  }
1050
1076
  _tryToParse(cursor) {
1051
- if (this._isBeyondRecursiveAllowance()) {
1052
- return null;
1053
- }
1054
1077
  const results = [];
1055
1078
  for (const pattern of this._children) {
1056
1079
  cursor.moveTo(this._firstIndex);
@@ -1068,20 +1091,6 @@ class Options {
1068
1091
  nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
1069
1092
  return nonNullResults[0] || null;
1070
1093
  }
1071
- _isBeyondRecursiveAllowance() {
1072
- let depth = 0;
1073
- let pattern = this;
1074
- while (pattern != null) {
1075
- if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
1076
- depth++;
1077
- }
1078
- if (depth > 2) {
1079
- return true;
1080
- }
1081
- pattern = pattern.parent;
1082
- }
1083
- return false;
1084
- }
1085
1094
  getTokens() {
1086
1095
  const tokens = [];
1087
1096
  for (const pattern of this._children) {
@@ -1192,7 +1201,6 @@ class FiniteRepeat {
1192
1201
  }
1193
1202
  parse(cursor) {
1194
1203
  this._firstIndex = cursor.index;
1195
- const startIndex = cursor.index;
1196
1204
  const nodes = [];
1197
1205
  const modulo = this._hasDivider ? 2 : 1;
1198
1206
  let matchCount = 0;
@@ -1228,12 +1236,12 @@ class FiniteRepeat {
1228
1236
  }
1229
1237
  if (matchCount < this._min) {
1230
1238
  const lastIndex = cursor.index;
1231
- cursor.moveTo(startIndex);
1232
- cursor.recordErrorAt(startIndex, lastIndex, this);
1239
+ cursor.moveTo(this._firstIndex);
1240
+ cursor.recordErrorAt(this._firstIndex, lastIndex, this);
1233
1241
  return null;
1234
1242
  }
1235
1243
  if (nodes.length === 0 && !cursor.hasError) {
1236
- cursor.moveTo(startIndex);
1244
+ cursor.moveTo(this._firstIndex);
1237
1245
  return null;
1238
1246
  }
1239
1247
  const firstIndex = nodes[0].firstIndex;
@@ -1357,7 +1365,7 @@ class InfiniteRepeat {
1357
1365
  this._children = children;
1358
1366
  this._pattern = children[0];
1359
1367
  this._divider = children[1];
1360
- this._firstIndex = -1;
1368
+ this._firstIndex = 0;
1361
1369
  this._nodes = [];
1362
1370
  this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
1363
1371
  }
@@ -1537,7 +1545,7 @@ class InfiniteRepeat {
1537
1545
  patterns.push(this._children[0]);
1538
1546
  }
1539
1547
  // If there is no divider then suggest the repeating pattern and the next pattern after.
1540
- if (index === 0 && !this._divider && this._parent) {
1548
+ if (index === 0 && this._divider == null && this._parent) {
1541
1549
  patterns.push(this._children[0]);
1542
1550
  patterns.push(...this._parent.getPatternsAfter(this));
1543
1551
  }
@@ -1738,10 +1746,6 @@ class Sequence {
1738
1746
  return null;
1739
1747
  }
1740
1748
  tryToParse(cursor) {
1741
- if (this._isBeyondRecursiveAllowance()) {
1742
- cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
1743
- return false;
1744
- }
1745
1749
  let passed = false;
1746
1750
  for (let i = 0; i < this._children.length; i++) {
1747
1751
  const runningCursorIndex = cursor.index;
@@ -1805,20 +1809,6 @@ class Sequence {
1805
1809
  }
1806
1810
  return nodes[nodes.length - 1];
1807
1811
  }
1808
- _isBeyondRecursiveAllowance() {
1809
- let depth = 0;
1810
- let pattern = this;
1811
- while (pattern != null) {
1812
- if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
1813
- depth++;
1814
- }
1815
- if (depth > 1) {
1816
- return true;
1817
- }
1818
- pattern = pattern.parent;
1819
- }
1820
- return false;
1821
- }
1822
1812
  areRemainingPatternsOptional(fromIndex) {
1823
1813
  const startOnIndex = fromIndex + 1;
1824
1814
  const length = this._children.length;
@@ -2130,13 +2120,13 @@ const repeatLiteral = new Sequence("repeat-literal", [
2130
2120
  const optionalNot = new Optional("optional-not", new Literal("not", "!"));
2131
2121
  const optionalIsOptional$1 = new Optional("optional-is-optional", new Literal("is-optional", "?"));
2132
2122
  const patternName$1 = name$1.clone("pattern-name");
2133
- const patterns$2 = new Options("and-patterns", [patternName$1, anonymousPattern]);
2134
- const pattern$1 = new Sequence("and-child-pattern", [
2123
+ const patterns$2 = new Options("sequence-patterns", [patternName$1, anonymousPattern]);
2124
+ const pattern$1 = new Sequence("sequence-child-pattern", [
2135
2125
  optionalNot,
2136
2126
  patterns$2,
2137
2127
  optionalIsOptional$1,
2138
2128
  ]);
2139
- const divider$1 = new Regex("and-divider", "\\s*[+]\\s*");
2129
+ const divider$1 = new Regex("sequence-divider", "\\s*[+]\\s*");
2140
2130
  divider$1.setTokens([" + "]);
2141
2131
  const sequenceLiteral = new Repeat("sequence-literal", pattern$1, { divider: divider$1, min: 2, trimDivider: true });
2142
2132
 
@@ -2878,7 +2868,7 @@ class PrecedenceTree {
2878
2868
  }
2879
2869
 
2880
2870
  let indexId$1 = 0;
2881
- class ExpressionPattern {
2871
+ class Expression {
2882
2872
  get id() {
2883
2873
  return this._id;
2884
2874
  }
@@ -2920,7 +2910,7 @@ class ExpressionPattern {
2920
2910
  this._type = "expression";
2921
2911
  this._name = name;
2922
2912
  this._parent = null;
2923
- this._firstIndex = -1;
2913
+ this._firstIndex = 0;
2924
2914
  this._atomPatterns = [];
2925
2915
  this._prefixPatterns = [];
2926
2916
  this._prefixNames = [];
@@ -2965,10 +2955,10 @@ class ExpressionPattern {
2965
2955
  }
2966
2956
  else if (this._isBinary(pattern)) {
2967
2957
  const name = this._extractName(pattern);
2968
- const clone = this._extractBinary(pattern);
2969
- clone.parent = this;
2958
+ const binary = this._extractBinary(pattern);
2959
+ binary.parent = this;
2970
2960
  this._precedenceMap[name] = this._binaryPatterns.length;
2971
- this._binaryPatterns.push(clone);
2961
+ this._binaryPatterns.push(binary);
2972
2962
  this._binaryNames.push(name);
2973
2963
  if (pattern.type === "right-associated") {
2974
2964
  this._associationMap[name] = Association.right;
@@ -2976,7 +2966,7 @@ class ExpressionPattern {
2976
2966
  else {
2977
2967
  this._associationMap[name] = Association.left;
2978
2968
  }
2979
- finalPatterns.push(clone);
2969
+ finalPatterns.push(binary);
2980
2970
  }
2981
2971
  });
2982
2972
  return finalPatterns;
@@ -3062,10 +3052,6 @@ class ExpressionPattern {
3062
3052
  return null;
3063
3053
  }
3064
3054
  _tryToParse(cursor) {
3065
- if (this._isBeyondRecursiveAllowance()) {
3066
- cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
3067
- return null;
3068
- }
3069
3055
  this._shouldStopParsing = false;
3070
3056
  while (true) {
3071
3057
  cursor.resolveError();
@@ -3196,20 +3182,6 @@ class ExpressionPattern {
3196
3182
  this._shouldStopParsing = true;
3197
3183
  }
3198
3184
  }
3199
- _isBeyondRecursiveAllowance() {
3200
- let depth = 0;
3201
- let pattern = this;
3202
- while (pattern != null) {
3203
- if (pattern.id === this.id && pattern.startedOnIndex === this.startedOnIndex) {
3204
- depth++;
3205
- }
3206
- if (depth > 2) {
3207
- return true;
3208
- }
3209
- pattern = pattern.parent;
3210
- }
3211
- return false;
3212
- }
3213
3185
  test(text, record = false) {
3214
3186
  return testPattern(this, text, record);
3215
3187
  }
@@ -3217,7 +3189,9 @@ class ExpressionPattern {
3217
3189
  return execPattern(this, text, record);
3218
3190
  }
3219
3191
  getTokens() {
3220
- return this.atomPatterns.map(p => p.getTokens()).flat();
3192
+ const atomTokens = this._atomPatterns.map(p => p.getTokens()).flat();
3193
+ const prefixTokens = this.prefixPatterns.map(p => p.getTokens()).flat();
3194
+ return [...prefixTokens, ...atomTokens];
3221
3195
  }
3222
3196
  getTokensAfter(childReference) {
3223
3197
  if (this._prefixPatterns.includes(childReference) || this._binaryPatterns.includes(childReference)) {
@@ -3246,7 +3220,9 @@ class ExpressionPattern {
3246
3220
  return this._parent.getTokensAfter(this);
3247
3221
  }
3248
3222
  getPatterns() {
3249
- return this.atomPatterns.map(p => p.getPatterns()).flat();
3223
+ const atomPatterns = this._atomPatterns.map(p => p.getPatterns()).flat();
3224
+ const prefixPatterns = this.prefixPatterns.map(p => p.getPatterns()).flat();
3225
+ return [...prefixPatterns, ...atomPatterns];
3250
3226
  }
3251
3227
  getPatternsAfter(childReference) {
3252
3228
  if (this._prefixPatterns.includes(childReference) || this._binaryPatterns.includes(childReference)) {
@@ -3278,7 +3254,7 @@ class ExpressionPattern {
3278
3254
  return findPattern(this, predicate);
3279
3255
  }
3280
3256
  clone(name = this._name) {
3281
- const clone = new ExpressionPattern(name, this._originalPatterns);
3257
+ const clone = new Expression(name, this._originalPatterns);
3282
3258
  clone._id = this._id;
3283
3259
  return clone;
3284
3260
  }
@@ -3288,7 +3264,7 @@ class ExpressionPattern {
3288
3264
  }
3289
3265
 
3290
3266
  let indexId = 0;
3291
- class RightAssociatedPattern {
3267
+ class RightAssociated {
3292
3268
  get id() {
3293
3269
  return this._id;
3294
3270
  }
@@ -3327,7 +3303,7 @@ class RightAssociatedPattern {
3327
3303
  return this.children[0].test(text, record);
3328
3304
  }
3329
3305
  clone(_name) {
3330
- const clone = new RightAssociatedPattern(this.children[0]);
3306
+ const clone = new RightAssociated(this.children[0]);
3331
3307
  clone._id = this._id;
3332
3308
  return clone;
3333
3309
  }
@@ -3420,14 +3396,6 @@ class Grammar {
3420
3396
  return this._buildPatternRecord();
3421
3397
  });
3422
3398
  }
3423
- _buildPatternRecord() {
3424
- const patterns = {};
3425
- const allPatterns = Array.from(this._parseContext.patternsByName.values());
3426
- allPatterns.forEach(p => {
3427
- patterns[p.name] = new Context(p.name, p, allPatterns.filter(o => o !== p));
3428
- });
3429
- return patterns;
3430
- }
3431
3399
  parseString(expression) {
3432
3400
  this._parseContext = new ParseContext(this._params);
3433
3401
  const ast = this._tryToParse(expression);
@@ -3437,6 +3405,14 @@ class Grammar {
3437
3405
  this._buildPatterns(ast);
3438
3406
  return this._buildPatternRecord();
3439
3407
  }
3408
+ _buildPatternRecord() {
3409
+ const patterns = {};
3410
+ const allPatterns = Array.from(this._parseContext.patternsByName.values());
3411
+ allPatterns.forEach(p => {
3412
+ patterns[p.name] = new Context(p.name, p, allPatterns.filter(o => o !== p));
3413
+ });
3414
+ return patterns;
3415
+ }
3440
3416
  _tryToParse(expression) {
3441
3417
  const { ast, cursor, options, isComplete } = this._autoComplete.suggestFor(expression);
3442
3418
  if (!isComplete) {
@@ -3553,7 +3529,7 @@ class Grammar {
3553
3529
  const patterns = patternNodes.map(n => {
3554
3530
  const rightAssociated = n.find(n => n.name === "right-associated");
3555
3531
  if (rightAssociated != null) {
3556
- return new RightAssociatedPattern(this._buildPattern(n.children[0]));
3532
+ return new RightAssociated(this._buildPattern(n.children[0]));
3557
3533
  }
3558
3534
  else {
3559
3535
  return this._buildPattern(n.children[0]);
@@ -3562,13 +3538,13 @@ class Grammar {
3562
3538
  const hasRecursivePattern = patterns.some(p => this._isRecursive(name, p));
3563
3539
  if (hasRecursivePattern && !isGreedy) {
3564
3540
  try {
3565
- const expression = new ExpressionPattern(name, patterns);
3541
+ const expression = new Expression(name, patterns);
3566
3542
  return expression;
3567
3543
  }
3568
3544
  catch (_a) { }
3569
3545
  }
3570
- const or = new Options(name, patterns, isGreedy);
3571
- return or;
3546
+ const options = new Options(name, patterns, isGreedy);
3547
+ return options;
3572
3548
  }
3573
3549
  _isRecursive(name, pattern) {
3574
3550
  if (pattern.type === "right-associated" && this._isRecursivePattern(name, pattern.children[0])) {
@@ -3623,7 +3599,7 @@ class Grammar {
3623
3599
  this._parseContext.patternsByName.set(name, sequence);
3624
3600
  }
3625
3601
  _buildSequence(name, node) {
3626
- const patternNodes = node.children.filter(n => n.name !== "and-divider");
3602
+ const patternNodes = node.children.filter(n => n.name !== "sequence-divider");
3627
3603
  const patterns = patternNodes.map(n => {
3628
3604
  const patternNode = n.children[0].name === "not" ? n.children[1] : n.children[0];
3629
3605
  const isNot = n.find(n => n.name === "not") != null;
@@ -3832,7 +3808,7 @@ exports.AutoComplete = AutoComplete;
3832
3808
  exports.Context = Context;
3833
3809
  exports.Cursor = Cursor;
3834
3810
  exports.CursorHistory = CursorHistory;
3835
- exports.ExpressionPattern = ExpressionPattern;
3811
+ exports.Expression = Expression;
3836
3812
  exports.Grammar = Grammar;
3837
3813
  exports.Literal = Literal;
3838
3814
  exports.Node = Node;
@@ -3843,6 +3819,7 @@ exports.ParseError = ParseError;
3843
3819
  exports.Reference = Reference;
3844
3820
  exports.Regex = Regex;
3845
3821
  exports.Repeat = Repeat;
3822
+ exports.RightAssociated = RightAssociated;
3846
3823
  exports.Sequence = Sequence;
3847
3824
  exports.compact = compact;
3848
3825
  exports.grammar = grammar;