clarity-pattern-parser 10.0.5 → 10.0.7

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,21 +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, cursorIndex) {
381
- super("Cyclical Parse Error");
382
- this.patternId = patternId;
383
- this.patternName = patternName;
384
- this.cursorIndex = cursorIndex;
385
- }
386
- }
387
370
  class Cursor {
388
371
  get text() {
389
372
  return this._text;
@@ -438,7 +421,6 @@ class Cursor {
438
421
  this._index = 0;
439
422
  this._length = [...text].length;
440
423
  this._history = new CursorHistory();
441
- this._stackTrace = [];
442
424
  }
443
425
  hasNext() {
444
426
  return this._index + 1 < this._length;
@@ -488,35 +470,6 @@ class Cursor {
488
470
  stopRecording() {
489
471
  this._history.stopRecording();
490
472
  }
491
- startParseWith(pattern) {
492
- const trace = {
493
- pattern,
494
- cursorIndex: this.index
495
- };
496
- const hasCycle = this._stackTrace.filter(t => t.pattern.id === pattern.id && this.index === t.cursorIndex).length > 1;
497
- if (hasCycle) {
498
- throw new CyclicalParseError(pattern.id, pattern.name, this.index);
499
- }
500
- this._history.pushStackTrace(trace);
501
- this._stackTrace.push(trace);
502
- }
503
- endParse() {
504
- this._stackTrace.pop();
505
- }
506
- audit() {
507
- return this._history.trace.map(t => {
508
- const onChar = this.getChars(t.cursorIndex, t.cursorIndex);
509
- const restChars = this.getChars(t.cursorIndex + 1, t.cursorIndex + 5);
510
- const context = `{${t.cursorIndex}}[${onChar}]${restChars}`;
511
- return `${this._buildPatternContext(t.pattern)}-->${context}`;
512
- });
513
- }
514
- _buildPatternContext(pattern) {
515
- if (pattern.parent != null) {
516
- return `${pattern.parent.name}.${pattern.name}`;
517
- }
518
- return pattern.name;
519
- }
520
473
  }
521
474
 
522
475
  let idIndex$9 = 0;
@@ -572,18 +525,15 @@ class Literal {
572
525
  };
573
526
  }
574
527
  parse(cursor) {
575
- cursor.startParseWith(this);
576
528
  this._firstIndex = cursor.index;
577
529
  const passed = this._tryToParse(cursor);
578
530
  if (passed) {
579
531
  cursor.resolveError();
580
532
  const node = this._createNode();
581
533
  cursor.recordMatch(this, node);
582
- cursor.endParse();
583
534
  return node;
584
535
  }
585
536
  cursor.recordErrorAt(this._firstIndex, this._endIndex, this);
586
- cursor.endParse();
587
537
  return null;
588
538
  }
589
539
  _tryToParse(cursor) {
@@ -712,11 +662,9 @@ class Regex {
712
662
  };
713
663
  }
714
664
  parse(cursor) {
715
- cursor.startParseWith(this);
716
665
  this._firstIndex = cursor.index;
717
666
  this.resetState(cursor);
718
667
  this.tryToParse(cursor);
719
- cursor.endParse();
720
668
  return this._node;
721
669
  }
722
670
  resetState(cursor) {
@@ -932,6 +880,33 @@ function clonePatterns(patterns) {
932
880
  return patterns.map(p => p.clone());
933
881
  }
934
882
 
883
+ class DepthCache {
884
+ constructor() {
885
+ this._depthMap = {};
886
+ }
887
+ getDepth(name, cursorIndex) {
888
+ if (this._depthMap[name] == null) {
889
+ this._depthMap[name] = {};
890
+ }
891
+ if (this._depthMap[name][cursorIndex] == null) {
892
+ this._depthMap[name][cursorIndex] = 0;
893
+ }
894
+ return this._depthMap[name][cursorIndex];
895
+ }
896
+ incrementDepth(name, cursorIndex) {
897
+ const depth = this.getDepth(name, cursorIndex);
898
+ this._depthMap[name][cursorIndex] = depth + 1;
899
+ }
900
+ decrementDepth(name, cursorIndex) {
901
+ const depth = this.getDepth(name, cursorIndex);
902
+ this._depthMap[name][cursorIndex] = depth - 1;
903
+ }
904
+ }
905
+
906
+ /*
907
+ The following is created to reduce the overhead of recursion check.
908
+ */
909
+ const depthCache$1 = new DepthCache();
935
910
  let idIndex$6 = 0;
936
911
  class Options {
937
912
  get id() {
@@ -986,30 +961,30 @@ class Options {
986
961
  };
987
962
  }
988
963
  parse(cursor) {
989
- cursor.startParseWith(this);
964
+ // This is a cache to help with speed
965
+ this._firstIndex = cursor.index;
966
+ depthCache$1.incrementDepth(this._id, this._firstIndex);
990
967
  this._firstIndex = cursor.index;
991
968
  const node = this._tryToParse(cursor);
969
+ depthCache$1.decrementDepth(this._id, this._firstIndex);
992
970
  if (node != null) {
993
971
  cursor.moveTo(node.lastIndex);
994
972
  cursor.resolveError();
995
- cursor.endParse();
996
973
  return node;
997
974
  }
998
975
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
999
- cursor.endParse();
1000
976
  return null;
1001
977
  }
1002
978
  _tryToParse(cursor) {
979
+ if (depthCache$1.getDepth(this._id, this._firstIndex) > 2) {
980
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
981
+ return null;
982
+ }
1003
983
  const results = [];
1004
984
  for (const pattern of this._children) {
1005
985
  cursor.moveTo(this._firstIndex);
1006
986
  let result = null;
1007
- try {
1008
- result = pattern.parse(cursor);
1009
- }
1010
- catch (_a) {
1011
- continue;
1012
- }
987
+ result = pattern.parse(cursor);
1013
988
  if (this._isGreedy) {
1014
989
  results.push(result);
1015
990
  }
@@ -1121,7 +1096,6 @@ class FiniteRepeat {
1121
1096
  }
1122
1097
  }
1123
1098
  parse(cursor) {
1124
- cursor.startParseWith(this);
1125
1099
  const startIndex = cursor.index;
1126
1100
  const nodes = [];
1127
1101
  const modulo = this._hasDivider ? 2 : 1;
@@ -1160,19 +1134,16 @@ class FiniteRepeat {
1160
1134
  const lastIndex = cursor.index;
1161
1135
  cursor.moveTo(startIndex);
1162
1136
  cursor.recordErrorAt(startIndex, lastIndex, this);
1163
- cursor.endParse();
1164
1137
  return null;
1165
1138
  }
1166
1139
  if (nodes.length === 0 && !cursor.hasError) {
1167
1140
  cursor.moveTo(startIndex);
1168
- cursor.endParse();
1169
1141
  return null;
1170
1142
  }
1171
1143
  const firstIndex = nodes[0].firstIndex;
1172
1144
  const lastIndex = nodes[nodes.length - 1].lastIndex;
1173
1145
  cursor.resolveError();
1174
1146
  cursor.moveTo(lastIndex);
1175
- cursor.endParse();
1176
1147
  return new Node(this._type, this.name, firstIndex, lastIndex, nodes);
1177
1148
  }
1178
1149
  test(text) {
@@ -1318,7 +1289,6 @@ class InfiniteRepeat {
1318
1289
  };
1319
1290
  }
1320
1291
  parse(cursor) {
1321
- cursor.startParseWith(this);
1322
1292
  this._firstIndex = cursor.index;
1323
1293
  this._nodes = [];
1324
1294
  const passed = this._tryToParse(cursor);
@@ -1329,15 +1299,12 @@ class InfiniteRepeat {
1329
1299
  cursor.moveTo(node.lastIndex);
1330
1300
  cursor.recordMatch(this, node);
1331
1301
  }
1332
- cursor.endParse();
1333
1302
  return node;
1334
1303
  }
1335
1304
  if (this._min > 0) {
1336
- cursor.endParse();
1337
1305
  return null;
1338
1306
  }
1339
1307
  cursor.resolveError();
1340
- cursor.endParse();
1341
1308
  return null;
1342
1309
  }
1343
1310
  _meetsMin() {
@@ -1622,6 +1589,7 @@ function filterOutNull(nodes) {
1622
1589
  return filteredNodes;
1623
1590
  }
1624
1591
 
1592
+ const depthCache = new DepthCache();
1625
1593
  let idIndex$2 = 0;
1626
1594
  class Sequence {
1627
1595
  get id() {
@@ -1676,22 +1644,26 @@ class Sequence {
1676
1644
  };
1677
1645
  }
1678
1646
  parse(cursor) {
1679
- cursor.startParseWith(this);
1647
+ // This is a cache to help with speed
1680
1648
  this._firstIndex = cursor.index;
1649
+ depthCache.incrementDepth(this._id, this._firstIndex);
1681
1650
  this._nodes = [];
1682
1651
  const passed = this.tryToParse(cursor);
1652
+ depthCache.decrementDepth(this._id, this._firstIndex);
1683
1653
  if (passed) {
1684
1654
  const node = this.createNode(cursor);
1685
1655
  if (node !== null) {
1686
1656
  cursor.recordMatch(this, node);
1687
1657
  }
1688
- cursor.endParse();
1689
1658
  return node;
1690
1659
  }
1691
- cursor.endParse();
1692
1660
  return null;
1693
1661
  }
1694
1662
  tryToParse(cursor) {
1663
+ if (depthCache.getDepth(this._id, this._firstIndex) > 1) {
1664
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
1665
+ return false;
1666
+ }
1695
1667
  let passed = false;
1696
1668
  for (let i = 0; i < this._children.length; i++) {
1697
1669
  const runningCursorIndex = cursor.index;
@@ -1930,17 +1902,14 @@ class Optional {
1930
1902
  };
1931
1903
  }
1932
1904
  parse(cursor) {
1933
- cursor.startParseWith(this);
1934
1905
  const firstIndex = cursor.index;
1935
1906
  const node = this._children[0].parse(cursor);
1936
1907
  if (cursor.hasError) {
1937
1908
  cursor.resolveError();
1938
1909
  cursor.moveTo(firstIndex);
1939
- cursor.endParse();
1940
1910
  return null;
1941
1911
  }
1942
1912
  else {
1943
- cursor.endParse();
1944
1913
  return node;
1945
1914
  }
1946
1915
  }
@@ -2245,7 +2214,6 @@ class Not {
2245
2214
  };
2246
2215
  }
2247
2216
  parse(cursor) {
2248
- cursor.startParseWith(this);
2249
2217
  const firstIndex = cursor.index;
2250
2218
  this._children[0].parse(cursor);
2251
2219
  if (cursor.hasError) {
@@ -2257,7 +2225,6 @@ class Not {
2257
2225
  cursor.resolveError();
2258
2226
  cursor.recordErrorAt(firstIndex, firstIndex, this);
2259
2227
  }
2260
- cursor.endParse();
2261
2228
  return null;
2262
2229
  }
2263
2230
  clone(name = this._name) {