clarity-pattern-parser 10.0.4 → 10.0.6

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
@@ -283,7 +283,6 @@ class CursorHistory {
283
283
  this._patterns = [];
284
284
  this._nodes = [];
285
285
  this._errors = [];
286
- this._trace = [];
287
286
  }
288
287
  get isRecording() {
289
288
  return this._isRecording;
@@ -312,9 +311,6 @@ class CursorHistory {
312
311
  get patterns() {
313
312
  return this._patterns;
314
313
  }
315
- get trace() {
316
- return this._trace;
317
- }
318
314
  recordMatch(pattern, node) {
319
315
  if (this._isRecording) {
320
316
  this._patterns.push(pattern);
@@ -369,20 +365,8 @@ class CursorHistory {
369
365
  resolveError() {
370
366
  this._currentError = null;
371
367
  }
372
- pushStackTrace(trace) {
373
- if (this._isRecording) {
374
- this._trace.push(trace);
375
- }
376
- }
377
368
  }
378
369
 
379
- class CyclicalParseError extends Error {
380
- constructor(patternId, patternName) {
381
- super("Cyclical Parse Error");
382
- this.patternId = patternId;
383
- this.patternName = patternName;
384
- }
385
- }
386
370
  class Cursor {
387
371
  get text() {
388
372
  return this._text;
@@ -437,7 +421,6 @@ class Cursor {
437
421
  this._index = 0;
438
422
  this._length = [...text].length;
439
423
  this._history = new CursorHistory();
440
- this._stackTrace = [];
441
424
  }
442
425
  hasNext() {
443
426
  return this._index + 1 < this._length;
@@ -487,35 +470,6 @@ class Cursor {
487
470
  stopRecording() {
488
471
  this._history.stopRecording();
489
472
  }
490
- startParseWith(pattern) {
491
- const trace = {
492
- pattern,
493
- cursorIndex: this.index
494
- };
495
- const hasCycle = this._stackTrace.filter(t => t.pattern.id === pattern.id && this.index === t.cursorIndex).length > 1;
496
- if (hasCycle) {
497
- throw new CyclicalParseError(pattern.id, pattern.name);
498
- }
499
- this._history.pushStackTrace(trace);
500
- this._stackTrace.push(trace);
501
- }
502
- endParse() {
503
- this._stackTrace.pop();
504
- }
505
- audit() {
506
- return this._history.trace.map(t => {
507
- const onChar = this.getChars(t.cursorIndex, t.cursorIndex);
508
- const restChars = this.getChars(t.cursorIndex + 1, t.cursorIndex + 5);
509
- const context = `{${t.cursorIndex}}[${onChar}]${restChars}`;
510
- return `${this._buildPatternContext(t.pattern)}-->${context}`;
511
- });
512
- }
513
- _buildPatternContext(pattern) {
514
- if (pattern.parent != null) {
515
- return `${pattern.parent.name}.${pattern.name}`;
516
- }
517
- return pattern.name;
518
- }
519
473
  }
520
474
 
521
475
  let idIndex$9 = 0;
@@ -571,18 +525,15 @@ class Literal {
571
525
  };
572
526
  }
573
527
  parse(cursor) {
574
- cursor.startParseWith(this);
575
528
  this._firstIndex = cursor.index;
576
529
  const passed = this._tryToParse(cursor);
577
530
  if (passed) {
578
531
  cursor.resolveError();
579
532
  const node = this._createNode();
580
533
  cursor.recordMatch(this, node);
581
- cursor.endParse();
582
534
  return node;
583
535
  }
584
536
  cursor.recordErrorAt(this._firstIndex, this._endIndex, this);
585
- cursor.endParse();
586
537
  return null;
587
538
  }
588
539
  _tryToParse(cursor) {
@@ -711,11 +662,9 @@ class Regex {
711
662
  };
712
663
  }
713
664
  parse(cursor) {
714
- cursor.startParseWith(this);
715
665
  this._firstIndex = cursor.index;
716
666
  this.resetState(cursor);
717
667
  this.tryToParse(cursor);
718
- cursor.endParse();
719
668
  return this._node;
720
669
  }
721
670
  resetState(cursor) {
@@ -985,36 +934,26 @@ class Options {
985
934
  };
986
935
  }
987
936
  parse(cursor) {
988
- cursor.startParseWith(this);
989
937
  this._firstIndex = cursor.index;
990
938
  const node = this._tryToParse(cursor);
991
939
  if (node != null) {
992
940
  cursor.moveTo(node.lastIndex);
993
941
  cursor.resolveError();
994
- cursor.endParse();
995
942
  return node;
996
943
  }
997
944
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
998
- cursor.endParse();
999
945
  return null;
1000
946
  }
1001
947
  _tryToParse(cursor) {
948
+ if (this._isBeyondRecursiveLimit()) {
949
+ cursor.recordErrorAt(cursor.index, cursor.index, this);
950
+ return null;
951
+ }
1002
952
  const results = [];
1003
953
  for (const pattern of this._children) {
1004
954
  cursor.moveTo(this._firstIndex);
1005
955
  let result = null;
1006
- try {
1007
- result = pattern.parse(cursor);
1008
- }
1009
- catch (error) {
1010
- if (error.patternId === this._id) {
1011
- continue;
1012
- }
1013
- else {
1014
- cursor.endParse();
1015
- throw error;
1016
- }
1017
- }
956
+ result = pattern.parse(cursor);
1018
957
  if (this._isGreedy) {
1019
958
  results.push(result);
1020
959
  }
@@ -1027,6 +966,25 @@ class Options {
1027
966
  nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
1028
967
  return nonNullResults[0] || null;
1029
968
  }
969
+ _isBeyondRecursiveLimit() {
970
+ let pattern = this;
971
+ const matches = [];
972
+ while (pattern.parent != null) {
973
+ if (pattern.type !== "options") {
974
+ pattern = pattern.parent;
975
+ continue;
976
+ }
977
+ const optionsPattern = pattern;
978
+ if (pattern.id === this.id && optionsPattern._firstIndex === this._firstIndex) {
979
+ matches.push(pattern);
980
+ if (matches.length > 2) {
981
+ return true;
982
+ }
983
+ }
984
+ pattern = pattern.parent;
985
+ }
986
+ return false;
987
+ }
1030
988
  getTokens() {
1031
989
  const tokens = [];
1032
990
  for (const child of this._children) {
@@ -1126,7 +1084,6 @@ class FiniteRepeat {
1126
1084
  }
1127
1085
  }
1128
1086
  parse(cursor) {
1129
- cursor.startParseWith(this);
1130
1087
  const startIndex = cursor.index;
1131
1088
  const nodes = [];
1132
1089
  const modulo = this._hasDivider ? 2 : 1;
@@ -1165,19 +1122,16 @@ class FiniteRepeat {
1165
1122
  const lastIndex = cursor.index;
1166
1123
  cursor.moveTo(startIndex);
1167
1124
  cursor.recordErrorAt(startIndex, lastIndex, this);
1168
- cursor.endParse();
1169
1125
  return null;
1170
1126
  }
1171
1127
  if (nodes.length === 0 && !cursor.hasError) {
1172
1128
  cursor.moveTo(startIndex);
1173
- cursor.endParse();
1174
1129
  return null;
1175
1130
  }
1176
1131
  const firstIndex = nodes[0].firstIndex;
1177
1132
  const lastIndex = nodes[nodes.length - 1].lastIndex;
1178
1133
  cursor.resolveError();
1179
1134
  cursor.moveTo(lastIndex);
1180
- cursor.endParse();
1181
1135
  return new Node(this._type, this.name, firstIndex, lastIndex, nodes);
1182
1136
  }
1183
1137
  test(text) {
@@ -1323,7 +1277,6 @@ class InfiniteRepeat {
1323
1277
  };
1324
1278
  }
1325
1279
  parse(cursor) {
1326
- cursor.startParseWith(this);
1327
1280
  this._firstIndex = cursor.index;
1328
1281
  this._nodes = [];
1329
1282
  const passed = this._tryToParse(cursor);
@@ -1334,15 +1287,12 @@ class InfiniteRepeat {
1334
1287
  cursor.moveTo(node.lastIndex);
1335
1288
  cursor.recordMatch(this, node);
1336
1289
  }
1337
- cursor.endParse();
1338
1290
  return node;
1339
1291
  }
1340
1292
  if (this._min > 0) {
1341
- cursor.endParse();
1342
1293
  return null;
1343
1294
  }
1344
1295
  cursor.resolveError();
1345
- cursor.endParse();
1346
1296
  return null;
1347
1297
  }
1348
1298
  _meetsMin() {
@@ -1681,19 +1631,20 @@ class Sequence {
1681
1631
  };
1682
1632
  }
1683
1633
  parse(cursor) {
1684
- cursor.startParseWith(this);
1685
1634
  this._firstIndex = cursor.index;
1686
1635
  this._nodes = [];
1636
+ if (this._isBeyondRecursiveLimit()) {
1637
+ cursor.recordErrorAt(cursor.index, cursor.index, this);
1638
+ return null;
1639
+ }
1687
1640
  const passed = this.tryToParse(cursor);
1688
1641
  if (passed) {
1689
1642
  const node = this.createNode(cursor);
1690
1643
  if (node !== null) {
1691
1644
  cursor.recordMatch(this, node);
1692
1645
  }
1693
- cursor.endParse();
1694
1646
  return node;
1695
1647
  }
1696
- cursor.endParse();
1697
1648
  return null;
1698
1649
  }
1699
1650
  tryToParse(cursor) {
@@ -1753,6 +1704,25 @@ class Sequence {
1753
1704
  }
1754
1705
  return passed;
1755
1706
  }
1707
+ _isBeyondRecursiveLimit() {
1708
+ let pattern = this;
1709
+ const matches = [];
1710
+ while (pattern.parent != null) {
1711
+ if (pattern.type !== "sequence") {
1712
+ pattern = pattern.parent;
1713
+ continue;
1714
+ }
1715
+ const sequencePattern = pattern;
1716
+ if (pattern.id === this.id && sequencePattern._firstIndex === this._firstIndex) {
1717
+ matches.push(pattern);
1718
+ if (matches.length > 1) {
1719
+ return true;
1720
+ }
1721
+ }
1722
+ pattern = pattern.parent;
1723
+ }
1724
+ return false;
1725
+ }
1756
1726
  getLastValidNode() {
1757
1727
  const nodes = filterOutNull(this._nodes);
1758
1728
  if (nodes.length === 0) {
@@ -1935,17 +1905,14 @@ class Optional {
1935
1905
  };
1936
1906
  }
1937
1907
  parse(cursor) {
1938
- cursor.startParseWith(this);
1939
1908
  const firstIndex = cursor.index;
1940
1909
  const node = this._children[0].parse(cursor);
1941
1910
  if (cursor.hasError) {
1942
1911
  cursor.resolveError();
1943
1912
  cursor.moveTo(firstIndex);
1944
- cursor.endParse();
1945
1913
  return null;
1946
1914
  }
1947
1915
  else {
1948
- cursor.endParse();
1949
1916
  return node;
1950
1917
  }
1951
1918
  }
@@ -2250,7 +2217,6 @@ class Not {
2250
2217
  };
2251
2218
  }
2252
2219
  parse(cursor) {
2253
- cursor.startParseWith(this);
2254
2220
  const firstIndex = cursor.index;
2255
2221
  this._children[0].parse(cursor);
2256
2222
  if (cursor.hasError) {
@@ -2262,7 +2228,6 @@ class Not {
2262
2228
  cursor.resolveError();
2263
2229
  cursor.recordErrorAt(firstIndex, firstIndex, this);
2264
2230
  }
2265
- cursor.endParse();
2266
2231
  return null;
2267
2232
  }
2268
2233
  clone(name = this._name) {