clarity-pattern-parser 10.3.7 → 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 +417 -487
  5. package/dist/index.browser.js.map +1 -1
  6. package/dist/index.d.ts +3 -1
  7. package/dist/index.esm.js +416 -488
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/index.js +417 -487
  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 +235 -384
  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
package/dist/index.esm.js CHANGED
@@ -68,6 +68,8 @@ class Node {
68
68
  const index = this.findChildIndex(referenceNode);
69
69
  if (index > -1) {
70
70
  this.spliceChildren(index, 1, newNode);
71
+ newNode._parent = this;
72
+ referenceNode._parent = null;
71
73
  }
72
74
  }
73
75
  replaceWith(newNode) {
@@ -240,15 +242,33 @@ class Node {
240
242
  isEqual(node) {
241
243
  return node.toJson(0) === this.toJson(0);
242
244
  }
243
- static createValueNode(name, value) {
244
- return new Node("custom-value-node", name, 0, 0, [], value);
245
+ static createValueNode(type, name, value = "") {
246
+ return new Node(type, name, 0, 0, [], value);
245
247
  }
246
- static createNode(name, children) {
248
+ static createNode(type, name, children = []) {
247
249
  const value = children.map(c => c.toString()).join("");
248
- return new Node("custom-node", name, 0, 0, children, value);
250
+ return new Node(type, name, 0, 0, children, value);
249
251
  }
250
252
  }
251
253
 
254
+ function compact(node, nodeMap) {
255
+ node.walkBreadthFirst(n => {
256
+ if (nodeMap[n.name]) {
257
+ n.compact();
258
+ }
259
+ });
260
+ return node;
261
+ }
262
+
263
+ function remove(node, nodeMap) {
264
+ node.walkBreadthFirst(n => {
265
+ if (nodeMap[n.name]) {
266
+ n.remove();
267
+ }
268
+ });
269
+ return node;
270
+ }
271
+
252
272
  /******************************************************************************
253
273
  Copyright (c) Microsoft Corporation.
254
274
 
@@ -505,6 +525,24 @@ class Cursor {
505
525
  }
506
526
  }
507
527
 
528
+ function execPattern(pattern, text, record = false) {
529
+ const cursor = new Cursor(text);
530
+ record && cursor.startRecording();
531
+ const ast = pattern.parse(cursor);
532
+ const isMatch = (ast === null || ast === void 0 ? void 0 : ast.value.length) === text.length;
533
+ return {
534
+ ast: isMatch ? ast : null,
535
+ cursor
536
+ };
537
+ }
538
+
539
+ function testPattern(pattern, text, record = false) {
540
+ const cursor = new Cursor(text);
541
+ record && cursor.startRecording();
542
+ const ast = pattern.parse(cursor);
543
+ return (ast === null || ast === void 0 ? void 0 : ast.value.length) === text.length;
544
+ }
545
+
508
546
  let idIndex$9 = 0;
509
547
  class Literal {
510
548
  get id() {
@@ -532,7 +570,6 @@ class Literal {
532
570
  return this._firstIndex;
533
571
  }
534
572
  constructor(name, value) {
535
- this.shouldCompactAst = false;
536
573
  if (value.length === 0) {
537
574
  throw new Error("Value Cannot be empty.");
538
575
  }
@@ -547,19 +584,10 @@ class Literal {
547
584
  this._endIndex = 0;
548
585
  }
549
586
  test(text, record = false) {
550
- const cursor = new Cursor(text);
551
- record && cursor.startRecording();
552
- const ast = this.parse(cursor);
553
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
587
+ return testPattern(this, text, record);
554
588
  }
555
589
  exec(text, record = false) {
556
- const cursor = new Cursor(text);
557
- record && cursor.startRecording();
558
- const ast = this.parse(cursor);
559
- return {
560
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
561
- cursor
562
- };
590
+ return execPattern(this, text, record);
563
591
  }
564
592
  parse(cursor) {
565
593
  this._firstIndex = cursor.index;
@@ -602,7 +630,6 @@ class Literal {
602
630
  clone(name = this._name) {
603
631
  const clone = new Literal(name, this._token);
604
632
  clone._id = this._id;
605
- clone.shouldCompactAst = this.shouldCompactAst;
606
633
  return clone;
607
634
  }
608
635
  getTokens() {
@@ -669,7 +696,6 @@ class Regex {
669
696
  this._firstIndex = 0;
670
697
  this._substring = "";
671
698
  this._tokens = [];
672
- this.shouldCompactAst = false;
673
699
  this._id = `regex-${idIndex$8++}`;
674
700
  this._type = "regex";
675
701
  this._name = name;
@@ -689,19 +715,11 @@ class Regex {
689
715
  throw new Error("Invalid Arguments: The regex string cannot end with a '$' because it is expected to be in the middle of a string.");
690
716
  }
691
717
  }
692
- test(text) {
693
- const cursor = new Cursor(text);
694
- const ast = this.parse(cursor);
695
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
718
+ test(text, record = false) {
719
+ return testPattern(this, text, record);
696
720
  }
697
721
  exec(text, record = false) {
698
- const cursor = new Cursor(text);
699
- record && cursor.startRecording();
700
- const ast = this.parse(cursor);
701
- return {
702
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
703
- cursor
704
- };
722
+ return execPattern(this, text, record);
705
723
  }
706
724
  parse(cursor) {
707
725
  this._firstIndex = cursor.index;
@@ -739,7 +757,6 @@ class Regex {
739
757
  const clone = new Regex(name, this._originalRegexString);
740
758
  clone._tokens = this._tokens.slice();
741
759
  clone._id = this._id;
742
- clone.shouldCompactAst = this.shouldCompactAst;
743
760
  return clone;
744
761
  }
745
762
  getTokens() {
@@ -823,7 +840,6 @@ class Reference {
823
840
  return this._firstIndex;
824
841
  }
825
842
  constructor(name) {
826
- this.shouldCompactAst = false;
827
843
  this._id = `reference-${idIndex$7++}`;
828
844
  this._type = "reference";
829
845
  this._name = name;
@@ -833,19 +849,11 @@ class Reference {
833
849
  this._children = [];
834
850
  this._firstIndex = 0;
835
851
  }
836
- test(text) {
837
- const cursor = new Cursor(text);
838
- const ast = this.parse(cursor);
839
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
852
+ test(text, record = false) {
853
+ return testPattern(this, text, record);
840
854
  }
841
855
  exec(text, record = false) {
842
- const cursor = new Cursor(text);
843
- record && cursor.startRecording();
844
- const ast = this.parse(cursor);
845
- return {
846
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
847
- cursor
848
- };
856
+ return execPattern(this, text, record);
849
857
  }
850
858
  parse(cursor) {
851
859
  this._firstIndex = cursor.index;
@@ -946,7 +954,6 @@ class Reference {
946
954
  clone(name = this._name) {
947
955
  const clone = new Reference(name);
948
956
  clone._id = this._id;
949
- clone.shouldCompactAst = this.shouldCompactAst;
950
957
  // Optimize future clones, by caching the pattern we already found.
951
958
  if (this._pattern != null) {
952
959
  clone._cachedPattern = this._pattern;
@@ -1001,7 +1008,6 @@ class Options {
1001
1008
  return this._firstIndex;
1002
1009
  }
1003
1010
  constructor(name, options, isGreedy = false) {
1004
- this.shouldCompactAst = false;
1005
1011
  if (options.length === 0) {
1006
1012
  throw new Error("Need at least one pattern with an 'options' pattern.");
1007
1013
  }
@@ -1020,19 +1026,11 @@ class Options {
1020
1026
  child.parent = this;
1021
1027
  }
1022
1028
  }
1023
- test(text) {
1024
- const cursor = new Cursor(text);
1025
- const ast = this.parse(cursor);
1026
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
1029
+ test(text, record = false) {
1030
+ return testPattern(this, text, record);
1027
1031
  }
1028
1032
  exec(text, record = false) {
1029
- const cursor = new Cursor(text);
1030
- record && cursor.startRecording();
1031
- const ast = this.parse(cursor);
1032
- return {
1033
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
1034
- cursor
1035
- };
1033
+ return execPattern(this, text, record);
1036
1034
  }
1037
1035
  parse(cursor) {
1038
1036
  this._firstIndex = cursor.index;
@@ -1040,9 +1038,6 @@ class Options {
1040
1038
  if (node != null) {
1041
1039
  cursor.moveTo(node.lastIndex);
1042
1040
  cursor.resolveError();
1043
- if (this.shouldCompactAst) {
1044
- node.compact();
1045
- }
1046
1041
  return node;
1047
1042
  }
1048
1043
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
@@ -1133,7 +1128,6 @@ class Options {
1133
1128
  clone(name = this._name) {
1134
1129
  const clone = new Options(name, this._children, this._isGreedy);
1135
1130
  clone._id = this._id;
1136
- clone.shouldCompactAst = this.shouldCompactAst;
1137
1131
  return clone;
1138
1132
  }
1139
1133
  isEqual(pattern) {
@@ -1171,7 +1165,6 @@ class FiniteRepeat {
1171
1165
  return this._firstIndex;
1172
1166
  }
1173
1167
  constructor(name, pattern, options = {}) {
1174
- this.shouldCompactAst = false;
1175
1168
  this._id = `finite-repeat-${idIndex$5++}`;
1176
1169
  this._type = "finite-repeat";
1177
1170
  this._name = name;
@@ -1244,24 +1237,13 @@ class FiniteRepeat {
1244
1237
  cursor.resolveError();
1245
1238
  cursor.moveTo(lastIndex);
1246
1239
  const node = new Node(this._type, this.name, firstIndex, lastIndex, nodes);
1247
- if (this.shouldCompactAst) {
1248
- node.compact();
1249
- }
1250
1240
  return node;
1251
1241
  }
1252
- test(text) {
1253
- const cursor = new Cursor(text);
1254
- const ast = this.parse(cursor);
1255
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
1242
+ test(text, record = false) {
1243
+ return testPattern(this, text, record);
1256
1244
  }
1257
1245
  exec(text, record = false) {
1258
- const cursor = new Cursor(text);
1259
- record && cursor.startRecording();
1260
- const ast = this.parse(cursor);
1261
- return {
1262
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
1263
- cursor
1264
- };
1246
+ return execPattern(this, text, record);
1265
1247
  }
1266
1248
  clone(name = this._name) {
1267
1249
  let min = this._min;
@@ -1273,7 +1255,6 @@ class FiniteRepeat {
1273
1255
  trimDivider: this._trimDivider
1274
1256
  });
1275
1257
  clone._id = this._id;
1276
- clone.shouldCompactAst = this.shouldCompactAst;
1277
1258
  return clone;
1278
1259
  }
1279
1260
  getTokens() {
@@ -1354,7 +1335,6 @@ class InfiniteRepeat {
1354
1335
  return this._firstIndex;
1355
1336
  }
1356
1337
  constructor(name, pattern, options = {}) {
1357
- this.shouldCompactAst = false;
1358
1338
  const min = options.min != null ? Math.max(options.min, 1) : 1;
1359
1339
  const divider = options.divider;
1360
1340
  let children;
@@ -1382,19 +1362,11 @@ class InfiniteRepeat {
1382
1362
  child.parent = this;
1383
1363
  }
1384
1364
  }
1385
- test(text) {
1386
- const cursor = new Cursor(text);
1387
- const ast = this.parse(cursor);
1388
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
1365
+ test(text, record = false) {
1366
+ return testPattern(this, text, record);
1389
1367
  }
1390
1368
  exec(text, record = false) {
1391
- const cursor = new Cursor(text);
1392
- record && cursor.startRecording();
1393
- const ast = this.parse(cursor);
1394
- return {
1395
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
1396
- cursor
1397
- };
1369
+ return execPattern(this, text, record);
1398
1370
  }
1399
1371
  parse(cursor) {
1400
1372
  this._firstIndex = cursor.index;
@@ -1406,9 +1378,6 @@ class InfiniteRepeat {
1406
1378
  if (node != null) {
1407
1379
  cursor.moveTo(node.lastIndex);
1408
1380
  cursor.recordMatch(this, node);
1409
- if (this.shouldCompactAst) {
1410
- node.compact();
1411
- }
1412
1381
  }
1413
1382
  return node;
1414
1383
  }
@@ -1587,7 +1556,6 @@ class InfiniteRepeat {
1587
1556
  trimDivider: this._trimDivider
1588
1557
  });
1589
1558
  clone._id = this._id;
1590
- clone.shouldCompactAst = this.shouldCompactAst;
1591
1559
  return clone;
1592
1560
  }
1593
1561
  isEqual(pattern) {
@@ -1597,13 +1565,6 @@ class InfiniteRepeat {
1597
1565
 
1598
1566
  let idIndex$3 = 0;
1599
1567
  class Repeat {
1600
- get shouldCompactAst() {
1601
- return this._shouldCompactAst;
1602
- }
1603
- set shouldCompactAst(value) {
1604
- this._shouldCompactAst = value;
1605
- this._repeatPattern.shouldCompactAst = value;
1606
- }
1607
1568
  get id() {
1608
1569
  return this._id;
1609
1570
  }
@@ -1635,7 +1596,6 @@ class Repeat {
1635
1596
  this._id = `repeat-${idIndex$3++}`;
1636
1597
  this._pattern = pattern;
1637
1598
  this._parent = null;
1638
- this._shouldCompactAst = false;
1639
1599
  this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1640
1600
  if (this._options.max !== Infinity) {
1641
1601
  this._repeatPattern = new FiniteRepeat(name, pattern, this._options);
@@ -1659,7 +1619,6 @@ class Repeat {
1659
1619
  let min = this._options.min;
1660
1620
  const clone = new Repeat(name, this._pattern, Object.assign(Object.assign({}, this._options), { min }));
1661
1621
  clone._id = this._id;
1662
- clone.shouldCompactAst = this.shouldCompactAst;
1663
1622
  return clone;
1664
1623
  }
1665
1624
  getTokens() {
@@ -1737,7 +1696,6 @@ class Sequence {
1737
1696
  return this._firstIndex;
1738
1697
  }
1739
1698
  constructor(name, sequence) {
1740
- this.shouldCompactAst = false;
1741
1699
  if (sequence.length === 0) {
1742
1700
  throw new Error("Need at least one pattern with a 'sequence' pattern.");
1743
1701
  }
@@ -1756,19 +1714,11 @@ class Sequence {
1756
1714
  child.parent = this;
1757
1715
  }
1758
1716
  }
1759
- test(text) {
1760
- const cursor = new Cursor(text);
1761
- const ast = this.parse(cursor);
1762
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
1717
+ test(text, record = false) {
1718
+ return testPattern(this, text, record);
1763
1719
  }
1764
1720
  exec(text, record = false) {
1765
- const cursor = new Cursor(text);
1766
- record && cursor.startRecording();
1767
- const ast = this.parse(cursor);
1768
- return {
1769
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
1770
- cursor
1771
- };
1721
+ return execPattern(this, text, record);
1772
1722
  }
1773
1723
  parse(cursor) {
1774
1724
  this._firstIndex = cursor.index;
@@ -1778,9 +1728,6 @@ class Sequence {
1778
1728
  const node = this.createNode(cursor);
1779
1729
  if (node !== null) {
1780
1730
  cursor.recordMatch(this, node);
1781
- if (this.shouldCompactAst) {
1782
- node.compact();
1783
- }
1784
1731
  }
1785
1732
  return node;
1786
1733
  }
@@ -1968,7 +1915,6 @@ class Sequence {
1968
1915
  clone(name = this._name) {
1969
1916
  const clone = new Sequence(name, this._children);
1970
1917
  clone._id = this._id;
1971
- clone.shouldCompactAst = this.shouldCompactAst;
1972
1918
  return clone;
1973
1919
  }
1974
1920
  isEqual(pattern) {
@@ -2031,7 +1977,6 @@ class Optional {
2031
1977
  return this._children[0].startedOnIndex;
2032
1978
  }
2033
1979
  constructor(name, pattern) {
2034
- this.shouldCompactAst = false;
2035
1980
  this._id = `optional-${idIndex$1++}`;
2036
1981
  this._type = "optional";
2037
1982
  this._name = name;
@@ -2062,16 +2007,12 @@ class Optional {
2062
2007
  return null;
2063
2008
  }
2064
2009
  else {
2065
- if (node != null && this.shouldCompactAst) {
2066
- node.compact();
2067
- }
2068
2010
  return node;
2069
2011
  }
2070
2012
  }
2071
2013
  clone(name = this._name) {
2072
2014
  const clone = new Optional(name, this._children[0]);
2073
2015
  clone._id = this._id;
2074
- clone.shouldCompactAst = this.shouldCompactAst;
2075
2016
  return clone;
2076
2017
  }
2077
2018
  getTokens() {
@@ -2221,9 +2162,6 @@ const pattern = new Options("pattern", [
2221
2162
 
2222
2163
  const optionalSpaces$2 = new Optional("optional-spaces", spaces$1);
2223
2164
  const assignOperator = new Literal("assign-operator", "=");
2224
- const compact = new Literal("compact", "compact");
2225
- const compactModifier = new Sequence("compact-modifier", [lineSpaces$1, compact]);
2226
- const optionalCompactModifier = new Optional("optional-compact-modifier", compactModifier);
2227
2165
  const assignStatement = new Sequence("assign-statement", [
2228
2166
  optionalSpaces$2,
2229
2167
  name$1,
@@ -2231,7 +2169,6 @@ const assignStatement = new Sequence("assign-statement", [
2231
2169
  assignOperator,
2232
2170
  optionalSpaces$2,
2233
2171
  pattern,
2234
- optionalCompactModifier
2235
2172
  ]);
2236
2173
  const statement = new Options("statement", [assignStatement, name$1.clone("export-name")]);
2237
2174
 
@@ -2355,7 +2292,6 @@ class Not {
2355
2292
  return this.children[0].startedOnIndex;
2356
2293
  }
2357
2294
  constructor(name, pattern) {
2358
- this.shouldCompactAst = false;
2359
2295
  this._id = `not-${idIndex++}`;
2360
2296
  this._type = "not";
2361
2297
  this._name = name;
@@ -2363,19 +2299,11 @@ class Not {
2363
2299
  this._children = [pattern.clone()];
2364
2300
  this._children[0].parent = this;
2365
2301
  }
2366
- test(text) {
2367
- const cursor = new Cursor(text);
2368
- this.parse(cursor);
2369
- return !cursor.hasError;
2302
+ test(text, record = false) {
2303
+ return testPattern(this, text, record);
2370
2304
  }
2371
2305
  exec(text, record = false) {
2372
- const cursor = new Cursor(text);
2373
- record && cursor.startRecording();
2374
- const ast = this.parse(cursor);
2375
- return {
2376
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
2377
- cursor
2378
- };
2306
+ return execPattern(this, text, record);
2379
2307
  }
2380
2308
  parse(cursor) {
2381
2309
  const firstIndex = cursor.index;
@@ -2768,15 +2696,163 @@ class Context {
2768
2696
  }
2769
2697
  }
2770
2698
 
2771
- let indexId = 0;
2772
- function createNode(name, children) {
2773
- return new Node("expression", name, 0, 0, children, "");
2774
- }
2775
2699
  var Association;
2776
2700
  (function (Association) {
2777
2701
  Association[Association["left"] = 0] = "left";
2778
2702
  Association[Association["right"] = 1] = "right";
2779
2703
  })(Association || (Association = {}));
2704
+ class PrecedenceTree {
2705
+ constructor(precedenceMap = {}, associationMap = {}) {
2706
+ this._prefixPlaceholder = Node.createNode("placeholder", "prefix-placeholder");
2707
+ this._prefixNode = null;
2708
+ this._postfixPlaceholder = Node.createNode("placeholder", "postfix-placeholder");
2709
+ this._postfixNode = null;
2710
+ this._binaryPlaceholder = Node.createNode("placeholder", "binary-placeholder");
2711
+ this._atomNode = null;
2712
+ this._binaryNode = null;
2713
+ this._orphanedAtom = null;
2714
+ this._precedenceMap = precedenceMap;
2715
+ this._associationMap = associationMap;
2716
+ }
2717
+ addPrefix(name, ...prefix) {
2718
+ const lastPrefixNode = this._prefixNode;
2719
+ if (lastPrefixNode == null) {
2720
+ const node = Node.createNode("expression", name, [...prefix]);
2721
+ this._prefixNode = node;
2722
+ this._prefixNode.append(this._prefixPlaceholder);
2723
+ return;
2724
+ }
2725
+ const node = Node.createNode("expression", name, [...prefix]);
2726
+ this._prefixPlaceholder.replaceWith(node);
2727
+ node.append(this._prefixPlaceholder);
2728
+ this._prefixNode = node;
2729
+ }
2730
+ addPostfix(name, ...postfix) {
2731
+ const lastPostfixNode = this._postfixNode;
2732
+ if (lastPostfixNode == null) {
2733
+ const node = Node.createNode("expression", name, [this._postfixPlaceholder, ...postfix]);
2734
+ this._postfixNode = node;
2735
+ return;
2736
+ }
2737
+ const node = Node.createNode("expression", name, [lastPostfixNode, ...postfix]);
2738
+ this._postfixNode = node;
2739
+ }
2740
+ addBinary(name, ...delimiterNode) {
2741
+ const lastBinaryNode = this._binaryNode;
2742
+ const lastPrecendece = this._getPrecedenceFromNode(this._binaryNode);
2743
+ const precedence = this._getPrecedence(name);
2744
+ const association = this._associationMap[name];
2745
+ const lastAtomNode = this._compileAtomNode();
2746
+ if (lastAtomNode == null) {
2747
+ throw new Error("Cannot add a binary without an atom node.");
2748
+ }
2749
+ this._binaryPlaceholder.remove();
2750
+ this._orphanedAtom = lastAtomNode;
2751
+ if (lastBinaryNode == null) {
2752
+ const node = Node.createNode("expression", name, [lastAtomNode, ...delimiterNode, this._binaryPlaceholder]);
2753
+ this._binaryNode = node;
2754
+ return;
2755
+ }
2756
+ if (precedence === lastPrecendece && association === Association.right) {
2757
+ const node = Node.createNode("expression", name, [lastAtomNode, ...delimiterNode, this._binaryPlaceholder]);
2758
+ lastBinaryNode.appendChild(node);
2759
+ this._binaryNode = node;
2760
+ }
2761
+ else if (precedence === lastPrecendece) {
2762
+ const node = Node.createNode("expression", name, []);
2763
+ lastBinaryNode.replaceWith(node);
2764
+ lastBinaryNode.appendChild(lastAtomNode);
2765
+ node.append(lastBinaryNode, ...delimiterNode, this._binaryPlaceholder);
2766
+ this._binaryNode = node;
2767
+ }
2768
+ else if (precedence > lastPrecendece) {
2769
+ let ancestor = lastBinaryNode.parent;
2770
+ let root = lastBinaryNode;
2771
+ while (ancestor != null) {
2772
+ const nodePrecedence = this._precedenceMap[ancestor.name];
2773
+ if (nodePrecedence > precedence) {
2774
+ break;
2775
+ }
2776
+ root = ancestor;
2777
+ ancestor = ancestor.parent;
2778
+ }
2779
+ lastBinaryNode.appendChild(lastAtomNode);
2780
+ const node = Node.createNode("expression", name, []);
2781
+ root.replaceWith(node);
2782
+ node.append(root, ...delimiterNode, this._binaryPlaceholder);
2783
+ this._binaryNode = node;
2784
+ }
2785
+ else {
2786
+ const node = Node.createNode("expression", name, [lastAtomNode, ...delimiterNode, this._binaryPlaceholder]);
2787
+ lastBinaryNode.appendChild(node);
2788
+ this._binaryNode = node;
2789
+ }
2790
+ }
2791
+ _getPrecedenceFromNode(node) {
2792
+ if (node == null) {
2793
+ return 0;
2794
+ }
2795
+ return this._getPrecedence(node.name);
2796
+ }
2797
+ _getPrecedence(name) {
2798
+ if (this._precedenceMap[name] != null) {
2799
+ return this._precedenceMap[name];
2800
+ }
2801
+ return 0;
2802
+ }
2803
+ _compileAtomNode() {
2804
+ let node = this._atomNode;
2805
+ if (this._prefixNode != null && this._atomNode != null) {
2806
+ node = this._prefixNode;
2807
+ this._prefixPlaceholder.replaceWith(this._atomNode);
2808
+ }
2809
+ if (this._postfixNode != null && node != null) {
2810
+ this._postfixPlaceholder.replaceWith(node);
2811
+ node = this._postfixNode;
2812
+ }
2813
+ this._prefixNode = null;
2814
+ this._atomNode = null;
2815
+ this._postfixNode = null;
2816
+ if (node == null) {
2817
+ return null;
2818
+ }
2819
+ return node.findRoot();
2820
+ }
2821
+ addAtom(node) {
2822
+ this._atomNode = node;
2823
+ }
2824
+ hasAtom() {
2825
+ return this._atomNode != null;
2826
+ }
2827
+ commit() {
2828
+ var _a;
2829
+ if (this._binaryNode == null) {
2830
+ return this._compileAtomNode();
2831
+ }
2832
+ const atomNode = this._compileAtomNode();
2833
+ if (atomNode == null) {
2834
+ let root = this._binaryPlaceholder.findRoot();
2835
+ (_a = this._binaryPlaceholder.parent) === null || _a === void 0 ? void 0 : _a.replaceWith(this._orphanedAtom);
2836
+ this.reset();
2837
+ return root;
2838
+ }
2839
+ else {
2840
+ this._binaryPlaceholder.replaceWith(atomNode);
2841
+ const root = this._binaryNode.findRoot();
2842
+ this.reset();
2843
+ return root;
2844
+ }
2845
+ }
2846
+ reset() {
2847
+ this._prefixNode = null;
2848
+ this._atomNode = null;
2849
+ this._orphanedAtom = null;
2850
+ this._postfixNode = null;
2851
+ this._binaryNode = null;
2852
+ }
2853
+ }
2854
+
2855
+ let indexId = 0;
2780
2856
  class ExpressionPattern {
2781
2857
  get id() {
2782
2858
  return this._id;
@@ -2796,23 +2872,22 @@ class ExpressionPattern {
2796
2872
  get children() {
2797
2873
  return this._patterns;
2798
2874
  }
2799
- get unaryPrefixPatterns() {
2800
- return this._unaryPrefixPatterns;
2875
+ get prefixPatterns() {
2876
+ return this._prefixPatterns;
2801
2877
  }
2802
2878
  get atomPatterns() {
2803
2879
  return this._atomPatterns;
2804
2880
  }
2881
+ get postfixPatterns() {
2882
+ return this._postfixPatterns;
2883
+ }
2805
2884
  get binaryPatterns() {
2806
2885
  return this._binaryPatterns;
2807
2886
  }
2808
- get recursivePatterns() {
2809
- return this._recursivePatterns;
2810
- }
2811
2887
  get startedOnIndex() {
2812
2888
  return this._firstIndex;
2813
2889
  }
2814
2890
  constructor(name, patterns) {
2815
- this.shouldCompactAst = false;
2816
2891
  if (patterns.length === 0) {
2817
2892
  throw new Error("Need at least one pattern with an 'expression' pattern.");
2818
2893
  }
@@ -2822,139 +2897,131 @@ class ExpressionPattern {
2822
2897
  this._parent = null;
2823
2898
  this._firstIndex = -1;
2824
2899
  this._atomPatterns = [];
2825
- this._unaryPrefixPatterns = [];
2826
- this._unaryPrefixNames = [];
2900
+ this._prefixPatterns = [];
2901
+ this._prefixNames = [];
2902
+ this._postfixPatterns = [];
2903
+ this._postfixNames = [];
2827
2904
  this._binaryPatterns = [];
2828
- this._recursivePatterns = [];
2829
- this._recursiveNames = [];
2830
- this._endsInRecursion = [];
2831
2905
  this._binaryNames = [];
2832
- this._binaryAssociation = [];
2906
+ this.associationMap = {};
2833
2907
  this._precedenceMap = {};
2834
2908
  this._originalPatterns = patterns;
2835
- this._shouldCompactPatternsMap = {};
2836
2909
  this._patterns = this._organizePatterns(patterns);
2910
+ this._shouldStopParsing = false;
2911
+ this._precedenceTree = new PrecedenceTree(this._precedenceMap, this.associationMap);
2837
2912
  if (this._atomPatterns.length === 0) {
2838
- throw new Error("Need at least one operand pattern with an 'expression' pattern.");
2913
+ throw new Error("Need at least one terminating pattern with an 'expression' pattern.");
2839
2914
  }
2840
2915
  }
2841
2916
  _organizePatterns(patterns) {
2842
2917
  const finalPatterns = [];
2843
2918
  patterns.forEach((pattern) => {
2844
- this._shouldCompactPatternsMap[pattern.name] = pattern.shouldCompactAst;
2845
- if (this._isUnary(pattern)) {
2846
- const unaryPrefix = this._extractUnaryPrefixPattern(pattern).clone();
2847
- this._unaryPrefixPatterns.push(unaryPrefix);
2848
- this._unaryPrefixNames.push(pattern.name);
2849
- unaryPrefix.parent = this;
2850
- finalPatterns.push(unaryPrefix);
2919
+ if (this._isAtom(pattern)) {
2920
+ const atom = pattern.clone();
2921
+ atom.parent = this;
2922
+ this._atomPatterns.push(atom);
2923
+ finalPatterns.push(atom);
2924
+ }
2925
+ else if (this._isPrefix(pattern)) {
2926
+ const name = this._extractName(pattern);
2927
+ const prefix = this._extractPrefix(pattern);
2928
+ prefix.parent = this;
2929
+ this._prefixPatterns.push(prefix);
2930
+ this._prefixNames.push(name);
2931
+ finalPatterns.push(prefix);
2932
+ }
2933
+ else if (this._isPostfix(pattern)) {
2934
+ const name = this._extractName(pattern);
2935
+ const postfix = this._extractPostfix(pattern);
2936
+ postfix.parent = this;
2937
+ this._postfixPatterns.push(postfix);
2938
+ this._postfixNames.push(name);
2939
+ finalPatterns.push(postfix);
2851
2940
  }
2852
2941
  else if (this._isBinary(pattern)) {
2853
- const binaryName = this._extractName(pattern);
2854
- const clone = this._extractDelimiter(pattern).clone();
2942
+ const name = this._extractName(pattern);
2943
+ const clone = this._extractBinary(pattern);
2855
2944
  clone.parent = this;
2856
- this._precedenceMap[binaryName] = this._binaryPatterns.length;
2945
+ this._precedenceMap[name] = this._binaryPatterns.length;
2857
2946
  this._binaryPatterns.push(clone);
2858
- this._binaryNames.push(binaryName);
2947
+ this._binaryNames.push(name);
2859
2948
  if (pattern.type === "right-associated") {
2860
- this._binaryAssociation.push(Association.right);
2949
+ this.associationMap[name] = Association.right;
2861
2950
  }
2862
2951
  else {
2863
- this._binaryAssociation.push(Association.left);
2952
+ this.associationMap[name] = Association.left;
2864
2953
  }
2865
2954
  finalPatterns.push(clone);
2866
2955
  }
2867
- else if (this._isRecursive(pattern)) {
2868
- const name = this._extractName(pattern);
2869
- const tail = this._extractRecursiveTail(pattern);
2870
- tail.parent = this;
2871
- this._recursivePatterns.push(tail);
2872
- this._recursiveNames.push(name);
2873
- this._endsInRecursion.push(this._endsWithRecursion(pattern));
2874
- finalPatterns.push(tail);
2875
- }
2876
- else {
2877
- const clone = pattern.clone();
2878
- clone.parent = this;
2879
- this._atomPatterns.push(clone);
2880
- finalPatterns.push(clone);
2881
- }
2882
2956
  });
2883
2957
  return finalPatterns;
2884
2958
  }
2885
- _isBinary(pattern) {
2886
- if (pattern.type === "right-associated" && this._isBinaryPattern(pattern.children[0])) {
2887
- return true;
2888
- }
2889
- return this._isBinaryPattern(pattern);
2890
- }
2891
- _isBinaryPattern(pattern) {
2892
- return pattern.type === "sequence" &&
2893
- pattern.children.length === 3 &&
2894
- pattern.children[0].type === "reference" &&
2895
- pattern.children[0].name === this.name &&
2896
- pattern.children[2].type === "reference" &&
2897
- pattern.children[2].name === this.name;
2898
- }
2899
- _extractDelimiter(pattern) {
2900
- if (pattern.type === "right-associated") {
2901
- return pattern.children[0].children[1];
2902
- }
2903
- return pattern.children[1];
2904
- }
2905
2959
  _extractName(pattern) {
2906
2960
  if (pattern.type === "right-associated") {
2907
2961
  return pattern.children[0].name;
2908
2962
  }
2909
2963
  return pattern.name;
2910
2964
  }
2911
- _isUnary(pattern) {
2912
- if (pattern.type === "right-associated" && this._isUnaryPattern(pattern.children[0])) {
2913
- return true;
2914
- }
2915
- return this._isUnaryPattern(pattern);
2916
- }
2917
- _isUnaryPattern(pattern) {
2918
- return pattern.type === "sequence" &&
2919
- pattern.children[0].type !== "reference" &&
2920
- pattern.children[0].name !== this.name &&
2921
- pattern.children[1].type === "reference" &&
2922
- pattern.children[1].name === this.name &&
2923
- pattern.children.length === 2;
2924
- }
2925
- _extractUnaryPrefixPattern(pattern) {
2926
- if (pattern.type === "right-associated") {
2927
- return pattern.children[0].children[0];
2928
- }
2929
- return pattern.children[0];
2965
+ _isPrefix(pattern) {
2966
+ pattern = this._unwrapAssociationIfNecessary(pattern);
2967
+ const lastChild = pattern.children[pattern.children.length - 1];
2968
+ const referenceCount = this._referenceCount(pattern);
2969
+ const lastChildIsReference = this._isRecursiveReference(lastChild);
2970
+ return lastChildIsReference &&
2971
+ referenceCount === 1;
2972
+ }
2973
+ _extractPrefix(pattern) {
2974
+ pattern = this._unwrapAssociationIfNecessary(pattern);
2975
+ return new Sequence(`${pattern.name}-prefix`, pattern.children.slice(0, -1));
2976
+ }
2977
+ _isAtom(pattern) {
2978
+ pattern = this._unwrapAssociationIfNecessary(pattern);
2979
+ const firstChild = pattern.children[0];
2980
+ const lastChild = pattern.children[1];
2981
+ const firstChildIsReference = this._isRecursiveReference(firstChild);
2982
+ const lastChildIsReference = this._isRecursiveReference(lastChild);
2983
+ return !firstChildIsReference && !lastChildIsReference;
2984
+ }
2985
+ _isPostfix(pattern) {
2986
+ pattern = this._unwrapAssociationIfNecessary(pattern);
2987
+ const firstChild = pattern.children[0];
2988
+ const referenceCount = this._referenceCount(pattern);
2989
+ const firstChildIsReference = this._isRecursiveReference(firstChild);
2990
+ return firstChildIsReference &&
2991
+ referenceCount === 1;
2992
+ }
2993
+ _extractPostfix(pattern) {
2994
+ pattern = this._unwrapAssociationIfNecessary(pattern);
2995
+ return new Sequence(`${pattern.name}-postfix`, pattern.children.slice(1));
2930
2996
  }
2931
- _isRecursive(pattern) {
2932
- if (pattern.type === "right-associated" && this._isRecursivePattern(pattern.children[0])) {
2933
- return true;
2934
- }
2935
- return this._isRecursivePattern(pattern);
2997
+ _isBinary(pattern) {
2998
+ pattern = this._unwrapAssociationIfNecessary(pattern);
2999
+ const firstChild = pattern.children[0];
3000
+ const lastChild = pattern.children[pattern.children.length - 1];
3001
+ const firstChildIsReference = this._isRecursiveReference(firstChild);
3002
+ const lastChildIsReference = this._isRecursiveReference(lastChild);
3003
+ return firstChildIsReference && lastChildIsReference && pattern.children.length > 2;
2936
3004
  }
2937
- _isRecursivePattern(pattern) {
2938
- return pattern.type === "sequence" &&
2939
- pattern.children[0].type === "reference" &&
2940
- pattern.children[0].name === this.name &&
2941
- pattern.children.length > 2;
3005
+ _extractBinary(pattern) {
3006
+ pattern = this._unwrapAssociationIfNecessary(pattern);
3007
+ const children = pattern.children.slice(1, -1);
3008
+ const binarySequence = new Sequence(`${pattern.name}-delimiter`, children);
3009
+ return binarySequence;
2942
3010
  }
2943
- _extractRecursiveTail(pattern) {
3011
+ _unwrapAssociationIfNecessary(pattern) {
2944
3012
  if (pattern.type === "right-associated") {
2945
- return new Sequence(`${pattern.children[0].name}-tail`, pattern.children[0].children.slice(1));
3013
+ return pattern.children[0];
2946
3014
  }
2947
- return new Sequence(`${pattern.name}-tail`, pattern.children.slice(1));
3015
+ return pattern;
2948
3016
  }
2949
- _endsWithRecursion(pattern) {
2950
- if (pattern.type === "right-associated") {
2951
- pattern = pattern.children[0];
3017
+ _referenceCount(pattern) {
3018
+ return pattern.children.filter(p => this._isRecursiveReference(p)).length;
3019
+ }
3020
+ _isRecursiveReference(pattern) {
3021
+ if (pattern == null) {
3022
+ return false;
2952
3023
  }
2953
- const lastChild = pattern.children[pattern.children.length - 1];
2954
- return pattern.type === "sequence" &&
2955
- pattern.children.length > 1 &&
2956
- lastChild.type === "reference" &&
2957
- lastChild.name === this.name;
3024
+ return pattern.type === "reference" && pattern.name === this.name;
2958
3025
  }
2959
3026
  parse(cursor) {
2960
3027
  this._firstIndex = cursor.index;
@@ -2963,226 +3030,144 @@ class ExpressionPattern {
2963
3030
  node.normalize(this._firstIndex);
2964
3031
  cursor.moveTo(node.lastIndex);
2965
3032
  cursor.resolveError();
2966
- this._compactResult(node);
2967
3033
  return node;
2968
3034
  }
2969
3035
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
2970
3036
  return null;
2971
3037
  }
2972
- _compactResult(node) {
2973
- if (node == null) {
2974
- return;
2975
- }
2976
- if (this.shouldCompactAst) {
2977
- node.compact();
2978
- return;
2979
- }
2980
- // This could be really expensive with large trees. So we optimize with these checks,
2981
- // as well as use breadth first as to not recompact nodes over and over again.
2982
- const isCompactingNeeded = Object.values(this._shouldCompactPatternsMap).some(p => p);
2983
- if (isCompactingNeeded) {
2984
- node.walkBreadthFirst(n => {
2985
- if (this._shouldCompactPatternsMap[n.name]) {
2986
- n.compact();
2987
- }
2988
- });
2989
- }
2990
- }
2991
3038
  _tryToParse(cursor) {
2992
3039
  if (this._isBeyondRecursiveAllowance()) {
2993
3040
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
2994
3041
  return null;
2995
3042
  }
2996
- let lastAtomNode = null;
2997
- let lastBinaryNode = null;
2998
- let onIndex = cursor.index;
2999
- outer: while (true) {
3043
+ this._shouldStopParsing = false;
3044
+ while (true) {
3000
3045
  cursor.resolveError();
3001
- onIndex = cursor.index;
3002
- let prefix = null;
3003
- let prefixName = "";
3004
- for (let i = 0; i < this._unaryPrefixPatterns.length; i++) {
3005
- cursor.moveTo(onIndex);
3006
- const pattern = this._unaryPrefixPatterns[i];
3007
- const node = pattern.parse(cursor);
3008
- if (node != null) {
3009
- prefix = node;
3010
- prefixName = this._unaryPrefixNames[i];
3011
- if (cursor.hasNext()) {
3012
- cursor.next();
3013
- }
3014
- else {
3015
- break outer;
3016
- }
3046
+ this._tryToMatchPrefix(cursor);
3047
+ if (this._shouldStopParsing) {
3048
+ break;
3049
+ }
3050
+ this._tryToMatchAtom(cursor);
3051
+ if (this._shouldStopParsing) {
3052
+ break;
3053
+ }
3054
+ this._tryToMatchPostfix(cursor);
3055
+ if (this._shouldStopParsing) {
3056
+ break;
3057
+ }
3058
+ if (this._precedenceTree.hasAtom()) {
3059
+ this._tryToMatchBinary(cursor);
3060
+ if (this._shouldStopParsing) {
3017
3061
  break;
3018
3062
  }
3063
+ }
3064
+ else {
3065
+ break;
3066
+ }
3067
+ }
3068
+ return this._precedenceTree.commit();
3069
+ }
3070
+ _tryToMatchPrefix(cursor) {
3071
+ let onIndex = cursor.index;
3072
+ for (let i = 0; i < this._prefixPatterns.length; i++) {
3073
+ const pattern = this._prefixPatterns[i];
3074
+ const name = this._prefixNames[i];
3075
+ const node = pattern.parse(cursor);
3076
+ if (node != null) {
3077
+ this._precedenceTree.addPrefix(name, ...node.children);
3078
+ if (cursor.hasNext()) {
3079
+ cursor.next();
3080
+ onIndex = cursor.index;
3081
+ i = -1;
3082
+ continue;
3083
+ }
3019
3084
  else {
3020
- cursor.resolveError();
3085
+ this._shouldStopParsing = true;
3086
+ break;
3021
3087
  }
3022
3088
  }
3023
- onIndex = cursor.index;
3024
- for (let i = 0; i < this._atomPatterns.length; i++) {
3089
+ else {
3025
3090
  cursor.moveTo(onIndex);
3026
- const pattern = this._atomPatterns[i];
3027
- const node = pattern.parse(cursor);
3028
- if (node != null) {
3029
- lastAtomNode = node;
3030
- break;
3091
+ cursor.resolveError();
3092
+ }
3093
+ }
3094
+ }
3095
+ _tryToMatchAtom(cursor) {
3096
+ let onIndex = cursor.index;
3097
+ for (let i = 0; i < this._atomPatterns.length; i++) {
3098
+ cursor.moveTo(onIndex);
3099
+ const pattern = this._atomPatterns[i];
3100
+ const node = pattern.parse(cursor);
3101
+ if (node != null) {
3102
+ this._precedenceTree.addAtom(node);
3103
+ if (cursor.hasNext()) {
3104
+ cursor.next();
3031
3105
  }
3032
3106
  else {
3033
- lastAtomNode = null;
3034
- cursor.resolveError();
3107
+ this._shouldStopParsing = true;
3035
3108
  }
3036
- }
3037
- if (lastAtomNode == null) {
3038
3109
  break;
3039
3110
  }
3040
- if (cursor.hasNext()) {
3041
- cursor.next();
3042
- }
3043
3111
  else {
3044
- if (lastBinaryNode != null && lastAtomNode != null) {
3045
- if (prefix != null) {
3046
- lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3047
- }
3048
- lastBinaryNode.appendChild(lastAtomNode);
3049
- }
3050
- break;
3051
- }
3052
- onIndex = cursor.index;
3053
- if (prefix != null && this._recursivePatterns.length === 0) {
3054
- lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3055
- }
3056
- for (let i = 0; i < this._recursivePatterns.length; i++) {
3057
- const pattern = this._recursivePatterns[i];
3058
- const node = pattern.parse(cursor);
3059
- if (node != null) {
3060
- const name = this._recursiveNames[i];
3061
- if (this._endsInRecursion[i]) {
3062
- if (lastBinaryNode != null && lastAtomNode != null) {
3063
- if (prefix != null) {
3064
- lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3065
- }
3066
- lastBinaryNode.appendChild(lastAtomNode);
3067
- }
3068
- const frontExpression = lastBinaryNode == null ? lastAtomNode : lastBinaryNode.findRoot();
3069
- const recursiveNode = createNode(name, [frontExpression, ...node.children]);
3070
- return recursiveNode;
3071
- }
3072
- else {
3073
- if (prefix != null) {
3074
- lastAtomNode = createNode(prefixName, [prefix, lastAtomNode]);
3075
- }
3076
- const recursiveNode = createNode(name, [lastAtomNode, ...node.children]);
3077
- lastAtomNode = recursiveNode;
3078
- if (cursor.hasNext()) {
3079
- cursor.next();
3080
- }
3081
- else {
3082
- if (lastBinaryNode != null && lastAtomNode != null) {
3083
- lastBinaryNode.appendChild(lastAtomNode);
3084
- }
3085
- break outer;
3086
- }
3087
- onIndex = cursor.index;
3088
- i = -1;
3089
- continue;
3090
- }
3091
- }
3092
3112
  cursor.resolveError();
3093
3113
  cursor.moveTo(onIndex);
3094
3114
  }
3095
- onIndex = cursor.index;
3096
- for (let i = 0; i < this._binaryPatterns.length; i++) {
3097
- cursor.resolveError();
3098
- cursor.moveTo(onIndex);
3099
- const pattern = this._binaryPatterns[i];
3100
- const name = this._binaryNames[i];
3101
- const delimiterNode = pattern.parse(cursor);
3102
- if (delimiterNode == null) {
3103
- if (i === this._binaryPatterns.length - 1) {
3104
- if (lastBinaryNode == null) {
3105
- return lastAtomNode;
3106
- }
3107
- else if (lastAtomNode != null) {
3108
- lastBinaryNode.appendChild(lastAtomNode);
3109
- }
3110
- }
3115
+ }
3116
+ }
3117
+ _tryToMatchPostfix(cursor) {
3118
+ let onIndex = cursor.index;
3119
+ for (let i = 0; i < this._postfixPatterns.length; i++) {
3120
+ const pattern = this._postfixPatterns[i];
3121
+ const name = this._postfixNames[i];
3122
+ const node = pattern.parse(cursor);
3123
+ if (node != null) {
3124
+ this._precedenceTree.addPostfix(name, ...node.children);
3125
+ if (cursor.hasNext()) {
3126
+ cursor.next();
3127
+ onIndex = cursor.index;
3128
+ i = -1;
3111
3129
  continue;
3112
3130
  }
3113
- if (lastBinaryNode == null && lastAtomNode != null && delimiterNode != null) {
3114
- const node = createNode(name, [lastAtomNode, delimiterNode]);
3115
- lastBinaryNode = node;
3116
- }
3117
- else if (lastBinaryNode != null && lastAtomNode != null && delimiterNode != null) {
3118
- const precedence = this._precedenceMap[name];
3119
- const lastPrecendece = lastBinaryNode == null ? 0 : this._precedenceMap[lastBinaryNode.name] == null ? -1 : this._precedenceMap[lastBinaryNode.name];
3120
- const association = this._binaryAssociation[i];
3121
- if (precedence === lastPrecendece && association === Association.right) {
3122
- const node = createNode(name, [lastAtomNode, delimiterNode]);
3123
- lastBinaryNode.appendChild(node);
3124
- lastBinaryNode = node;
3125
- }
3126
- else if (precedence === lastPrecendece) {
3127
- const node = createNode(name, []);
3128
- lastBinaryNode.replaceWith(node);
3129
- lastBinaryNode.appendChild(lastAtomNode);
3130
- node.append(lastBinaryNode, delimiterNode);
3131
- lastBinaryNode = node;
3132
- }
3133
- else if (precedence > lastPrecendece) {
3134
- let ancestor = lastBinaryNode.parent;
3135
- let root = lastBinaryNode;
3136
- while (ancestor != null) {
3137
- const nodePrecedence = this._precedenceMap[ancestor.name];
3138
- if (nodePrecedence > precedence) {
3139
- break;
3140
- }
3141
- root = ancestor;
3142
- ancestor = ancestor.parent;
3143
- }
3144
- lastBinaryNode.appendChild(lastAtomNode);
3145
- if (root != null) {
3146
- const node = createNode(name, []);
3147
- root.replaceWith(node);
3148
- node.append(root, delimiterNode);
3149
- lastBinaryNode = node;
3150
- }
3151
- else {
3152
- const node = createNode(name, [lastAtomNode, delimiterNode]);
3153
- lastBinaryNode = node;
3154
- }
3155
- }
3156
- else {
3157
- const node = createNode(name, [lastAtomNode, delimiterNode]);
3158
- lastBinaryNode.appendChild(node);
3159
- lastBinaryNode = node;
3160
- }
3131
+ else {
3132
+ this._shouldStopParsing = true;
3133
+ break;
3161
3134
  }
3135
+ }
3136
+ else {
3137
+ cursor.moveTo(onIndex);
3138
+ cursor.resolveError();
3139
+ }
3140
+ }
3141
+ }
3142
+ _tryToMatchBinary(cursor) {
3143
+ let onIndex = cursor.index;
3144
+ let foundMatch = false;
3145
+ if (this.binaryPatterns.length === 0) {
3146
+ this._shouldStopParsing = true;
3147
+ }
3148
+ for (let i = 0; i < this._binaryPatterns.length; i++) {
3149
+ cursor.moveTo(onIndex);
3150
+ const pattern = this._binaryPatterns[i];
3151
+ const name = this._binaryNames[i];
3152
+ const node = pattern.parse(cursor);
3153
+ if (node != null) {
3154
+ foundMatch = true;
3155
+ this._precedenceTree.addBinary(name, ...node.children);
3162
3156
  if (cursor.hasNext()) {
3163
3157
  cursor.next();
3164
3158
  }
3165
3159
  else {
3166
- break outer;
3160
+ this._shouldStopParsing = true;
3167
3161
  }
3168
3162
  break;
3169
3163
  }
3170
- if (lastBinaryNode == null) {
3171
- break;
3164
+ else {
3165
+ cursor.resolveError();
3166
+ cursor.moveTo(onIndex);
3172
3167
  }
3173
3168
  }
3174
- if (lastBinaryNode == null) {
3175
- return lastAtomNode;
3176
- }
3177
- else {
3178
- const root = lastBinaryNode.findAncestor(n => n.parent == null) || lastBinaryNode;
3179
- if (lastBinaryNode.children.length < 3) {
3180
- lastBinaryNode.remove();
3181
- if (lastBinaryNode === root) {
3182
- return lastAtomNode;
3183
- }
3184
- }
3185
- return root;
3169
+ if (!foundMatch) {
3170
+ this._shouldStopParsing = true;
3186
3171
  }
3187
3172
  }
3188
3173
  _isBeyondRecursiveAllowance() {
@@ -3199,40 +3184,16 @@ class ExpressionPattern {
3199
3184
  }
3200
3185
  return false;
3201
3186
  }
3202
- test(text) {
3203
- const cursor = new Cursor(text);
3204
- const ast = this.parse(cursor);
3205
- return (ast === null || ast === void 0 ? void 0 : ast.value) === text;
3187
+ test(text, record = false) {
3188
+ return testPattern(this, text, record);
3206
3189
  }
3207
3190
  exec(text, record = false) {
3208
- const cursor = new Cursor(text);
3209
- record && cursor.startRecording();
3210
- const ast = this.parse(cursor);
3211
- return {
3212
- ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
3213
- cursor
3214
- };
3191
+ return execPattern(this, text, record);
3215
3192
  }
3216
3193
  getTokens() {
3217
3194
  return this.atomPatterns.map(p => p.getTokens()).flat();
3218
3195
  }
3219
- getTokensAfter(childReference) {
3220
- if (this.atomPatterns.indexOf(childReference)) {
3221
- const recursiveTokens = this._recursivePatterns.map(p => p.getTokens()).flat();
3222
- const binaryTokens = this._binaryPatterns.map(p => p.getTokens()).flat();
3223
- return [...recursiveTokens, ...binaryTokens];
3224
- }
3225
- if (this.recursivePatterns.indexOf(childReference)) {
3226
- return this._binaryPatterns.map(p => p.getTokens()).flat();
3227
- }
3228
- if (this.binaryPatterns.indexOf(childReference)) {
3229
- const unaryTokens = this._atomPatterns.map(p => p.getTokens()).flat();
3230
- if (this._parent != null) {
3231
- const nextTokens = this._parent.getTokensAfter(this);
3232
- return [...unaryTokens, ...nextTokens];
3233
- }
3234
- return unaryTokens;
3235
- }
3196
+ getTokensAfter(_childReference) {
3236
3197
  return [];
3237
3198
  }
3238
3199
  getNextTokens() {
@@ -3244,23 +3205,7 @@ class ExpressionPattern {
3244
3205
  getPatterns() {
3245
3206
  return this.atomPatterns.map(p => p.getPatterns()).flat();
3246
3207
  }
3247
- getPatternsAfter(childReference) {
3248
- if (this.atomPatterns.indexOf(childReference)) {
3249
- const recursivePatterns = this._recursivePatterns.map(p => p.getPatterns()).flat();
3250
- const binaryPatterns = this._binaryPatterns.map(p => p.getPatterns()).flat();
3251
- return [...recursivePatterns, ...binaryPatterns];
3252
- }
3253
- if (this.recursivePatterns.indexOf(childReference)) {
3254
- return this._binaryPatterns.map(p => p.getPatterns()).flat();
3255
- }
3256
- if (this.binaryPatterns.indexOf(childReference)) {
3257
- const unaryPatterns = this._atomPatterns.map(p => p.getPatterns()).flat();
3258
- if (this._parent != null) {
3259
- const nextPatterns = this._parent.getPatternsAfter(this);
3260
- return [...unaryPatterns, ...nextPatterns];
3261
- }
3262
- return unaryPatterns;
3263
- }
3208
+ getPatternsAfter(_childReference) {
3264
3209
  return [];
3265
3210
  }
3266
3211
  getNextPatterns() {
@@ -3275,7 +3220,6 @@ class ExpressionPattern {
3275
3220
  clone(name = this._name) {
3276
3221
  const clone = new ExpressionPattern(name, this._originalPatterns);
3277
3222
  clone._id = this._id;
3278
- clone.shouldCompactAst = this.shouldCompactAst;
3279
3223
  return clone;
3280
3224
  }
3281
3225
  isEqual(pattern) {
@@ -3456,13 +3400,9 @@ class Grammar {
3456
3400
  }
3457
3401
  _saveOptions(statementNode) {
3458
3402
  const nameNode = statementNode.find(n => n.name === "name");
3459
- const shouldCompactAst = statementNode.find(n => n.name === "compact");
3460
3403
  const name = nameNode.value;
3461
3404
  const optionsNode = statementNode.find(n => n.name === "options-literal");
3462
3405
  const options = this._buildOptions(name, optionsNode);
3463
- if (shouldCompactAst != null) {
3464
- options.shouldCompactAst = true;
3465
- }
3466
3406
  this._parseContext.patternsByName.set(name, options);
3467
3407
  }
3468
3408
  _buildOptions(name, node) {
@@ -3522,13 +3462,9 @@ class Grammar {
3522
3462
  }
3523
3463
  _saveSequence(statementNode) {
3524
3464
  const nameNode = statementNode.find(n => n.name === "name");
3525
- const shouldCompactAst = statementNode.find(n => n.name === "compact");
3526
3465
  const name = nameNode.value;
3527
3466
  const sequenceNode = statementNode.find(n => n.name === "sequence-literal");
3528
3467
  const sequence = this._buildSequence(name, sequenceNode);
3529
- if (shouldCompactAst != null) {
3530
- sequence.shouldCompactAst = true;
3531
- }
3532
3468
  this._parseContext.patternsByName.set(name, sequence);
3533
3469
  }
3534
3470
  _buildSequence(name, node) {
@@ -3548,13 +3484,9 @@ class Grammar {
3548
3484
  }
3549
3485
  _saveRepeat(statementNode) {
3550
3486
  const nameNode = statementNode.find(n => n.name === "name");
3551
- const shouldCompactAst = statementNode.find(n => n.name === "compact");
3552
3487
  const name = nameNode.value;
3553
3488
  const repeatNode = statementNode.find(n => n.name === "repeat-literal");
3554
3489
  const repeat = this._buildRepeat(name, repeatNode);
3555
- if (shouldCompactAst != null) {
3556
- repeat.shouldCompactAst = true;
3557
- }
3558
3490
  this._parseContext.patternsByName.set(name, repeat);
3559
3491
  }
3560
3492
  _buildRepeat(name, repeatNode) {
@@ -3707,14 +3639,10 @@ class Grammar {
3707
3639
  }
3708
3640
  _saveAlias(statementNode) {
3709
3641
  const nameNode = statementNode.find(n => n.name === "name");
3710
- const shouldCompactAst = statementNode.find(n => n.name === "compact");
3711
3642
  const aliasNode = statementNode.find(n => n.name === "alias-literal");
3712
3643
  const aliasName = aliasNode.value;
3713
3644
  const name = nameNode.value;
3714
3645
  const alias = this._getPattern(aliasName).clone(name);
3715
- if (shouldCompactAst != null) {
3716
- alias.shouldCompactAst = true;
3717
- }
3718
3646
  this._parseContext.patternsByName.set(name, alias);
3719
3647
  }
3720
3648
  static parse(expression, options) {
@@ -3745,5 +3673,5 @@ function patterns(strings, ...values) {
3745
3673
  return result;
3746
3674
  }
3747
3675
 
3748
- export { AutoComplete, Context, Cursor, CursorHistory, ExpressionPattern, Grammar, Literal, Node, Not, Optional, Options, ParseError, Reference, Regex, Repeat, Sequence, grammar, patterns };
3676
+ export { AutoComplete, Context, Cursor, CursorHistory, ExpressionPattern, Grammar, Literal, Node, Not, Optional, Options, ParseError, Reference, Regex, Repeat, Sequence, compact, grammar, patterns, remove };
3749
3677
  //# sourceMappingURL=index.esm.js.map