clarity-pattern-parser 10.2.13 → 10.3.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 (39) hide show
  1. package/dist/ast/Node.d.ts +1 -0
  2. package/dist/index.browser.js +100 -9
  3. package/dist/index.browser.js.map +1 -1
  4. package/dist/index.esm.js +100 -9
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/index.js +100 -9
  7. package/dist/index.js.map +1 -1
  8. package/dist/patterns/Context.d.ts +1 -0
  9. package/dist/patterns/ExpressionPattern.d.ts +3 -0
  10. package/dist/patterns/FiniteRepeat.d.ts +1 -0
  11. package/dist/patterns/InfiniteRepeat.d.ts +1 -0
  12. package/dist/patterns/Literal.d.ts +1 -0
  13. package/dist/patterns/Not.d.ts +1 -0
  14. package/dist/patterns/Optional.d.ts +1 -0
  15. package/dist/patterns/Options.d.ts +1 -0
  16. package/dist/patterns/Pattern.d.ts +1 -0
  17. package/dist/patterns/Reference.d.ts +1 -0
  18. package/dist/patterns/Regex.d.ts +1 -0
  19. package/dist/patterns/Repeat.d.ts +3 -0
  20. package/dist/patterns/Sequence.d.ts +1 -0
  21. package/package.json +1 -1
  22. package/src/ast/Node.ts +6 -2
  23. package/src/grammar/Grammar.test.ts +53 -3
  24. package/src/grammar/Grammar.ts +20 -0
  25. package/src/grammar/patterns/statement.ts +7 -2
  26. package/src/patterns/Context.ts +3 -0
  27. package/src/patterns/ExpressionPattern.ts +35 -0
  28. package/src/patterns/FiniteRepeat.ts +10 -1
  29. package/src/patterns/InfiniteRepeat.ts +7 -0
  30. package/src/patterns/Literal.ts +3 -0
  31. package/src/patterns/Not.ts +2 -0
  32. package/src/patterns/Optional.ts +10 -3
  33. package/src/patterns/Options.ts +11 -3
  34. package/src/patterns/Pattern.ts +1 -0
  35. package/src/patterns/Reference.ts +3 -0
  36. package/src/patterns/Regex.ts +5 -2
  37. package/src/patterns/Repeat.ts +12 -0
  38. package/src/patterns/RightAssociatedPattern.ts +2 -0
  39. package/src/patterns/Sequence.ts +7 -0
@@ -50,6 +50,7 @@ export declare class Node {
50
50
  remove(): void;
51
51
  clone(): Node;
52
52
  normalize(startIndex?: number): number;
53
+ compact(): void;
53
54
  toString(): string;
54
55
  toCycleFreeObject(): CycleFreeNode;
55
56
  toJson(space?: number): string;
@@ -167,7 +167,6 @@
167
167
  walkBreadthFirst(callback) {
168
168
  const queue = [this];
169
169
  while (queue.length > 0) {
170
- // biome-ignore lint/style/noNonNullAssertion: This will never be undefined.
171
170
  const current = queue.shift();
172
171
  callback(current);
173
172
  queue.push(...current.children);
@@ -221,6 +220,10 @@
221
220
  this._lastIndex = Math.max(startIndex + length - 1, 0);
222
221
  return length;
223
222
  }
223
+ compact() {
224
+ this._value = this.toString();
225
+ this._children.length = 0;
226
+ }
224
227
  toString() {
225
228
  if (this._children.length === 0) {
226
229
  return this._value;
@@ -532,6 +535,7 @@
532
535
  return [];
533
536
  }
534
537
  constructor(name, value) {
538
+ this.shouldCompactAst = false;
535
539
  if (value.length === 0) {
536
540
  throw new Error("Value Cannot be empty.");
537
541
  }
@@ -601,6 +605,7 @@
601
605
  clone(name = this._name) {
602
606
  const clone = new Literal(name, this._token);
603
607
  clone._id = this._id;
608
+ clone.shouldCompactAst = this.shouldCompactAst;
604
609
  return clone;
605
610
  }
606
611
  getTokens() {
@@ -664,6 +669,7 @@
664
669
  this._firstIndex = -1;
665
670
  this._substring = "";
666
671
  this._tokens = [];
672
+ this.shouldCompactAst = false;
667
673
  this._id = `regex-${idIndex$8++}`;
668
674
  this._type = "regex";
669
675
  this._name = name;
@@ -733,6 +739,7 @@
733
739
  const clone = new Regex(name, this._originalRegexString);
734
740
  clone._tokens = this._tokens.slice();
735
741
  clone._id = this._id;
742
+ clone.shouldCompactAst = this.shouldCompactAst;
736
743
  return clone;
737
744
  }
738
745
  getTokens() {
@@ -813,6 +820,7 @@
813
820
  return this._children;
814
821
  }
815
822
  constructor(name) {
823
+ this.shouldCompactAst = false;
816
824
  this._id = `reference-${idIndex$7++}`;
817
825
  this._type = "reference";
818
826
  this._name = name;
@@ -933,6 +941,7 @@
933
941
  clone(name = this._name) {
934
942
  const clone = new Reference(name);
935
943
  clone._id = this._id;
944
+ clone.shouldCompactAst = this.shouldCompactAst;
936
945
  // Optimize future clones, by caching the pattern we already found.
937
946
  if (this._pattern != null) {
938
947
  clone._cachedPattern = this._pattern;
@@ -1011,6 +1020,7 @@
1011
1020
  return this._children;
1012
1021
  }
1013
1022
  constructor(name, options, isGreedy = false) {
1023
+ this.shouldCompactAst = false;
1014
1024
  if (options.length === 0) {
1015
1025
  throw new Error("Need at least one pattern with an 'options' pattern.");
1016
1026
  }
@@ -1053,6 +1063,9 @@
1053
1063
  if (node != null) {
1054
1064
  cursor.moveTo(node.lastIndex);
1055
1065
  cursor.resolveError();
1066
+ if (this.shouldCompactAst) {
1067
+ node.compact();
1068
+ }
1056
1069
  return node;
1057
1070
  }
1058
1071
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
@@ -1127,9 +1140,10 @@
1127
1140
  return findPattern(this, predicate);
1128
1141
  }
1129
1142
  clone(name = this._name) {
1130
- const or = new Options(name, this._children, this._isGreedy);
1131
- or._id = this._id;
1132
- return or;
1143
+ const clone = new Options(name, this._children, this._isGreedy);
1144
+ clone._id = this._id;
1145
+ clone.shouldCompactAst = this.shouldCompactAst;
1146
+ return clone;
1133
1147
  }
1134
1148
  isEqual(pattern) {
1135
1149
  return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
@@ -1163,6 +1177,7 @@
1163
1177
  return this._max;
1164
1178
  }
1165
1179
  constructor(name, pattern, options = {}) {
1180
+ this.shouldCompactAst = false;
1166
1181
  this._id = `finite-repeat-${idIndex$5++}`;
1167
1182
  this._type = "finite-repeat";
1168
1183
  this._name = name;
@@ -1232,7 +1247,11 @@
1232
1247
  const lastIndex = nodes[nodes.length - 1].lastIndex;
1233
1248
  cursor.resolveError();
1234
1249
  cursor.moveTo(lastIndex);
1235
- return new Node(this._type, this.name, firstIndex, lastIndex, nodes);
1250
+ const node = new Node(this._type, this.name, firstIndex, lastIndex, nodes);
1251
+ if (this.shouldCompactAst) {
1252
+ node.compact();
1253
+ }
1254
+ return node;
1236
1255
  }
1237
1256
  test(text) {
1238
1257
  const cursor = new Cursor(text);
@@ -1258,6 +1277,7 @@
1258
1277
  trimDivider: this._trimDivider
1259
1278
  });
1260
1279
  clone._id = this._id;
1280
+ clone.shouldCompactAst = this.shouldCompactAst;
1261
1281
  return clone;
1262
1282
  }
1263
1283
  getTokens() {
@@ -1335,6 +1355,7 @@
1335
1355
  return this._min;
1336
1356
  }
1337
1357
  constructor(name, pattern, options = {}) {
1358
+ this.shouldCompactAst = false;
1338
1359
  const min = options.min != null ? Math.max(options.min, 1) : 1;
1339
1360
  const divider = options.divider;
1340
1361
  let children;
@@ -1386,6 +1407,9 @@
1386
1407
  if (node != null) {
1387
1408
  cursor.moveTo(node.lastIndex);
1388
1409
  cursor.recordMatch(this, node);
1410
+ if (this.shouldCompactAst) {
1411
+ node.compact();
1412
+ }
1389
1413
  }
1390
1414
  return node;
1391
1415
  }
@@ -1564,6 +1588,7 @@
1564
1588
  trimDivider: this._trimDivider
1565
1589
  });
1566
1590
  clone._id = this._id;
1591
+ clone.shouldCompactAst = this.shouldCompactAst;
1567
1592
  return clone;
1568
1593
  }
1569
1594
  isEqual(pattern) {
@@ -1573,6 +1598,13 @@
1573
1598
 
1574
1599
  let idIndex$3 = 0;
1575
1600
  class Repeat {
1601
+ get shouldCompactAst() {
1602
+ return this._shouldCompactAst;
1603
+ }
1604
+ set shouldCompactAst(value) {
1605
+ this._shouldCompactAst = value;
1606
+ this._repeatPattern.shouldCompactAst = value;
1607
+ }
1576
1608
  get id() {
1577
1609
  return this._id;
1578
1610
  }
@@ -1601,6 +1633,7 @@
1601
1633
  this._id = `repeat-${idIndex$3++}`;
1602
1634
  this._pattern = pattern;
1603
1635
  this._parent = null;
1636
+ this._shouldCompactAst = false;
1604
1637
  this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1605
1638
  if (this._options.max !== Infinity) {
1606
1639
  this._repeatPattern = new FiniteRepeat(name, pattern, this._options);
@@ -1624,6 +1657,7 @@
1624
1657
  let min = this._options.min;
1625
1658
  const clone = new Repeat(name, this._pattern, Object.assign(Object.assign({}, this._options), { min }));
1626
1659
  clone._id = this._id;
1660
+ clone.shouldCompactAst = this.shouldCompactAst;
1627
1661
  return clone;
1628
1662
  }
1629
1663
  getTokens() {
@@ -1699,6 +1733,7 @@
1699
1733
  return this._children;
1700
1734
  }
1701
1735
  constructor(name, sequence) {
1736
+ this.shouldCompactAst = false;
1702
1737
  if (sequence.length === 0) {
1703
1738
  throw new Error("Need at least one pattern with a 'sequence' pattern.");
1704
1739
  }
@@ -1742,6 +1777,9 @@
1742
1777
  const node = this.createNode(cursor);
1743
1778
  if (node !== null) {
1744
1779
  cursor.recordMatch(this, node);
1780
+ if (this.shouldCompactAst) {
1781
+ node.compact();
1782
+ }
1745
1783
  }
1746
1784
  return node;
1747
1785
  }
@@ -1915,6 +1953,7 @@
1915
1953
  clone(name = this._name) {
1916
1954
  const clone = new Sequence(name, this._children);
1917
1955
  clone._id = this._id;
1956
+ clone.shouldCompactAst = this.shouldCompactAst;
1918
1957
  return clone;
1919
1958
  }
1920
1959
  isEqual(pattern) {
@@ -1974,6 +2013,7 @@
1974
2013
  return this._children;
1975
2014
  }
1976
2015
  constructor(name, pattern) {
2016
+ this.shouldCompactAst = false;
1977
2017
  this._id = `optional-${idIndex$1++}`;
1978
2018
  this._type = "optional";
1979
2019
  this._name = name;
@@ -2004,13 +2044,17 @@
2004
2044
  return null;
2005
2045
  }
2006
2046
  else {
2047
+ if (node != null && this.shouldCompactAst) {
2048
+ node.compact();
2049
+ }
2007
2050
  return node;
2008
2051
  }
2009
2052
  }
2010
2053
  clone(name = this._name) {
2011
- const optional = new Optional(name, this._children[0]);
2012
- optional._id = this._id;
2013
- return optional;
2054
+ const clone = new Optional(name, this._children[0]);
2055
+ clone._id = this._id;
2056
+ clone.shouldCompactAst = this.shouldCompactAst;
2057
+ return clone;
2014
2058
  }
2015
2059
  getTokens() {
2016
2060
  return this._children[0].getTokens();
@@ -2159,13 +2203,17 @@
2159
2203
 
2160
2204
  const optionalSpaces$2 = new Optional("optional-spaces", spaces$1);
2161
2205
  const assignOperator = new Literal("assign-operator", "=");
2206
+ const compact = new Literal("compact", "compact");
2207
+ const compactModifier = new Sequence("compact-modifier", [lineSpaces$1, compact]);
2208
+ const optionalCompactModifier = new Optional("optional-compact-modifier", compactModifier);
2162
2209
  const assignStatement = new Sequence("assign-statement", [
2163
2210
  optionalSpaces$2,
2164
2211
  name$1,
2165
2212
  optionalSpaces$2,
2166
2213
  assignOperator,
2167
2214
  optionalSpaces$2,
2168
- pattern
2215
+ pattern,
2216
+ optionalCompactModifier
2169
2217
  ]);
2170
2218
  const statement = new Options("statement", [assignStatement, name$1.clone("export-name")]);
2171
2219
 
@@ -2286,6 +2334,7 @@
2286
2334
  return this._children;
2287
2335
  }
2288
2336
  constructor(name, pattern) {
2337
+ this.shouldCompactAst = false;
2289
2338
  this._id = `not-${idIndex++}`;
2290
2339
  this._type = "not";
2291
2340
  this._name = name;
@@ -2630,6 +2679,7 @@
2630
2679
  return Object.assign({}, this._patterns);
2631
2680
  }
2632
2681
  constructor(name, pattern, context = []) {
2682
+ this.shouldCompactAst = false;
2633
2683
  this._id = `context-${contextId++}`;
2634
2684
  this._type = "context";
2635
2685
  this._name = name;
@@ -2653,6 +2703,7 @@
2653
2703
  clone(name = this._name) {
2654
2704
  const clone = new Context(name, this._pattern, Object.values(this._patterns));
2655
2705
  clone._id = this._id;
2706
+ clone.shouldCompactAst = this.shouldCompactAst;
2656
2707
  return clone;
2657
2708
  }
2658
2709
  getTokens() {
@@ -2732,6 +2783,7 @@
2732
2783
  return this._recursivePatterns;
2733
2784
  }
2734
2785
  constructor(name, patterns) {
2786
+ this.shouldCompactAst = false;
2735
2787
  if (patterns.length === 0) {
2736
2788
  throw new Error("Need at least one pattern with an 'expression' pattern.");
2737
2789
  }
@@ -2749,6 +2801,7 @@
2749
2801
  this._binaryAssociation = [];
2750
2802
  this._precedenceMap = {};
2751
2803
  this._originalPatterns = patterns;
2804
+ this._shouldCompactPatternsMap = {};
2752
2805
  this._patterns = this._organizePatterns(patterns);
2753
2806
  if (this._unaryPatterns.length === 0) {
2754
2807
  throw new Error("Need at least one operand pattern with an 'expression' pattern.");
@@ -2757,6 +2810,7 @@
2757
2810
  _organizePatterns(patterns) {
2758
2811
  const finalPatterns = [];
2759
2812
  patterns.forEach((pattern) => {
2813
+ this._shouldCompactPatternsMap[pattern.name] = pattern.shouldCompactAst;
2760
2814
  if (this._isBinary(pattern)) {
2761
2815
  const binaryName = this._extractName(pattern);
2762
2816
  const clone = this._extractDelimiter(pattern).clone();
@@ -2854,11 +2908,31 @@
2854
2908
  if (node != null) {
2855
2909
  cursor.moveTo(node.lastIndex);
2856
2910
  cursor.resolveError();
2911
+ this._compactResult(node);
2857
2912
  return node;
2858
2913
  }
2859
2914
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
2860
2915
  return null;
2861
2916
  }
2917
+ _compactResult(node) {
2918
+ if (node == null) {
2919
+ return;
2920
+ }
2921
+ if (this.shouldCompactAst) {
2922
+ node.compact();
2923
+ return;
2924
+ }
2925
+ // This could be really expensive with large trees. So we optimize with these checks,
2926
+ // as well as use breadth first as to not recompact nodes over and over again.
2927
+ const isCompactingNeeded = Object.values(this._shouldCompactPatternsMap).some(p => p);
2928
+ if (isCompactingNeeded) {
2929
+ node.walkBreadthFirst(n => {
2930
+ if (this._shouldCompactPatternsMap[n.name]) {
2931
+ n.compact();
2932
+ }
2933
+ });
2934
+ }
2935
+ }
2862
2936
  _tryToParse(cursor) {
2863
2937
  if (depthCache.getDepth(this._id, this._firstIndex) > 2) {
2864
2938
  cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
@@ -3099,6 +3173,7 @@
3099
3173
  clone(name = this._name) {
3100
3174
  const clone = new ExpressionPattern(name, this._originalPatterns);
3101
3175
  clone._id = this._id;
3176
+ clone.shouldCompactAst = this.shouldCompactAst;
3102
3177
  return clone;
3103
3178
  }
3104
3179
  isEqual(pattern) {
@@ -3279,9 +3354,13 @@
3279
3354
  }
3280
3355
  _saveOptions(statementNode) {
3281
3356
  const nameNode = statementNode.find(n => n.name === "name");
3357
+ const shouldCompactAst = statementNode.find(n => n.name === "compact");
3282
3358
  const name = nameNode.value;
3283
3359
  const optionsNode = statementNode.find(n => n.name === "options-literal");
3284
3360
  const options = this._buildOptions(name, optionsNode);
3361
+ if (shouldCompactAst != null) {
3362
+ options.shouldCompactAst = true;
3363
+ }
3285
3364
  this._parseContext.patternsByName.set(name, options);
3286
3365
  }
3287
3366
  _buildOptions(name, node) {
@@ -3341,9 +3420,13 @@
3341
3420
  }
3342
3421
  _saveSequence(statementNode) {
3343
3422
  const nameNode = statementNode.find(n => n.name === "name");
3423
+ const shouldCompactAst = statementNode.find(n => n.name === "compact");
3344
3424
  const name = nameNode.value;
3345
3425
  const sequenceNode = statementNode.find(n => n.name === "sequence-literal");
3346
3426
  const sequence = this._buildSequence(name, sequenceNode);
3427
+ if (shouldCompactAst != null) {
3428
+ sequence.shouldCompactAst = true;
3429
+ }
3347
3430
  this._parseContext.patternsByName.set(name, sequence);
3348
3431
  }
3349
3432
  _buildSequence(name, node) {
@@ -3363,9 +3446,13 @@
3363
3446
  }
3364
3447
  _saveRepeat(statementNode) {
3365
3448
  const nameNode = statementNode.find(n => n.name === "name");
3449
+ const shouldCompactAst = statementNode.find(n => n.name === "compact");
3366
3450
  const name = nameNode.value;
3367
3451
  const repeatNode = statementNode.find(n => n.name === "repeat-literal");
3368
3452
  const repeat = this._buildRepeat(name, repeatNode);
3453
+ if (shouldCompactAst != null) {
3454
+ repeat.shouldCompactAst = true;
3455
+ }
3369
3456
  this._parseContext.patternsByName.set(name, repeat);
3370
3457
  }
3371
3458
  _buildRepeat(name, repeatNode) {
@@ -3518,10 +3605,14 @@
3518
3605
  }
3519
3606
  _saveAlias(statementNode) {
3520
3607
  const nameNode = statementNode.find(n => n.name === "name");
3608
+ const shouldCompactAst = statementNode.find(n => n.name === "compact");
3521
3609
  const aliasNode = statementNode.find(n => n.name === "alias-literal");
3522
3610
  const aliasName = aliasNode.value;
3523
3611
  const name = nameNode.value;
3524
3612
  const alias = this._getPattern(aliasName).clone(name);
3613
+ if (shouldCompactAst != null) {
3614
+ alias.shouldCompactAst = true;
3615
+ }
3525
3616
  this._parseContext.patternsByName.set(name, alias);
3526
3617
  }
3527
3618
  static parse(expression, options) {