clarity-pattern-parser 10.3.6 → 11.0.0

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.
Files changed (51) hide show
  1. package/dist/ast/Node.d.ts +2 -2
  2. package/dist/ast/compact.d.ts +2 -0
  3. package/dist/ast/remove.d.ts +2 -0
  4. package/dist/index.browser.js +418 -490
  5. package/dist/index.browser.js.map +1 -1
  6. package/dist/index.d.ts +3 -1
  7. package/dist/index.esm.js +417 -491
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/index.js +418 -490
  10. package/dist/index.js.map +1 -1
  11. package/dist/patterns/ExpressionPattern.d.ts +27 -25
  12. package/dist/patterns/FiniteRepeat.d.ts +1 -2
  13. package/dist/patterns/InfiniteRepeat.d.ts +1 -2
  14. package/dist/patterns/Literal.d.ts +0 -1
  15. package/dist/patterns/Not.d.ts +1 -2
  16. package/dist/patterns/Optional.d.ts +0 -1
  17. package/dist/patterns/Options.d.ts +1 -2
  18. package/dist/patterns/Pattern.d.ts +0 -1
  19. package/dist/patterns/PrecedenceTree.d.ts +28 -0
  20. package/dist/patterns/Reference.d.ts +1 -2
  21. package/dist/patterns/Regex.d.ts +1 -2
  22. package/dist/patterns/Repeat.d.ts +0 -3
  23. package/dist/patterns/Sequence.d.ts +3 -6
  24. package/dist/patterns/execPattern.d.ts +3 -0
  25. package/dist/patterns/testPattern.d.ts +2 -0
  26. package/package.json +1 -1
  27. package/src/ast/Node.test.ts +17 -17
  28. package/src/ast/Node.ts +7 -5
  29. package/src/ast/compact.ts +11 -0
  30. package/src/ast/remove.ts +11 -0
  31. package/src/grammar/Grammar.test.ts +0 -50
  32. package/src/grammar/Grammar.ts +0 -20
  33. package/src/grammar/patterns/statement.ts +1 -6
  34. package/src/index.ts +4 -0
  35. package/src/patterns/ExpressionPattern.test.ts +1 -1
  36. package/src/patterns/ExpressionPattern.ts +237 -387
  37. package/src/patterns/FiniteRepeat.ts +5 -22
  38. package/src/patterns/InfiniteRepeat.ts +6 -21
  39. package/src/patterns/Literal.ts +5 -19
  40. package/src/patterns/Not.ts +5 -16
  41. package/src/patterns/Optional.ts +0 -7
  42. package/src/patterns/Options.ts +5 -21
  43. package/src/patterns/Pattern.ts +0 -1
  44. package/src/patterns/PrecedenceTree.test.ts +162 -0
  45. package/src/patterns/PrecedenceTree.ts +207 -0
  46. package/src/patterns/Reference.ts +5 -17
  47. package/src/patterns/Regex.ts +5 -17
  48. package/src/patterns/Repeat.ts +1 -13
  49. package/src/patterns/Sequence.ts +7 -22
  50. package/src/patterns/execPattern.ts +16 -0
  51. package/src/patterns/testPattern.ts +11 -0
@@ -74,6 +74,8 @@
74
74
  const index = this.findChildIndex(referenceNode);
75
75
  if (index > -1) {
76
76
  this.spliceChildren(index, 1, newNode);
77
+ newNode._parent = this;
78
+ referenceNode._parent = null;
77
79
  }
78
80
  }
79
81
  replaceWith(newNode) {
@@ -246,15 +248,33 @@
246
248
  isEqual(node) {
247
249
  return node.toJson(0) === this.toJson(0);
248
250
  }
249
- static createValueNode(name, value) {
250
- return new Node("custom-value-node", name, 0, 0, [], value);
251
+ static createValueNode(type, name, value = "") {
252
+ return new Node(type, name, 0, 0, [], value);
251
253
  }
252
- static createNode(name, children) {
254
+ static createNode(type, name, children = []) {
253
255
  const value = children.map(c => c.toString()).join("");
254
- return new Node("custom-node", name, 0, 0, children, value);
256
+ return new Node(type, name, 0, 0, children, value);
255
257
  }
256
258
  }
257
259
 
260
+ function compact(node, nodeMap) {
261
+ node.walkBreadthFirst(n => {
262
+ if (nodeMap[n.name]) {
263
+ n.compact();
264
+ }
265
+ });
266
+ return node;
267
+ }
268
+
269
+ function remove(node, nodeMap) {
270
+ node.walkBreadthFirst(n => {
271
+ if (nodeMap[n.name]) {
272
+ n.remove();
273
+ }
274
+ });
275
+ return node;
276
+ }
277
+
258
278
  /******************************************************************************
259
279
  Copyright (c) Microsoft Corporation.
260
280
 
@@ -511,6 +531,24 @@
511
531
  }
512
532
  }
513
533
 
534
+ function execPattern(pattern, text, record = false) {
535
+ const cursor = new Cursor(text);
536
+ record && cursor.startRecording();
537
+ const ast = pattern.parse(cursor);
538
+ const isMatch = (ast === null || ast === void 0 ? void 0 : ast.value.length) === text.length;
539
+ return {
540
+ ast: isMatch ? ast : null,
541
+ cursor
542
+ };
543
+ }
544
+
545
+ function testPattern(pattern, text, record = false) {
546
+ const cursor = new Cursor(text);
547
+ record && cursor.startRecording();
548
+ const ast = pattern.parse(cursor);
549
+ return (ast === null || ast === void 0 ? void 0 : ast.value.length) === text.length;
550
+ }
551
+
514
552
  let idIndex$9 = 0;
515
553
  class Literal {
516
554
  get id() {
@@ -538,7 +576,6 @@
538
576
  return this._firstIndex;
539
577
  }
540
578
  constructor(name, value) {
541
- this.shouldCompactAst = false;
542
579
  if (value.length === 0) {
543
580
  throw new Error("Value Cannot be empty.");
544
581
  }
@@ -553,19 +590,10 @@
553
590
  this._endIndex = 0;
554
591
  }
555
592
  test(text, record = false) {
556
- const cursor = new Cursor(text);
557
- record && cursor.startRecording();
558
- const ast = this.parse(cursor);
559
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
593
+ return testPattern(this, text, record);
560
594
  }
561
595
  exec(text, record = false) {
562
- const cursor = new Cursor(text);
563
- record && cursor.startRecording();
564
- const ast = this.parse(cursor);
565
- return {
566
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
567
- cursor
568
- };
596
+ return execPattern(this, text, record);
569
597
  }
570
598
  parse(cursor) {
571
599
  this._firstIndex = cursor.index;
@@ -608,7 +636,6 @@
608
636
  clone(name = this._name) {
609
637
  const clone = new Literal(name, this._token);
610
638
  clone._id = this._id;
611
- clone.shouldCompactAst = this.shouldCompactAst;
612
639
  return clone;
613
640
  }
614
641
  getTokens() {
@@ -675,7 +702,6 @@
675
702
  this._firstIndex = 0;
676
703
  this._substring = "";
677
704
  this._tokens = [];
678
- this.shouldCompactAst = false;
679
705
  this._id = `regex-${idIndex$8++}`;
680
706
  this._type = "regex";
681
707
  this._name = name;
@@ -695,19 +721,11 @@
695
721
  throw new Error("Invalid Arguments: The regex string cannot end with a '$' because it is expected to be in the middle of a string.");
696
722
  }
697
723
  }
698
- test(text) {
699
- const cursor = new Cursor(text);
700
- const ast = this.parse(cursor);
701
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
724
+ test(text, record = false) {
725
+ return testPattern(this, text, record);
702
726
  }
703
727
  exec(text, record = false) {
704
- const cursor = new Cursor(text);
705
- record && cursor.startRecording();
706
- const ast = this.parse(cursor);
707
- return {
708
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
709
- cursor
710
- };
728
+ return execPattern(this, text, record);
711
729
  }
712
730
  parse(cursor) {
713
731
  this._firstIndex = cursor.index;
@@ -745,7 +763,6 @@
745
763
  const clone = new Regex(name, this._originalRegexString);
746
764
  clone._tokens = this._tokens.slice();
747
765
  clone._id = this._id;
748
- clone.shouldCompactAst = this.shouldCompactAst;
749
766
  return clone;
750
767
  }
751
768
  getTokens() {
@@ -829,7 +846,6 @@
829
846
  return this._firstIndex;
830
847
  }
831
848
  constructor(name) {
832
- this.shouldCompactAst = false;
833
849
  this._id = `reference-${idIndex$7++}`;
834
850
  this._type = "reference";
835
851
  this._name = name;
@@ -839,19 +855,11 @@
839
855
  this._children = [];
840
856
  this._firstIndex = 0;
841
857
  }
842
- test(text) {
843
- const cursor = new Cursor(text);
844
- const ast = this.parse(cursor);
845
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
858
+ test(text, record = false) {
859
+ return testPattern(this, text, record);
846
860
  }
847
861
  exec(text, record = false) {
848
- const cursor = new Cursor(text);
849
- record && cursor.startRecording();
850
- const ast = this.parse(cursor);
851
- return {
852
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
853
- cursor
854
- };
862
+ return execPattern(this, text, record);
855
863
  }
856
864
  parse(cursor) {
857
865
  this._firstIndex = cursor.index;
@@ -952,7 +960,6 @@
952
960
  clone(name = this._name) {
953
961
  const clone = new Reference(name);
954
962
  clone._id = this._id;
955
- clone.shouldCompactAst = this.shouldCompactAst;
956
963
  // Optimize future clones, by caching the pattern we already found.
957
964
  if (this._pattern != null) {
958
965
  clone._cachedPattern = this._pattern;
@@ -1007,7 +1014,6 @@
1007
1014
  return this._firstIndex;
1008
1015
  }
1009
1016
  constructor(name, options, isGreedy = false) {
1010
- this.shouldCompactAst = false;
1011
1017
  if (options.length === 0) {
1012
1018
  throw new Error("Need at least one pattern with an 'options' pattern.");
1013
1019
  }
@@ -1026,19 +1032,11 @@
1026
1032
  child.parent = this;
1027
1033
  }
1028
1034
  }
1029
- test(text) {
1030
- const cursor = new Cursor(text);
1031
- const ast = this.parse(cursor);
1032
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
1035
+ test(text, record = false) {
1036
+ return testPattern(this, text, record);
1033
1037
  }
1034
1038
  exec(text, record = false) {
1035
- const cursor = new Cursor(text);
1036
- record && cursor.startRecording();
1037
- const ast = this.parse(cursor);
1038
- return {
1039
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
1040
- cursor
1041
- };
1039
+ return execPattern(this, text, record);
1042
1040
  }
1043
1041
  parse(cursor) {
1044
1042
  this._firstIndex = cursor.index;
@@ -1046,9 +1044,6 @@
1046
1044
  if (node != null) {
1047
1045
  cursor.moveTo(node.lastIndex);
1048
1046
  cursor.resolveError();
1049
- if (this.shouldCompactAst) {
1050
- node.compact();
1051
- }
1052
1047
  return node;
1053
1048
  }
1054
1049
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
@@ -1139,7 +1134,6 @@
1139
1134
  clone(name = this._name) {
1140
1135
  const clone = new Options(name, this._children, this._isGreedy);
1141
1136
  clone._id = this._id;
1142
- clone.shouldCompactAst = this.shouldCompactAst;
1143
1137
  return clone;
1144
1138
  }
1145
1139
  isEqual(pattern) {
@@ -1177,7 +1171,6 @@
1177
1171
  return this._firstIndex;
1178
1172
  }
1179
1173
  constructor(name, pattern, options = {}) {
1180
- this.shouldCompactAst = false;
1181
1174
  this._id = `finite-repeat-${idIndex$5++}`;
1182
1175
  this._type = "finite-repeat";
1183
1176
  this._name = name;
@@ -1250,24 +1243,13 @@
1250
1243
  cursor.resolveError();
1251
1244
  cursor.moveTo(lastIndex);
1252
1245
  const node = new Node(this._type, this.name, firstIndex, lastIndex, nodes);
1253
- if (this.shouldCompactAst) {
1254
- node.compact();
1255
- }
1256
1246
  return node;
1257
1247
  }
1258
- test(text) {
1259
- const cursor = new Cursor(text);
1260
- const ast = this.parse(cursor);
1261
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
1248
+ test(text, record = false) {
1249
+ return testPattern(this, text, record);
1262
1250
  }
1263
1251
  exec(text, record = false) {
1264
- const cursor = new Cursor(text);
1265
- record && cursor.startRecording();
1266
- const ast = this.parse(cursor);
1267
- return {
1268
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
1269
- cursor
1270
- };
1252
+ return execPattern(this, text, record);
1271
1253
  }
1272
1254
  clone(name = this._name) {
1273
1255
  let min = this._min;
@@ -1279,7 +1261,6 @@
1279
1261
  trimDivider: this._trimDivider
1280
1262
  });
1281
1263
  clone._id = this._id;
1282
- clone.shouldCompactAst = this.shouldCompactAst;
1283
1264
  return clone;
1284
1265
  }
1285
1266
  getTokens() {
@@ -1360,7 +1341,6 @@
1360
1341
  return this._firstIndex;
1361
1342
  }
1362
1343
  constructor(name, pattern, options = {}) {
1363
- this.shouldCompactAst = false;
1364
1344
  const min = options.min != null ? Math.max(options.min, 1) : 1;
1365
1345
  const divider = options.divider;
1366
1346
  let children;
@@ -1388,19 +1368,11 @@
1388
1368
  child.parent = this;
1389
1369
  }
1390
1370
  }
1391
- test(text) {
1392
- const cursor = new Cursor(text);
1393
- const ast = this.parse(cursor);
1394
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
1371
+ test(text, record = false) {
1372
+ return testPattern(this, text, record);
1395
1373
  }
1396
1374
  exec(text, record = false) {
1397
- const cursor = new Cursor(text);
1398
- record && cursor.startRecording();
1399
- const ast = this.parse(cursor);
1400
- return {
1401
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
1402
- cursor
1403
- };
1375
+ return execPattern(this, text, record);
1404
1376
  }
1405
1377
  parse(cursor) {
1406
1378
  this._firstIndex = cursor.index;
@@ -1412,9 +1384,6 @@
1412
1384
  if (node != null) {
1413
1385
  cursor.moveTo(node.lastIndex);
1414
1386
  cursor.recordMatch(this, node);
1415
- if (this.shouldCompactAst) {
1416
- node.compact();
1417
- }
1418
1387
  }
1419
1388
  return node;
1420
1389
  }
@@ -1593,7 +1562,6 @@
1593
1562
  trimDivider: this._trimDivider
1594
1563
  });
1595
1564
  clone._id = this._id;
1596
- clone.shouldCompactAst = this.shouldCompactAst;
1597
1565
  return clone;
1598
1566
  }
1599
1567
  isEqual(pattern) {
@@ -1603,13 +1571,6 @@
1603
1571
 
1604
1572
  let idIndex$3 = 0;
1605
1573
  class Repeat {
1606
- get shouldCompactAst() {
1607
- return this._shouldCompactAst;
1608
- }
1609
- set shouldCompactAst(value) {
1610
- this._shouldCompactAst = value;
1611
- this._repeatPattern.shouldCompactAst = value;
1612
- }
1613
1574
  get id() {
1614
1575
  return this._id;
1615
1576
  }
@@ -1641,7 +1602,6 @@
1641
1602
  this._id = `repeat-${idIndex$3++}`;
1642
1603
  this._pattern = pattern;
1643
1604
  this._parent = null;
1644
- this._shouldCompactAst = false;
1645
1605
  this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1646
1606
  if (this._options.max !== Infinity) {
1647
1607
  this._repeatPattern = new FiniteRepeat(name, pattern, this._options);
@@ -1665,7 +1625,6 @@
1665
1625
  let min = this._options.min;
1666
1626
  const clone = new Repeat(name, this._pattern, Object.assign(Object.assign({}, this._options), { min }));
1667
1627
  clone._id = this._id;
1668
- clone.shouldCompactAst = this.shouldCompactAst;
1669
1628
  return clone;
1670
1629
  }
1671
1630
  getTokens() {
@@ -1743,7 +1702,6 @@
1743
1702
  return this._firstIndex;
1744
1703
  }
1745
1704
  constructor(name, sequence) {
1746
- this.shouldCompactAst = false;
1747
1705
  if (sequence.length === 0) {
1748
1706
  throw new Error("Need at least one pattern with a 'sequence' pattern.");
1749
1707
  }
@@ -1762,19 +1720,11 @@
1762
1720
  child.parent = this;
1763
1721
  }
1764
1722
  }
1765
- test(text) {
1766
- const cursor = new Cursor(text);
1767
- const ast = this.parse(cursor);
1768
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
1723
+ test(text, record = false) {
1724
+ return testPattern(this, text, record);
1769
1725
  }
1770
1726
  exec(text, record = false) {
1771
- const cursor = new Cursor(text);
1772
- record && cursor.startRecording();
1773
- const ast = this.parse(cursor);
1774
- return {
1775
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
1776
- cursor
1777
- };
1727
+ return execPattern(this, text, record);
1778
1728
  }
1779
1729
  parse(cursor) {
1780
1730
  this._firstIndex = cursor.index;
@@ -1784,9 +1734,6 @@
1784
1734
  const node = this.createNode(cursor);
1785
1735
  if (node !== null) {
1786
1736
  cursor.recordMatch(this, node);
1787
- if (this.shouldCompactAst) {
1788
- node.compact();
1789
- }
1790
1737
  }
1791
1738
  return node;
1792
1739
  }
@@ -1974,7 +1921,6 @@
1974
1921
  clone(name = this._name) {
1975
1922
  const clone = new Sequence(name, this._children);
1976
1923
  clone._id = this._id;
1977
- clone.shouldCompactAst = this.shouldCompactAst;
1978
1924
  return clone;
1979
1925
  }
1980
1926
  isEqual(pattern) {
@@ -2037,7 +1983,6 @@
2037
1983
  return this._children[0].startedOnIndex;
2038
1984
  }
2039
1985
  constructor(name, pattern) {
2040
- this.shouldCompactAst = false;
2041
1986
  this._id = `optional-${idIndex$1++}`;
2042
1987
  this._type = "optional";
2043
1988
  this._name = name;
@@ -2068,16 +2013,12 @@
2068
2013
  return null;
2069
2014
  }
2070
2015
  else {
2071
- if (node != null && this.shouldCompactAst) {
2072
- node.compact();
2073
- }
2074
2016
  return node;
2075
2017
  }
2076
2018
  }
2077
2019
  clone(name = this._name) {
2078
2020
  const clone = new Optional(name, this._children[0]);
2079
2021
  clone._id = this._id;
2080
- clone.shouldCompactAst = this.shouldCompactAst;
2081
2022
  return clone;
2082
2023
  }
2083
2024
  getTokens() {
@@ -2227,9 +2168,6 @@
2227
2168
 
2228
2169
  const optionalSpaces$2 = new Optional("optional-spaces", spaces$1);
2229
2170
  const assignOperator = new Literal("assign-operator", "=");
2230
- const compact = new Literal("compact", "compact");
2231
- const compactModifier = new Sequence("compact-modifier", [lineSpaces$1, compact]);
2232
- const optionalCompactModifier = new Optional("optional-compact-modifier", compactModifier);
2233
2171
  const assignStatement = new Sequence("assign-statement", [
2234
2172
  optionalSpaces$2,
2235
2173
  name$1,
@@ -2237,7 +2175,6 @@
2237
2175
  assignOperator,
2238
2176
  optionalSpaces$2,
2239
2177
  pattern,
2240
- optionalCompactModifier
2241
2178
  ]);
2242
2179
  const statement = new Options("statement", [assignStatement, name$1.clone("export-name")]);
2243
2180
 
@@ -2361,7 +2298,6 @@
2361
2298
  return this.children[0].startedOnIndex;
2362
2299
  }
2363
2300
  constructor(name, pattern) {
2364
- this.shouldCompactAst = false;
2365
2301
  this._id = `not-${idIndex++}`;
2366
2302
  this._type = "not";
2367
2303
  this._name = name;
@@ -2369,19 +2305,11 @@
2369
2305
  this._children = [pattern.clone()];
2370
2306
  this._children[0].parent = this;
2371
2307
  }
2372
- test(text) {
2373
- const cursor = new Cursor(text);
2374
- this.parse(cursor);
2375
- return !cursor.hasError;
2308
+ test(text, record = false) {
2309
+ return testPattern(this, text, record);
2376
2310
  }
2377
2311
  exec(text, record = false) {
2378
- const cursor = new Cursor(text);
2379
- record && cursor.startRecording();
2380
- const ast = this.parse(cursor);
2381
- return {
2382
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
2383
- cursor
2384
- };
2312
+ return execPattern(this, text, record);
2385
2313
  }
2386
2314
  parse(cursor) {
2387
2315
  const firstIndex = cursor.index;
@@ -2774,15 +2702,163 @@
2774
2702
  }
2775
2703
  }
2776
2704
 
2777
- let indexId = 0;
2778
- function createNode(name, children) {
2779
- return new Node("expression", name, 0, 0, children, "");
2780
- }
2781
2705
  var Association;
2782
2706
  (function (Association) {
2783
2707
  Association[Association["left"] = 0] = "left";
2784
2708
  Association[Association["right"] = 1] = "right";
2785
2709
  })(Association || (Association = {}));
2710
+ class PrecedenceTree {
2711
+ constructor(precedenceMap = {}, associationMap = {}) {
2712
+ this._prefixPlaceholder = Node.createNode("placeholder", "prefix-placeholder");
2713
+ this._prefixNode = null;
2714
+ this._postfixPlaceholder = Node.createNode("placeholder", "postfix-placeholder");
2715
+ this._postfixNode = null;
2716
+ this._binaryPlaceholder = Node.createNode("placeholder", "binary-placeholder");
2717
+ this._atomNode = null;
2718
+ this._binaryNode = null;
2719
+ this._orphanedAtom = null;
2720
+ this._precedenceMap = precedenceMap;
2721
+ this._associationMap = associationMap;
2722
+ }
2723
+ addPrefix(name, ...prefix) {
2724
+ const lastPrefixNode = this._prefixNode;
2725
+ if (lastPrefixNode == null) {
2726
+ const node = Node.createNode("expression", name, [...prefix]);
2727
+ this._prefixNode = node;
2728
+ this._prefixNode.append(this._prefixPlaceholder);
2729
+ return;
2730
+ }
2731
+ const node = Node.createNode("expression", name, [...prefix]);
2732
+ this._prefixPlaceholder.replaceWith(node);
2733
+ node.append(this._prefixPlaceholder);
2734
+ this._prefixNode = node;
2735
+ }
2736
+ addPostfix(name, ...postfix) {
2737
+ const lastPostfixNode = this._postfixNode;
2738
+ if (lastPostfixNode == null) {
2739
+ const node = Node.createNode("expression", name, [this._postfixPlaceholder, ...postfix]);
2740
+ this._postfixNode = node;
2741
+ return;
2742
+ }
2743
+ const node = Node.createNode("expression", name, [lastPostfixNode, ...postfix]);
2744
+ this._postfixNode = node;
2745
+ }
2746
+ addBinary(name, ...delimiterNode) {
2747
+ const lastBinaryNode = this._binaryNode;
2748
+ const lastPrecendece = this._getPrecedenceFromNode(this._binaryNode);
2749
+ const precedence = this._getPrecedence(name);
2750
+ const association = this._associationMap[name];
2751
+ const lastAtomNode = this._compileAtomNode();
2752
+ if (lastAtomNode == null) {
2753
+ throw new Error("Cannot add a binary without an atom node.");
2754
+ }
2755
+ this._binaryPlaceholder.remove();
2756
+ this._orphanedAtom = lastAtomNode;
2757
+ if (lastBinaryNode == null) {
2758
+ const node = Node.createNode("expression", name, [lastAtomNode, ...delimiterNode, this._binaryPlaceholder]);
2759
+ this._binaryNode = node;
2760
+ return;
2761
+ }
2762
+ if (precedence === lastPrecendece && association === Association.right) {
2763
+ const node = Node.createNode("expression", name, [lastAtomNode, ...delimiterNode, this._binaryPlaceholder]);
2764
+ lastBinaryNode.appendChild(node);
2765
+ this._binaryNode = node;
2766
+ }
2767
+ else if (precedence === lastPrecendece) {
2768
+ const node = Node.createNode("expression", name, []);
2769
+ lastBinaryNode.replaceWith(node);
2770
+ lastBinaryNode.appendChild(lastAtomNode);
2771
+ node.append(lastBinaryNode, ...delimiterNode, this._binaryPlaceholder);
2772
+ this._binaryNode = node;
2773
+ }
2774
+ else if (precedence > lastPrecendece) {
2775
+ let ancestor = lastBinaryNode.parent;
2776
+ let root = lastBinaryNode;
2777
+ while (ancestor != null) {
2778
+ const nodePrecedence = this._precedenceMap[ancestor.name];
2779
+ if (nodePrecedence > precedence) {
2780
+ break;
2781
+ }
2782
+ root = ancestor;
2783
+ ancestor = ancestor.parent;
2784
+ }
2785
+ lastBinaryNode.appendChild(lastAtomNode);
2786
+ const node = Node.createNode("expression", name, []);
2787
+ root.replaceWith(node);
2788
+ node.append(root, ...delimiterNode, this._binaryPlaceholder);
2789
+ this._binaryNode = node;
2790
+ }
2791
+ else {
2792
+ const node = Node.createNode("expression", name, [lastAtomNode, ...delimiterNode, this._binaryPlaceholder]);
2793
+ lastBinaryNode.appendChild(node);
2794
+ this._binaryNode = node;
2795
+ }
2796
+ }
2797
+ _getPrecedenceFromNode(node) {
2798
+ if (node == null) {
2799
+ return 0;
2800
+ }
2801
+ return this._getPrecedence(node.name);
2802
+ }
2803
+ _getPrecedence(name) {
2804
+ if (this._precedenceMap[name] != null) {
2805
+ return this._precedenceMap[name];
2806
+ }
2807
+ return 0;
2808
+ }
2809
+ _compileAtomNode() {
2810
+ let node = this._atomNode;
2811
+ if (this._prefixNode != null && this._atomNode != null) {
2812
+ node = this._prefixNode;
2813
+ this._prefixPlaceholder.replaceWith(this._atomNode);
2814
+ }
2815
+ if (this._postfixNode != null && node != null) {
2816
+ this._postfixPlaceholder.replaceWith(node);
2817
+ node = this._postfixNode;
2818
+ }
2819
+ this._prefixNode = null;
2820
+ this._atomNode = null;
2821
+ this._postfixNode = null;
2822
+ if (node == null) {
2823
+ return null;
2824
+ }
2825
+ return node.findRoot();
2826
+ }
2827
+ addAtom(node) {
2828
+ this._atomNode = node;
2829
+ }
2830
+ hasAtom() {
2831
+ return this._atomNode != null;
2832
+ }
2833
+ commit() {
2834
+ var _a;
2835
+ if (this._binaryNode == null) {
2836
+ return this._compileAtomNode();
2837
+ }
2838
+ const atomNode = this._compileAtomNode();
2839
+ if (atomNode == null) {
2840
+ let root = this._binaryPlaceholder.findRoot();
2841
+ (_a = this._binaryPlaceholder.parent) === null || _a === void 0 ? void 0 : _a.replaceWith(this._orphanedAtom);
2842
+ this.reset();
2843
+ return root;
2844
+ }
2845
+ else {
2846
+ this._binaryPlaceholder.replaceWith(atomNode);
2847
+ const root = this._binaryNode.findRoot();
2848
+ this.reset();
2849
+ return root;
2850
+ }
2851
+ }
2852
+ reset() {
2853
+ this._prefixNode = null;
2854
+ this._atomNode = null;
2855
+ this._orphanedAtom = null;
2856
+ this._postfixNode = null;
2857
+ this._binaryNode = null;
2858
+ }
2859
+ }
2860
+
2861
+ let indexId = 0;
2786
2862
  class ExpressionPattern {
2787
2863
  get id() {
2788
2864
  return this._id;
@@ -2802,23 +2878,22 @@
2802
2878
  get children() {
2803
2879
  return this._patterns;
2804
2880
  }
2805
- get unaryPrefixPatterns() {
2806
- return this._unaryPrefixPatterns;
2881
+ get prefixPatterns() {
2882
+ return this._prefixPatterns;
2807
2883
  }
2808
2884
  get atomPatterns() {
2809
2885
  return this._atomPatterns;
2810
2886
  }
2887
+ get postfixPatterns() {
2888
+ return this._postfixPatterns;
2889
+ }
2811
2890
  get binaryPatterns() {
2812
2891
  return this._binaryPatterns;
2813
2892
  }
2814
- get recursivePatterns() {
2815
- return this._recursivePatterns;
2816
- }
2817
2893
  get startedOnIndex() {
2818
2894
  return this._firstIndex;
2819
2895
  }
2820
2896
  constructor(name, patterns) {
2821
- this.shouldCompactAst = false;
2822
2897
  if (patterns.length === 0) {
2823
2898
  throw new Error("Need at least one pattern with an 'expression' pattern.");
2824
2899
  }
@@ -2828,369 +2903,277 @@
2828
2903
  this._parent = null;
2829
2904
  this._firstIndex = -1;
2830
2905
  this._atomPatterns = [];
2831
- this._unaryPrefixPatterns = [];
2832
- this._unaryPrefixNames = [];
2906
+ this._prefixPatterns = [];
2907
+ this._prefixNames = [];
2908
+ this._postfixPatterns = [];
2909
+ this._postfixNames = [];
2833
2910
  this._binaryPatterns = [];
2834
- this._recursivePatterns = [];
2835
- this._recursiveNames = [];
2836
- this._endsInRecursion = [];
2837
2911
  this._binaryNames = [];
2838
- this._binaryAssociation = [];
2912
+ this.associationMap = {};
2839
2913
  this._precedenceMap = {};
2840
2914
  this._originalPatterns = patterns;
2841
- this._shouldCompactPatternsMap = {};
2842
2915
  this._patterns = this._organizePatterns(patterns);
2916
+ this._shouldStopParsing = false;
2917
+ this._precedenceTree = new PrecedenceTree(this._precedenceMap, this.associationMap);
2843
2918
  if (this._atomPatterns.length === 0) {
2844
- throw new Error("Need at least one operand pattern with an 'expression' pattern.");
2919
+ throw new Error("Need at least one terminating pattern with an 'expression' pattern.");
2845
2920
  }
2846
2921
  }
2847
2922
  _organizePatterns(patterns) {
2848
2923
  const finalPatterns = [];
2849
2924
  patterns.forEach((pattern) => {
2850
- this._shouldCompactPatternsMap[pattern.name] = pattern.shouldCompactAst;
2851
- if (this._isUnary(pattern)) {
2852
- const unaryPrefix = this._extractUnaryPrefixPattern(pattern).clone();
2853
- this._unaryPrefixPatterns.push(unaryPrefix);
2854
- this._unaryPrefixNames.push(pattern.name);
2855
- unaryPrefix.parent = this;
2856
- finalPatterns.push(unaryPrefix);
2925
+ if (this._isAtom(pattern)) {
2926
+ const atom = pattern.clone();
2927
+ atom.parent = this;
2928
+ this._atomPatterns.push(atom);
2929
+ finalPatterns.push(atom);
2930
+ }
2931
+ else if (this._isPrefix(pattern)) {
2932
+ const name = this._extractName(pattern);
2933
+ const prefix = this._extractPrefix(pattern);
2934
+ prefix.parent = this;
2935
+ this._prefixPatterns.push(prefix);
2936
+ this._prefixNames.push(name);
2937
+ finalPatterns.push(prefix);
2938
+ }
2939
+ else if (this._isPostfix(pattern)) {
2940
+ const name = this._extractName(pattern);
2941
+ const postfix = this._extractPostfix(pattern);
2942
+ postfix.parent = this;
2943
+ this._postfixPatterns.push(postfix);
2944
+ this._postfixNames.push(name);
2945
+ finalPatterns.push(postfix);
2857
2946
  }
2858
2947
  else if (this._isBinary(pattern)) {
2859
- const binaryName = this._extractName(pattern);
2860
- const clone = this._extractDelimiter(pattern).clone();
2948
+ const name = this._extractName(pattern);
2949
+ const clone = this._extractBinary(pattern);
2861
2950
  clone.parent = this;
2862
- this._precedenceMap[binaryName] = this._binaryPatterns.length;
2951
+ this._precedenceMap[name] = this._binaryPatterns.length;
2863
2952
  this._binaryPatterns.push(clone);
2864
- this._binaryNames.push(binaryName);
2953
+ this._binaryNames.push(name);
2865
2954
  if (pattern.type === "right-associated") {
2866
- this._binaryAssociation.push(Association.right);
2955
+ this.associationMap[name] = Association.right;
2867
2956
  }
2868
2957
  else {
2869
- this._binaryAssociation.push(Association.left);
2958
+ this.associationMap[name] = Association.left;
2870
2959
  }
2871
2960
  finalPatterns.push(clone);
2872
2961
  }
2873
- else if (this._isRecursive(pattern)) {
2874
- const name = this._extractName(pattern);
2875
- const tail = this._extractRecursiveTail(pattern);
2876
- tail.parent = this;
2877
- this._recursivePatterns.push(tail);
2878
- this._recursiveNames.push(name);
2879
- this._endsInRecursion.push(this._endsWithRecursion(pattern));
2880
- finalPatterns.push(tail);
2881
- }
2882
- else {
2883
- const clone = pattern.clone();
2884
- clone.parent = this;
2885
- this._atomPatterns.push(clone);
2886
- finalPatterns.push(clone);
2887
- }
2888
2962
  });
2889
2963
  return finalPatterns;
2890
2964
  }
2891
- _isBinary(pattern) {
2892
- if (pattern.type === "right-associated" && this._isBinaryPattern(pattern.children[0])) {
2893
- return true;
2894
- }
2895
- return this._isBinaryPattern(pattern);
2896
- }
2897
- _isBinaryPattern(pattern) {
2898
- return pattern.type === "sequence" &&
2899
- pattern.children.length === 3 &&
2900
- pattern.children[0].type === "reference" &&
2901
- pattern.children[0].name === this.name &&
2902
- pattern.children[2].type === "reference" &&
2903
- pattern.children[2].name === this.name;
2904
- }
2905
- _extractDelimiter(pattern) {
2906
- if (pattern.type === "right-associated") {
2907
- return pattern.children[0].children[1];
2908
- }
2909
- return pattern.children[1];
2910
- }
2911
2965
  _extractName(pattern) {
2912
2966
  if (pattern.type === "right-associated") {
2913
2967
  return pattern.children[0].name;
2914
2968
  }
2915
2969
  return pattern.name;
2916
2970
  }
2917
- _isUnary(pattern) {
2918
- if (pattern.type === "right-associated" && this._isUnaryPattern(pattern.children[0])) {
2919
- return true;
2920
- }
2921
- return this._isUnaryPattern(pattern);
2922
- }
2923
- _isUnaryPattern(pattern) {
2924
- return pattern.type === "sequence" &&
2925
- pattern.children[0].type !== "reference" &&
2926
- pattern.children[0].name !== this.name &&
2927
- pattern.children[1].type === "reference" &&
2928
- pattern.children[1].name === this.name &&
2929
- pattern.children.length === 2;
2930
- }
2931
- _extractUnaryPrefixPattern(pattern) {
2932
- if (pattern.type === "right-associated") {
2933
- return pattern.children[0].children[0];
2934
- }
2935
- return pattern.children[0];
2971
+ _isPrefix(pattern) {
2972
+ pattern = this._unwrapAssociationIfNecessary(pattern);
2973
+ const lastChild = pattern.children[pattern.children.length - 1];
2974
+ const referenceCount = this._referenceCount(pattern);
2975
+ const lastChildIsReference = this._isRecursiveReference(lastChild);
2976
+ return lastChildIsReference &&
2977
+ referenceCount === 1;
2978
+ }
2979
+ _extractPrefix(pattern) {
2980
+ pattern = this._unwrapAssociationIfNecessary(pattern);
2981
+ return new Sequence(`${pattern.name}-prefix`, pattern.children.slice(0, -1));
2982
+ }
2983
+ _isAtom(pattern) {
2984
+ pattern = this._unwrapAssociationIfNecessary(pattern);
2985
+ const firstChild = pattern.children[0];
2986
+ const lastChild = pattern.children[1];
2987
+ const firstChildIsReference = this._isRecursiveReference(firstChild);
2988
+ const lastChildIsReference = this._isRecursiveReference(lastChild);
2989
+ return !firstChildIsReference && !lastChildIsReference;
2990
+ }
2991
+ _isPostfix(pattern) {
2992
+ pattern = this._unwrapAssociationIfNecessary(pattern);
2993
+ const firstChild = pattern.children[0];
2994
+ const referenceCount = this._referenceCount(pattern);
2995
+ const firstChildIsReference = this._isRecursiveReference(firstChild);
2996
+ return firstChildIsReference &&
2997
+ referenceCount === 1;
2998
+ }
2999
+ _extractPostfix(pattern) {
3000
+ pattern = this._unwrapAssociationIfNecessary(pattern);
3001
+ return new Sequence(`${pattern.name}-postfix`, pattern.children.slice(1));
2936
3002
  }
2937
- _isRecursive(pattern) {
2938
- if (pattern.type === "right-associated" && this._isRecursivePattern(pattern.children[0])) {
2939
- return true;
2940
- }
2941
- return this._isRecursivePattern(pattern);
3003
+ _isBinary(pattern) {
3004
+ pattern = this._unwrapAssociationIfNecessary(pattern);
3005
+ const firstChild = pattern.children[0];
3006
+ const lastChild = pattern.children[pattern.children.length - 1];
3007
+ const firstChildIsReference = this._isRecursiveReference(firstChild);
3008
+ const lastChildIsReference = this._isRecursiveReference(lastChild);
3009
+ return firstChildIsReference && lastChildIsReference && pattern.children.length > 2;
2942
3010
  }
2943
- _isRecursivePattern(pattern) {
2944
- return pattern.type === "sequence" &&
2945
- pattern.children[0].type === "reference" &&
2946
- pattern.children[0].name === this.name &&
2947
- pattern.children.length > 2;
3011
+ _extractBinary(pattern) {
3012
+ pattern = this._unwrapAssociationIfNecessary(pattern);
3013
+ const children = pattern.children.slice(1, -1);
3014
+ const binarySequence = new Sequence(`${pattern.name}-delimiter`, children);
3015
+ return binarySequence;
2948
3016
  }
2949
- _extractRecursiveTail(pattern) {
3017
+ _unwrapAssociationIfNecessary(pattern) {
2950
3018
  if (pattern.type === "right-associated") {
2951
- return new Sequence(`${pattern.children[0].name}-tail`, pattern.children[0].children.slice(1));
3019
+ return pattern.children[0];
2952
3020
  }
2953
- return new Sequence(`${pattern.name}-tail`, pattern.children.slice(1));
3021
+ return pattern;
2954
3022
  }
2955
- _endsWithRecursion(pattern) {
2956
- if (pattern.type === "right-associated") {
2957
- pattern = pattern.children[0];
3023
+ _referenceCount(pattern) {
3024
+ return pattern.children.filter(p => this._isRecursiveReference(p)).length;
3025
+ }
3026
+ _isRecursiveReference(pattern) {
3027
+ if (pattern == null) {
3028
+ return false;
2958
3029
  }
2959
- const lastChild = pattern.children[pattern.children.length - 1];
2960
- return pattern.type === "sequence" &&
2961
- pattern.children.length > 1 &&
2962
- lastChild.type === "reference" &&
2963
- lastChild.name === this.name;
3030
+ return pattern.type === "reference" && pattern.name === this.name;
2964
3031
  }
2965
3032
  parse(cursor) {
2966
3033
  this._firstIndex = cursor.index;
2967
3034
  const node = this._tryToParse(cursor);
2968
3035
  if (node != null) {
3036
+ node.normalize(this._firstIndex);
2969
3037
  cursor.moveTo(node.lastIndex);
2970
3038
  cursor.resolveError();
2971
- this._compactResult(node);
2972
3039
  return node;
2973
3040
  }
2974
3041
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
2975
3042
  return null;
2976
3043
  }
2977
- _compactResult(node) {
2978
- if (node == null) {
2979
- return;
2980
- }
2981
- if (this.shouldCompactAst) {
2982
- node.compact();
2983
- return;
2984
- }
2985
- // This could be really expensive with large trees. So we optimize with these checks,
2986
- // as well as use breadth first as to not recompact nodes over and over again.
2987
- const isCompactingNeeded = Object.values(this._shouldCompactPatternsMap).some(p => p);
2988
- if (isCompactingNeeded) {
2989
- node.walkBreadthFirst(n => {
2990
- if (this._shouldCompactPatternsMap[n.name]) {
2991
- n.compact();
2992
- }
2993
- });
2994
- }
2995
- }
2996
3044
  _tryToParse(cursor) {
2997
3045
  if (this._isBeyondRecursiveAllowance()) {
2998
3046
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
2999
3047
  return null;
3000
3048
  }
3001
- let lastAtomNode = null;
3002
- let lastBinaryNode = null;
3003
- let onIndex = cursor.index;
3004
- outer: while (true) {
3049
+ this._shouldStopParsing = false;
3050
+ while (true) {
3005
3051
  cursor.resolveError();
3006
- onIndex = cursor.index;
3007
- let prefix = null;
3008
- let prefixName = "";
3009
- for (let i = 0; i < this._unaryPrefixPatterns.length; i++) {
3010
- cursor.moveTo(onIndex);
3011
- const pattern = this._unaryPrefixPatterns[i];
3012
- const node = pattern.parse(cursor);
3013
- if (node != null) {
3014
- prefix = node;
3015
- prefixName = this._unaryPrefixNames[i];
3016
- if (cursor.hasNext()) {
3017
- cursor.next();
3018
- }
3019
- else {
3020
- break outer;
3021
- }
3052
+ this._tryToMatchPrefix(cursor);
3053
+ if (this._shouldStopParsing) {
3054
+ break;
3055
+ }
3056
+ this._tryToMatchAtom(cursor);
3057
+ if (this._shouldStopParsing) {
3058
+ break;
3059
+ }
3060
+ this._tryToMatchPostfix(cursor);
3061
+ if (this._shouldStopParsing) {
3062
+ break;
3063
+ }
3064
+ if (this._precedenceTree.hasAtom()) {
3065
+ this._tryToMatchBinary(cursor);
3066
+ if (this._shouldStopParsing) {
3022
3067
  break;
3023
3068
  }
3069
+ }
3070
+ else {
3071
+ break;
3072
+ }
3073
+ }
3074
+ return this._precedenceTree.commit();
3075
+ }
3076
+ _tryToMatchPrefix(cursor) {
3077
+ let onIndex = cursor.index;
3078
+ for (let i = 0; i < this._prefixPatterns.length; i++) {
3079
+ const pattern = this._prefixPatterns[i];
3080
+ const name = this._prefixNames[i];
3081
+ const node = pattern.parse(cursor);
3082
+ if (node != null) {
3083
+ this._precedenceTree.addPrefix(name, ...node.children);
3084
+ if (cursor.hasNext()) {
3085
+ cursor.next();
3086
+ onIndex = cursor.index;
3087
+ i = -1;
3088
+ continue;
3089
+ }
3024
3090
  else {
3025
- cursor.resolveError();
3091
+ this._shouldStopParsing = true;
3092
+ break;
3026
3093
  }
3027
3094
  }
3028
- onIndex = cursor.index;
3029
- for (let i = 0; i < this._atomPatterns.length; i++) {
3095
+ else {
3030
3096
  cursor.moveTo(onIndex);
3031
- const pattern = this._atomPatterns[i];
3032
- const node = pattern.parse(cursor);
3033
- if (node != null) {
3034
- lastAtomNode = node;
3035
- break;
3097
+ cursor.resolveError();
3098
+ }
3099
+ }
3100
+ }
3101
+ _tryToMatchAtom(cursor) {
3102
+ let onIndex = cursor.index;
3103
+ for (let i = 0; i < this._atomPatterns.length; i++) {
3104
+ cursor.moveTo(onIndex);
3105
+ const pattern = this._atomPatterns[i];
3106
+ const node = pattern.parse(cursor);
3107
+ if (node != null) {
3108
+ this._precedenceTree.addAtom(node);
3109
+ if (cursor.hasNext()) {
3110
+ cursor.next();
3036
3111
  }
3037
3112
  else {
3038
- lastAtomNode = null;
3039
- cursor.resolveError();
3113
+ this._shouldStopParsing = true;
3040
3114
  }
3041
- }
3042
- if (lastAtomNode == null) {
3043
3115
  break;
3044
3116
  }
3045
- if (cursor.hasNext()) {
3046
- cursor.next();
3047
- }
3048
3117
  else {
3049
- if (lastBinaryNode != null && lastAtomNode != null) {
3050
- if (prefix != null) {
3051
- lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3052
- }
3053
- lastBinaryNode.appendChild(lastAtomNode);
3054
- }
3055
- break;
3056
- }
3057
- onIndex = cursor.index;
3058
- if (prefix != null && this._recursivePatterns.length === 0) {
3059
- lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3060
- }
3061
- for (let i = 0; i < this._recursivePatterns.length; i++) {
3062
- const pattern = this._recursivePatterns[i];
3063
- const node = pattern.parse(cursor);
3064
- if (node != null) {
3065
- const name = this._recursiveNames[i];
3066
- if (this._endsInRecursion[i]) {
3067
- if (lastBinaryNode != null && lastAtomNode != null) {
3068
- if (prefix != null) {
3069
- lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3070
- }
3071
- lastBinaryNode.appendChild(lastAtomNode);
3072
- }
3073
- const frontExpression = lastBinaryNode == null ? lastAtomNode : lastBinaryNode.findRoot();
3074
- const recursiveNode = createNode(name, [frontExpression, ...node.children]);
3075
- recursiveNode.normalize(this._firstIndex);
3076
- return recursiveNode;
3077
- }
3078
- else {
3079
- if (prefix != null) {
3080
- lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3081
- }
3082
- const recursiveNode = createNode(name, [lastAtomNode, ...node.children]);
3083
- recursiveNode.normalize(lastAtomNode.startIndex);
3084
- lastAtomNode = recursiveNode;
3085
- if (cursor.hasNext()) {
3086
- cursor.next();
3087
- }
3088
- else {
3089
- if (lastBinaryNode != null && lastAtomNode != null) {
3090
- lastBinaryNode.appendChild(lastAtomNode);
3091
- }
3092
- break outer;
3093
- }
3094
- onIndex = cursor.index;
3095
- i = -1;
3096
- continue;
3097
- }
3098
- }
3099
3118
  cursor.resolveError();
3100
3119
  cursor.moveTo(onIndex);
3101
3120
  }
3102
- onIndex = cursor.index;
3103
- for (let i = 0; i < this._binaryPatterns.length; i++) {
3104
- cursor.resolveError();
3105
- cursor.moveTo(onIndex);
3106
- const pattern = this._binaryPatterns[i];
3107
- const name = this._binaryNames[i];
3108
- const delimiterNode = pattern.parse(cursor);
3109
- if (delimiterNode == null) {
3110
- if (i === this._binaryPatterns.length - 1) {
3111
- if (lastBinaryNode == null) {
3112
- return lastAtomNode;
3113
- }
3114
- else if (lastAtomNode != null) {
3115
- lastBinaryNode.appendChild(lastAtomNode);
3116
- }
3117
- }
3121
+ }
3122
+ }
3123
+ _tryToMatchPostfix(cursor) {
3124
+ let onIndex = cursor.index;
3125
+ for (let i = 0; i < this._postfixPatterns.length; i++) {
3126
+ const pattern = this._postfixPatterns[i];
3127
+ const name = this._postfixNames[i];
3128
+ const node = pattern.parse(cursor);
3129
+ if (node != null) {
3130
+ this._precedenceTree.addPostfix(name, ...node.children);
3131
+ if (cursor.hasNext()) {
3132
+ cursor.next();
3133
+ onIndex = cursor.index;
3134
+ i = -1;
3118
3135
  continue;
3119
3136
  }
3120
- if (lastBinaryNode == null && lastAtomNode != null && delimiterNode != null) {
3121
- const node = createNode(name, [lastAtomNode, delimiterNode]);
3122
- lastBinaryNode = node;
3123
- }
3124
- else if (lastBinaryNode != null && lastAtomNode != null && delimiterNode != null) {
3125
- const precedence = this._precedenceMap[name];
3126
- const lastPrecendece = lastBinaryNode == null ? 0 : this._precedenceMap[lastBinaryNode.name] == null ? -1 : this._precedenceMap[lastBinaryNode.name];
3127
- const association = this._binaryAssociation[i];
3128
- if (precedence === lastPrecendece && association === Association.right) {
3129
- const node = createNode(name, [lastAtomNode, delimiterNode]);
3130
- lastBinaryNode.appendChild(node);
3131
- lastBinaryNode = node;
3132
- }
3133
- else if (precedence === lastPrecendece) {
3134
- const node = createNode(name, []);
3135
- lastBinaryNode.replaceWith(node);
3136
- lastBinaryNode.appendChild(lastAtomNode);
3137
- node.append(lastBinaryNode, delimiterNode);
3138
- lastBinaryNode = node;
3139
- }
3140
- else if (precedence > lastPrecendece) {
3141
- let ancestor = lastBinaryNode.parent;
3142
- let root = lastBinaryNode;
3143
- while (ancestor != null) {
3144
- const nodePrecedence = this._precedenceMap[ancestor.name];
3145
- if (nodePrecedence > precedence) {
3146
- break;
3147
- }
3148
- root = ancestor;
3149
- ancestor = ancestor.parent;
3150
- }
3151
- lastBinaryNode.appendChild(lastAtomNode);
3152
- if (root != null) {
3153
- const node = createNode(name, []);
3154
- root.replaceWith(node);
3155
- node.append(root, delimiterNode);
3156
- lastBinaryNode = node;
3157
- }
3158
- else {
3159
- const node = createNode(name, [lastAtomNode, delimiterNode]);
3160
- lastBinaryNode = node;
3161
- }
3162
- }
3163
- else {
3164
- const node = createNode(name, [lastAtomNode, delimiterNode]);
3165
- lastBinaryNode.appendChild(node);
3166
- lastBinaryNode = node;
3167
- }
3137
+ else {
3138
+ this._shouldStopParsing = true;
3139
+ break;
3168
3140
  }
3141
+ }
3142
+ else {
3143
+ cursor.moveTo(onIndex);
3144
+ cursor.resolveError();
3145
+ }
3146
+ }
3147
+ }
3148
+ _tryToMatchBinary(cursor) {
3149
+ let onIndex = cursor.index;
3150
+ let foundMatch = false;
3151
+ if (this.binaryPatterns.length === 0) {
3152
+ this._shouldStopParsing = true;
3153
+ }
3154
+ for (let i = 0; i < this._binaryPatterns.length; i++) {
3155
+ cursor.moveTo(onIndex);
3156
+ const pattern = this._binaryPatterns[i];
3157
+ const name = this._binaryNames[i];
3158
+ const node = pattern.parse(cursor);
3159
+ if (node != null) {
3160
+ foundMatch = true;
3161
+ this._precedenceTree.addBinary(name, ...node.children);
3169
3162
  if (cursor.hasNext()) {
3170
3163
  cursor.next();
3171
3164
  }
3172
3165
  else {
3173
- break outer;
3166
+ this._shouldStopParsing = true;
3174
3167
  }
3175
3168
  break;
3176
3169
  }
3177
- if (lastBinaryNode == null) {
3178
- break;
3170
+ else {
3171
+ cursor.resolveError();
3172
+ cursor.moveTo(onIndex);
3179
3173
  }
3180
3174
  }
3181
- if (lastBinaryNode == null) {
3182
- return lastAtomNode;
3183
- }
3184
- else {
3185
- const root = lastBinaryNode.findAncestor(n => n.parent == null) || lastBinaryNode;
3186
- if (lastBinaryNode.children.length < 3) {
3187
- lastBinaryNode.remove();
3188
- if (lastBinaryNode === root) {
3189
- return lastAtomNode;
3190
- }
3191
- }
3192
- root.normalize(this._firstIndex);
3193
- return root;
3175
+ if (!foundMatch) {
3176
+ this._shouldStopParsing = true;
3194
3177
  }
3195
3178
  }
3196
3179
  _isBeyondRecursiveAllowance() {
@@ -3207,40 +3190,16 @@
3207
3190
  }
3208
3191
  return false;
3209
3192
  }
3210
- test(text) {
3211
- const cursor = new Cursor(text);
3212
- const ast = this.parse(cursor);
3213
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
3193
+ test(text, record = false) {
3194
+ return testPattern(this, text, record);
3214
3195
  }
3215
3196
  exec(text, record = false) {
3216
- const cursor = new Cursor(text);
3217
- record && cursor.startRecording();
3218
- const ast = this.parse(cursor);
3219
- return {
3220
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
3221
- cursor
3222
- };
3197
+ return execPattern(this, text, record);
3223
3198
  }
3224
3199
  getTokens() {
3225
3200
  return this.atomPatterns.map(p => p.getTokens()).flat();
3226
3201
  }
3227
- getTokensAfter(childReference) {
3228
- if (this.atomPatterns.indexOf(childReference)) {
3229
- const recursiveTokens = this._recursivePatterns.map(p => p.getTokens()).flat();
3230
- const binaryTokens = this._binaryPatterns.map(p => p.getTokens()).flat();
3231
- return [...recursiveTokens, ...binaryTokens];
3232
- }
3233
- if (this.recursivePatterns.indexOf(childReference)) {
3234
- return this._binaryPatterns.map(p => p.getTokens()).flat();
3235
- }
3236
- if (this.binaryPatterns.indexOf(childReference)) {
3237
- const unaryTokens = this._atomPatterns.map(p => p.getTokens()).flat();
3238
- if (this._parent != null) {
3239
- const nextTokens = this._parent.getTokensAfter(this);
3240
- return [...unaryTokens, ...nextTokens];
3241
- }
3242
- return unaryTokens;
3243
- }
3202
+ getTokensAfter(_childReference) {
3244
3203
  return [];
3245
3204
  }
3246
3205
  getNextTokens() {
@@ -3252,23 +3211,7 @@
3252
3211
  getPatterns() {
3253
3212
  return this.atomPatterns.map(p => p.getPatterns()).flat();
3254
3213
  }
3255
- getPatternsAfter(childReference) {
3256
- if (this.atomPatterns.indexOf(childReference)) {
3257
- const recursivePatterns = this._recursivePatterns.map(p => p.getPatterns()).flat();
3258
- const binaryPatterns = this._binaryPatterns.map(p => p.getPatterns()).flat();
3259
- return [...recursivePatterns, ...binaryPatterns];
3260
- }
3261
- if (this.recursivePatterns.indexOf(childReference)) {
3262
- return this._binaryPatterns.map(p => p.getPatterns()).flat();
3263
- }
3264
- if (this.binaryPatterns.indexOf(childReference)) {
3265
- const unaryPatterns = this._atomPatterns.map(p => p.getPatterns()).flat();
3266
- if (this._parent != null) {
3267
- const nextPatterns = this._parent.getPatternsAfter(this);
3268
- return [...unaryPatterns, ...nextPatterns];
3269
- }
3270
- return unaryPatterns;
3271
- }
3214
+ getPatternsAfter(_childReference) {
3272
3215
  return [];
3273
3216
  }
3274
3217
  getNextPatterns() {
@@ -3283,7 +3226,6 @@
3283
3226
  clone(name = this._name) {
3284
3227
  const clone = new ExpressionPattern(name, this._originalPatterns);
3285
3228
  clone._id = this._id;
3286
- clone.shouldCompactAst = this.shouldCompactAst;
3287
3229
  return clone;
3288
3230
  }
3289
3231
  isEqual(pattern) {
@@ -3464,13 +3406,9 @@
3464
3406
  }
3465
3407
  _saveOptions(statementNode) {
3466
3408
  const nameNode = statementNode.find(n => n.name === "name");
3467
- const shouldCompactAst = statementNode.find(n => n.name === "compact");
3468
3409
  const name = nameNode.value;
3469
3410
  const optionsNode = statementNode.find(n => n.name === "options-literal");
3470
3411
  const options = this._buildOptions(name, optionsNode);
3471
- if (shouldCompactAst != null) {
3472
- options.shouldCompactAst = true;
3473
- }
3474
3412
  this._parseContext.patternsByName.set(name, options);
3475
3413
  }
3476
3414
  _buildOptions(name, node) {
@@ -3530,13 +3468,9 @@
3530
3468
  }
3531
3469
  _saveSequence(statementNode) {
3532
3470
  const nameNode = statementNode.find(n => n.name === "name");
3533
- const shouldCompactAst = statementNode.find(n => n.name === "compact");
3534
3471
  const name = nameNode.value;
3535
3472
  const sequenceNode = statementNode.find(n => n.name === "sequence-literal");
3536
3473
  const sequence = this._buildSequence(name, sequenceNode);
3537
- if (shouldCompactAst != null) {
3538
- sequence.shouldCompactAst = true;
3539
- }
3540
3474
  this._parseContext.patternsByName.set(name, sequence);
3541
3475
  }
3542
3476
  _buildSequence(name, node) {
@@ -3556,13 +3490,9 @@
3556
3490
  }
3557
3491
  _saveRepeat(statementNode) {
3558
3492
  const nameNode = statementNode.find(n => n.name === "name");
3559
- const shouldCompactAst = statementNode.find(n => n.name === "compact");
3560
3493
  const name = nameNode.value;
3561
3494
  const repeatNode = statementNode.find(n => n.name === "repeat-literal");
3562
3495
  const repeat = this._buildRepeat(name, repeatNode);
3563
- if (shouldCompactAst != null) {
3564
- repeat.shouldCompactAst = true;
3565
- }
3566
3496
  this._parseContext.patternsByName.set(name, repeat);
3567
3497
  }
3568
3498
  _buildRepeat(name, repeatNode) {
@@ -3715,14 +3645,10 @@
3715
3645
  }
3716
3646
  _saveAlias(statementNode) {
3717
3647
  const nameNode = statementNode.find(n => n.name === "name");
3718
- const shouldCompactAst = statementNode.find(n => n.name === "compact");
3719
3648
  const aliasNode = statementNode.find(n => n.name === "alias-literal");
3720
3649
  const aliasName = aliasNode.value;
3721
3650
  const name = nameNode.value;
3722
3651
  const alias = this._getPattern(aliasName).clone(name);
3723
- if (shouldCompactAst != null) {
3724
- alias.shouldCompactAst = true;
3725
- }
3726
3652
  this._parseContext.patternsByName.set(name, alias);
3727
3653
  }
3728
3654
  static parse(expression, options) {
@@ -3769,8 +3695,10 @@
3769
3695
  exports.Regex = Regex;
3770
3696
  exports.Repeat = Repeat;
3771
3697
  exports.Sequence = Sequence;
3698
+ exports.compact = compact;
3772
3699
  exports.grammar = grammar;
3773
3700
  exports.patterns = patterns;
3701
+ exports.remove = remove;
3774
3702
 
3775
3703
  Object.defineProperty(exports, '__esModule', { value: true });
3776
3704