clarity-pattern-parser 10.3.7 → 11.0.1

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