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.esm.js CHANGED
@@ -279,7 +279,6 @@ class CursorHistory {
279
279
  this._patterns = [];
280
280
  this._nodes = [];
281
281
  this._errors = [];
282
- this._trace = [];
283
282
  }
284
283
  get isRecording() {
285
284
  return this._isRecording;
@@ -308,9 +307,6 @@ class CursorHistory {
308
307
  get patterns() {
309
308
  return this._patterns;
310
309
  }
311
- get trace() {
312
- return this._trace;
313
- }
314
310
  recordMatch(pattern, node) {
315
311
  if (this._isRecording) {
316
312
  this._patterns.push(pattern);
@@ -365,21 +361,8 @@ class CursorHistory {
365
361
  resolveError() {
366
362
  this._currentError = null;
367
363
  }
368
- pushStackTrace(trace) {
369
- if (this._isRecording) {
370
- this._trace.push(trace);
371
- }
372
- }
373
364
  }
374
365
 
375
- class CyclicalParseError extends Error {
376
- constructor(patternId, patternName, cursorIndex) {
377
- super("Cyclical Parse Error");
378
- this.patternId = patternId;
379
- this.patternName = patternName;
380
- this.cursorIndex = cursorIndex;
381
- }
382
- }
383
366
  class Cursor {
384
367
  get text() {
385
368
  return this._text;
@@ -434,7 +417,6 @@ class Cursor {
434
417
  this._index = 0;
435
418
  this._length = [...text].length;
436
419
  this._history = new CursorHistory();
437
- this._stackTrace = [];
438
420
  }
439
421
  hasNext() {
440
422
  return this._index + 1 < this._length;
@@ -484,35 +466,6 @@ class Cursor {
484
466
  stopRecording() {
485
467
  this._history.stopRecording();
486
468
  }
487
- startParseWith(pattern) {
488
- const trace = {
489
- pattern,
490
- cursorIndex: this.index
491
- };
492
- const hasCycle = this._stackTrace.filter(t => t.pattern.id === pattern.id && this.index === t.cursorIndex).length > 1;
493
- if (hasCycle) {
494
- throw new CyclicalParseError(pattern.id, pattern.name, this.index);
495
- }
496
- this._history.pushStackTrace(trace);
497
- this._stackTrace.push(trace);
498
- }
499
- endParse() {
500
- this._stackTrace.pop();
501
- }
502
- audit() {
503
- return this._history.trace.map(t => {
504
- const onChar = this.getChars(t.cursorIndex, t.cursorIndex);
505
- const restChars = this.getChars(t.cursorIndex + 1, t.cursorIndex + 5);
506
- const context = `{${t.cursorIndex}}[${onChar}]${restChars}`;
507
- return `${this._buildPatternContext(t.pattern)}-->${context}`;
508
- });
509
- }
510
- _buildPatternContext(pattern) {
511
- if (pattern.parent != null) {
512
- return `${pattern.parent.name}.${pattern.name}`;
513
- }
514
- return pattern.name;
515
- }
516
469
  }
517
470
 
518
471
  let idIndex$9 = 0;
@@ -568,18 +521,15 @@ class Literal {
568
521
  };
569
522
  }
570
523
  parse(cursor) {
571
- cursor.startParseWith(this);
572
524
  this._firstIndex = cursor.index;
573
525
  const passed = this._tryToParse(cursor);
574
526
  if (passed) {
575
527
  cursor.resolveError();
576
528
  const node = this._createNode();
577
529
  cursor.recordMatch(this, node);
578
- cursor.endParse();
579
530
  return node;
580
531
  }
581
532
  cursor.recordErrorAt(this._firstIndex, this._endIndex, this);
582
- cursor.endParse();
583
533
  return null;
584
534
  }
585
535
  _tryToParse(cursor) {
@@ -708,11 +658,9 @@ class Regex {
708
658
  };
709
659
  }
710
660
  parse(cursor) {
711
- cursor.startParseWith(this);
712
661
  this._firstIndex = cursor.index;
713
662
  this.resetState(cursor);
714
663
  this.tryToParse(cursor);
715
- cursor.endParse();
716
664
  return this._node;
717
665
  }
718
666
  resetState(cursor) {
@@ -928,6 +876,33 @@ function clonePatterns(patterns) {
928
876
  return patterns.map(p => p.clone());
929
877
  }
930
878
 
879
+ class DepthCache {
880
+ constructor() {
881
+ this._depthMap = {};
882
+ }
883
+ getDepth(name, cursorIndex) {
884
+ if (this._depthMap[name] == null) {
885
+ this._depthMap[name] = {};
886
+ }
887
+ if (this._depthMap[name][cursorIndex] == null) {
888
+ this._depthMap[name][cursorIndex] = 0;
889
+ }
890
+ return this._depthMap[name][cursorIndex];
891
+ }
892
+ incrementDepth(name, cursorIndex) {
893
+ const depth = this.getDepth(name, cursorIndex);
894
+ this._depthMap[name][cursorIndex] = depth + 1;
895
+ }
896
+ decrementDepth(name, cursorIndex) {
897
+ const depth = this.getDepth(name, cursorIndex);
898
+ this._depthMap[name][cursorIndex] = depth - 1;
899
+ }
900
+ }
901
+
902
+ /*
903
+ The following is created to reduce the overhead of recursion check.
904
+ */
905
+ const depthCache$1 = new DepthCache();
931
906
  let idIndex$6 = 0;
932
907
  class Options {
933
908
  get id() {
@@ -982,30 +957,30 @@ class Options {
982
957
  };
983
958
  }
984
959
  parse(cursor) {
985
- cursor.startParseWith(this);
960
+ // This is a cache to help with speed
961
+ this._firstIndex = cursor.index;
962
+ depthCache$1.incrementDepth(this._id, this._firstIndex);
986
963
  this._firstIndex = cursor.index;
987
964
  const node = this._tryToParse(cursor);
965
+ depthCache$1.decrementDepth(this._id, this._firstIndex);
988
966
  if (node != null) {
989
967
  cursor.moveTo(node.lastIndex);
990
968
  cursor.resolveError();
991
- cursor.endParse();
992
969
  return node;
993
970
  }
994
971
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
995
- cursor.endParse();
996
972
  return null;
997
973
  }
998
974
  _tryToParse(cursor) {
975
+ if (depthCache$1.getDepth(this._id, this._firstIndex) > 2) {
976
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
977
+ return null;
978
+ }
999
979
  const results = [];
1000
980
  for (const pattern of this._children) {
1001
981
  cursor.moveTo(this._firstIndex);
1002
982
  let result = null;
1003
- try {
1004
- result = pattern.parse(cursor);
1005
- }
1006
- catch (_a) {
1007
- continue;
1008
- }
983
+ result = pattern.parse(cursor);
1009
984
  if (this._isGreedy) {
1010
985
  results.push(result);
1011
986
  }
@@ -1117,7 +1092,6 @@ class FiniteRepeat {
1117
1092
  }
1118
1093
  }
1119
1094
  parse(cursor) {
1120
- cursor.startParseWith(this);
1121
1095
  const startIndex = cursor.index;
1122
1096
  const nodes = [];
1123
1097
  const modulo = this._hasDivider ? 2 : 1;
@@ -1156,19 +1130,16 @@ class FiniteRepeat {
1156
1130
  const lastIndex = cursor.index;
1157
1131
  cursor.moveTo(startIndex);
1158
1132
  cursor.recordErrorAt(startIndex, lastIndex, this);
1159
- cursor.endParse();
1160
1133
  return null;
1161
1134
  }
1162
1135
  if (nodes.length === 0 && !cursor.hasError) {
1163
1136
  cursor.moveTo(startIndex);
1164
- cursor.endParse();
1165
1137
  return null;
1166
1138
  }
1167
1139
  const firstIndex = nodes[0].firstIndex;
1168
1140
  const lastIndex = nodes[nodes.length - 1].lastIndex;
1169
1141
  cursor.resolveError();
1170
1142
  cursor.moveTo(lastIndex);
1171
- cursor.endParse();
1172
1143
  return new Node(this._type, this.name, firstIndex, lastIndex, nodes);
1173
1144
  }
1174
1145
  test(text) {
@@ -1314,7 +1285,6 @@ class InfiniteRepeat {
1314
1285
  };
1315
1286
  }
1316
1287
  parse(cursor) {
1317
- cursor.startParseWith(this);
1318
1288
  this._firstIndex = cursor.index;
1319
1289
  this._nodes = [];
1320
1290
  const passed = this._tryToParse(cursor);
@@ -1325,15 +1295,12 @@ class InfiniteRepeat {
1325
1295
  cursor.moveTo(node.lastIndex);
1326
1296
  cursor.recordMatch(this, node);
1327
1297
  }
1328
- cursor.endParse();
1329
1298
  return node;
1330
1299
  }
1331
1300
  if (this._min > 0) {
1332
- cursor.endParse();
1333
1301
  return null;
1334
1302
  }
1335
1303
  cursor.resolveError();
1336
- cursor.endParse();
1337
1304
  return null;
1338
1305
  }
1339
1306
  _meetsMin() {
@@ -1618,6 +1585,7 @@ function filterOutNull(nodes) {
1618
1585
  return filteredNodes;
1619
1586
  }
1620
1587
 
1588
+ const depthCache = new DepthCache();
1621
1589
  let idIndex$2 = 0;
1622
1590
  class Sequence {
1623
1591
  get id() {
@@ -1672,22 +1640,26 @@ class Sequence {
1672
1640
  };
1673
1641
  }
1674
1642
  parse(cursor) {
1675
- cursor.startParseWith(this);
1643
+ // This is a cache to help with speed
1676
1644
  this._firstIndex = cursor.index;
1645
+ depthCache.incrementDepth(this._id, this._firstIndex);
1677
1646
  this._nodes = [];
1678
1647
  const passed = this.tryToParse(cursor);
1648
+ depthCache.decrementDepth(this._id, this._firstIndex);
1679
1649
  if (passed) {
1680
1650
  const node = this.createNode(cursor);
1681
1651
  if (node !== null) {
1682
1652
  cursor.recordMatch(this, node);
1683
1653
  }
1684
- cursor.endParse();
1685
1654
  return node;
1686
1655
  }
1687
- cursor.endParse();
1688
1656
  return null;
1689
1657
  }
1690
1658
  tryToParse(cursor) {
1659
+ if (depthCache.getDepth(this._id, this._firstIndex) > 1) {
1660
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
1661
+ return false;
1662
+ }
1691
1663
  let passed = false;
1692
1664
  for (let i = 0; i < this._children.length; i++) {
1693
1665
  const runningCursorIndex = cursor.index;
@@ -1926,17 +1898,14 @@ class Optional {
1926
1898
  };
1927
1899
  }
1928
1900
  parse(cursor) {
1929
- cursor.startParseWith(this);
1930
1901
  const firstIndex = cursor.index;
1931
1902
  const node = this._children[0].parse(cursor);
1932
1903
  if (cursor.hasError) {
1933
1904
  cursor.resolveError();
1934
1905
  cursor.moveTo(firstIndex);
1935
- cursor.endParse();
1936
1906
  return null;
1937
1907
  }
1938
1908
  else {
1939
- cursor.endParse();
1940
1909
  return node;
1941
1910
  }
1942
1911
  }
@@ -2241,7 +2210,6 @@ class Not {
2241
2210
  };
2242
2211
  }
2243
2212
  parse(cursor) {
2244
- cursor.startParseWith(this);
2245
2213
  const firstIndex = cursor.index;
2246
2214
  this._children[0].parse(cursor);
2247
2215
  if (cursor.hasError) {
@@ -2253,7 +2221,6 @@ class Not {
2253
2221
  cursor.resolveError();
2254
2222
  cursor.recordErrorAt(firstIndex, firstIndex, this);
2255
2223
  }
2256
- cursor.endParse();
2257
2224
  return null;
2258
2225
  }
2259
2226
  clone(name = this._name) {