clarity-pattern-parser 8.1.7 → 8.2.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.
package/dist/index.esm.js CHANGED
@@ -1,14 +1,4 @@
1
1
  class Node {
2
- constructor(type, name, firstIndex, lastIndex, children = [], value = "") {
3
- this._type = type;
4
- this._name = name;
5
- this._firstIndex = firstIndex;
6
- this._lastIndex = lastIndex;
7
- this._parent = null;
8
- this._children = children;
9
- this._value = value;
10
- this._children.forEach(c => c._parent = this);
11
- }
12
2
  get type() {
13
3
  return this._type;
14
4
  }
@@ -39,6 +29,16 @@ class Node {
39
29
  get value() {
40
30
  return this.toString();
41
31
  }
32
+ constructor(type, name, firstIndex, lastIndex, children = [], value = "") {
33
+ this._type = type;
34
+ this._name = name;
35
+ this._firstIndex = firstIndex;
36
+ this._lastIndex = lastIndex;
37
+ this._parent = null;
38
+ this._children = children;
39
+ this._value = value;
40
+ this._children.forEach(c => c._parent = this);
41
+ }
42
42
  removeChild(node) {
43
43
  const index = this._children.indexOf(node);
44
44
  if (index > -1) {
@@ -279,12 +279,6 @@ class CursorHistory {
279
279
  }
280
280
 
281
281
  class Cursor {
282
- constructor(text) {
283
- this._text = text;
284
- this._index = 0;
285
- this._length = text.length;
286
- this._history = new CursorHistory();
287
- }
288
282
  get text() {
289
283
  return this._text;
290
284
  }
@@ -327,6 +321,12 @@ class Cursor {
327
321
  get currentChar() {
328
322
  return this._text[this._index];
329
323
  }
324
+ constructor(text) {
325
+ this._text = text;
326
+ this._index = 0;
327
+ this._length = text.length;
328
+ this._history = new CursorHistory();
329
+ }
330
330
  hasNext() {
331
331
  return this._index + 1 < this._length;
332
332
  }
@@ -378,20 +378,6 @@ class Cursor {
378
378
  }
379
379
 
380
380
  class Literal {
381
- constructor(name, value, isOptional = false) {
382
- if (value.length === 0) {
383
- throw new Error("Value Cannot be empty.");
384
- }
385
- this._type = "literal";
386
- this._name = name;
387
- this._literal = value;
388
- this._runes = Array.from(value);
389
- this._isOptional = isOptional;
390
- this._parent = null;
391
- this._firstIndex = 0;
392
- this._lastIndex = 0;
393
- this._endIndex = 0;
394
- }
395
381
  get type() {
396
382
  return this._type;
397
383
  }
@@ -410,6 +396,20 @@ class Literal {
410
396
  get isOptional() {
411
397
  return this._isOptional;
412
398
  }
399
+ constructor(name, value, isOptional = false) {
400
+ if (value.length === 0) {
401
+ throw new Error("Value Cannot be empty.");
402
+ }
403
+ this._type = "literal";
404
+ this._name = name;
405
+ this._literal = value;
406
+ this._runes = Array.from(value);
407
+ this._isOptional = isOptional;
408
+ this._parent = null;
409
+ this._firstIndex = 0;
410
+ this._lastIndex = 0;
411
+ this._endIndex = 0;
412
+ }
413
413
  test(text) {
414
414
  const cursor = new Cursor(text);
415
415
  const ast = this.parse(cursor);
@@ -500,20 +500,6 @@ class Literal {
500
500
  }
501
501
 
502
502
  class Regex {
503
- constructor(name, regex, isOptional = false) {
504
- this._node = null;
505
- this._cursor = null;
506
- this._firstIndex = -1;
507
- this._substring = "";
508
- this._tokens = [];
509
- this._type = "regex";
510
- this._name = name;
511
- this._isOptional = isOptional;
512
- this._parent = null;
513
- this._originalRegexString = regex;
514
- this._regex = new RegExp(`^${regex}`, "g");
515
- this.assertArguments();
516
- }
517
503
  get type() {
518
504
  return this._type;
519
505
  }
@@ -532,6 +518,20 @@ class Regex {
532
518
  get isOptional() {
533
519
  return this._isOptional;
534
520
  }
521
+ constructor(name, regex, isOptional = false) {
522
+ this._node = null;
523
+ this._cursor = null;
524
+ this._firstIndex = -1;
525
+ this._substring = "";
526
+ this._tokens = [];
527
+ this._type = "regex";
528
+ this._name = name;
529
+ this._isOptional = isOptional;
530
+ this._parent = null;
531
+ this._originalRegexString = regex;
532
+ this._regex = new RegExp(`^${regex}`, "g");
533
+ this.assertArguments();
534
+ }
535
535
  assertArguments() {
536
536
  if (this._originalRegexString.length < 1) {
537
537
  throw new Error("Invalid Arguments: The regex string argument needs to be at least one character long.");
@@ -650,14 +650,6 @@ function findPattern(pattern, predicate) {
650
650
  }
651
651
 
652
652
  class Reference {
653
- constructor(name, isOptional = false) {
654
- this._type = "reference";
655
- this._name = name;
656
- this._parent = null;
657
- this._isOptional = isOptional;
658
- this._pattern = null;
659
- this._children = [];
660
- }
661
653
  get type() {
662
654
  return this._type;
663
655
  }
@@ -676,6 +668,14 @@ class Reference {
676
668
  get isOptional() {
677
669
  return this._isOptional;
678
670
  }
671
+ constructor(name, isOptional = false) {
672
+ this._type = "reference";
673
+ this._name = name;
674
+ this._parent = null;
675
+ this._isOptional = isOptional;
676
+ this._pattern = null;
677
+ this._children = [];
678
+ }
679
679
  test(text) {
680
680
  const cursor = new Cursor(text);
681
681
  const ast = this.parse(cursor);
@@ -767,19 +767,6 @@ function clonePatterns(patterns, isOptional) {
767
767
  }
768
768
 
769
769
  class Or {
770
- constructor(name, options, isOptional = false) {
771
- if (options.length === 0) {
772
- throw new Error("Need at least one pattern with an 'or' pattern.");
773
- }
774
- const children = clonePatterns(options, false);
775
- this._assignChildrenToParent(children);
776
- this._type = "or";
777
- this._name = name;
778
- this._parent = null;
779
- this._children = children;
780
- this._isOptional = isOptional;
781
- this._firstIndex = 0;
782
- }
783
770
  get type() {
784
771
  return this._type;
785
772
  }
@@ -798,6 +785,20 @@ class Or {
798
785
  get isOptional() {
799
786
  return this._isOptional;
800
787
  }
788
+ constructor(name, options, isOptional = false, isGreedy = false) {
789
+ if (options.length === 0) {
790
+ throw new Error("Need at least one pattern with an 'or' pattern.");
791
+ }
792
+ const children = clonePatterns(options, false);
793
+ this._assignChildrenToParent(children);
794
+ this._type = "or";
795
+ this._name = name;
796
+ this._parent = null;
797
+ this._children = children;
798
+ this._isOptional = isOptional;
799
+ this._firstIndex = 0;
800
+ this._isGreedy = isGreedy;
801
+ }
801
802
  _assignChildrenToParent(children) {
802
803
  for (const child of children) {
803
804
  child.parent = this;
@@ -820,6 +821,7 @@ class Or {
820
821
  this._firstIndex = cursor.index;
821
822
  const node = this._tryToParse(cursor);
822
823
  if (node != null) {
824
+ cursor.moveTo(node.lastIndex);
823
825
  cursor.resolveError();
824
826
  return node;
825
827
  }
@@ -832,15 +834,21 @@ class Or {
832
834
  return null;
833
835
  }
834
836
  _tryToParse(cursor) {
837
+ const results = [];
835
838
  for (const pattern of this._children) {
836
839
  cursor.moveTo(this._firstIndex);
837
840
  const result = pattern.parse(cursor);
838
- if (!cursor.hasError) {
841
+ if (this._isGreedy) {
842
+ results.push(result);
843
+ }
844
+ if (!cursor.hasError && !this._isGreedy) {
839
845
  return result;
840
846
  }
841
847
  cursor.resolveError();
842
848
  }
843
- return null;
849
+ const nonNullResults = results.filter(r => r != null);
850
+ nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
851
+ return nonNullResults[0] || null;
844
852
  }
845
853
  getTokens() {
846
854
  const tokens = [];
@@ -884,28 +892,12 @@ class Or {
884
892
  return findPattern(this, predicate);
885
893
  }
886
894
  clone(name = this._name, isOptional = this._isOptional) {
887
- const or = new Or(name, this._children, isOptional);
895
+ const or = new Or(name, this._children, isOptional, this._isGreedy);
888
896
  return or;
889
897
  }
890
898
  }
891
899
 
892
900
  class FiniteRepeat {
893
- constructor(name, pattern, repeatAmount, options = {}) {
894
- this._type = "finite-repeat";
895
- this._name = name;
896
- this._parent = null;
897
- this._children = [];
898
- this._hasDivider = options.divider != null;
899
- this._min = options.min != null ? options.min : 1;
900
- this._max = repeatAmount;
901
- this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
902
- for (let i = 0; i < repeatAmount; i++) {
903
- this._children.push(pattern.clone(pattern.name));
904
- if (options.divider != null && (i < repeatAmount - 1 || !this._trimDivider)) {
905
- this._children.push(options.divider.clone(options.divider.name, false));
906
- }
907
- }
908
- }
909
901
  get type() {
910
902
  return this._type;
911
903
  }
@@ -930,6 +922,22 @@ class FiniteRepeat {
930
922
  get max() {
931
923
  return this._max;
932
924
  }
925
+ constructor(name, pattern, repeatAmount, options = {}) {
926
+ this._type = "finite-repeat";
927
+ this._name = name;
928
+ this._parent = null;
929
+ this._children = [];
930
+ this._hasDivider = options.divider != null;
931
+ this._min = options.min != null ? options.min : 1;
932
+ this._max = repeatAmount;
933
+ this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
934
+ for (let i = 0; i < repeatAmount; i++) {
935
+ this._children.push(pattern.clone(pattern.name));
936
+ if (options.divider != null && (i < repeatAmount - 1 || !this._trimDivider)) {
937
+ this._children.push(options.divider.clone(options.divider.name, false));
938
+ }
939
+ }
940
+ }
933
941
  parse(cursor) {
934
942
  const startIndex = cursor.index;
935
943
  const nodes = [];
@@ -1054,6 +1062,27 @@ class FiniteRepeat {
1054
1062
  }
1055
1063
 
1056
1064
  class InfiniteRepeat {
1065
+ get type() {
1066
+ return this._type;
1067
+ }
1068
+ get name() {
1069
+ return this._name;
1070
+ }
1071
+ get parent() {
1072
+ return this._parent;
1073
+ }
1074
+ set parent(pattern) {
1075
+ this._parent = pattern;
1076
+ }
1077
+ get children() {
1078
+ return this._children;
1079
+ }
1080
+ get isOptional() {
1081
+ return this._min === 0;
1082
+ }
1083
+ get min() {
1084
+ return this._min;
1085
+ }
1057
1086
  constructor(name, pattern, options = {}) {
1058
1087
  const min = options.min != null ? options.min : 1;
1059
1088
  const divider = options.divider;
@@ -1076,27 +1105,6 @@ class InfiniteRepeat {
1076
1105
  this._nodes = [];
1077
1106
  this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
1078
1107
  }
1079
- get type() {
1080
- return this._type;
1081
- }
1082
- get name() {
1083
- return this._name;
1084
- }
1085
- get parent() {
1086
- return this._parent;
1087
- }
1088
- set parent(pattern) {
1089
- this._parent = pattern;
1090
- }
1091
- get children() {
1092
- return this._children;
1093
- }
1094
- get isOptional() {
1095
- return this._min === 0;
1096
- }
1097
- get min() {
1098
- return this._min;
1099
- }
1100
1108
  _assignChildrenToParent(children) {
1101
1109
  for (const child of children) {
1102
1110
  child.parent = this;
@@ -1290,19 +1298,6 @@ class InfiniteRepeat {
1290
1298
  }
1291
1299
 
1292
1300
  class Repeat {
1293
- constructor(name, pattern, options = {}) {
1294
- this._pattern = pattern;
1295
- this._parent = null;
1296
- this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1297
- if (this._options.max !== Infinity) {
1298
- this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
1299
- }
1300
- else {
1301
- this._repeatPattern = new InfiniteRepeat(name, pattern, this._options);
1302
- }
1303
- this._children = [this._repeatPattern];
1304
- this._repeatPattern.parent = this;
1305
- }
1306
1301
  get type() {
1307
1302
  return this._repeatPattern.type;
1308
1303
  }
@@ -1321,6 +1316,19 @@ class Repeat {
1321
1316
  get isOptional() {
1322
1317
  return this._repeatPattern.isOptional;
1323
1318
  }
1319
+ constructor(name, pattern, options = {}) {
1320
+ this._pattern = pattern;
1321
+ this._parent = null;
1322
+ this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1323
+ if (this._options.max !== Infinity) {
1324
+ this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
1325
+ }
1326
+ else {
1327
+ this._repeatPattern = new InfiniteRepeat(name, pattern, this._options);
1328
+ }
1329
+ this._children = [this._repeatPattern];
1330
+ this._repeatPattern.parent = this;
1331
+ }
1324
1332
  parse(cursor) {
1325
1333
  return this._repeatPattern.parse(cursor);
1326
1334
  }
@@ -1390,20 +1398,6 @@ function filterOutNull(nodes) {
1390
1398
  }
1391
1399
 
1392
1400
  class And {
1393
- constructor(name, sequence, isOptional = false) {
1394
- if (sequence.length === 0) {
1395
- throw new Error("Need at least one pattern with an 'and' pattern.");
1396
- }
1397
- const children = clonePatterns(sequence);
1398
- this._assignChildrenToParent(children);
1399
- this._type = "and";
1400
- this._name = name;
1401
- this._isOptional = isOptional;
1402
- this._parent = null;
1403
- this._children = children;
1404
- this._firstIndex = -1;
1405
- this._nodes = [];
1406
- }
1407
1401
  get type() {
1408
1402
  return this._type;
1409
1403
  }
@@ -1422,6 +1416,20 @@ class And {
1422
1416
  get isOptional() {
1423
1417
  return this._isOptional;
1424
1418
  }
1419
+ constructor(name, sequence, isOptional = false) {
1420
+ if (sequence.length === 0) {
1421
+ throw new Error("Need at least one pattern with an 'and' pattern.");
1422
+ }
1423
+ const children = clonePatterns(sequence);
1424
+ this._assignChildrenToParent(children);
1425
+ this._type = "and";
1426
+ this._name = name;
1427
+ this._isOptional = isOptional;
1428
+ this._parent = null;
1429
+ this._children = children;
1430
+ this._firstIndex = -1;
1431
+ this._nodes = [];
1432
+ }
1425
1433
  _assignChildrenToParent(children) {
1426
1434
  for (const child of children) {
1427
1435
  child.parent = this;
@@ -1738,13 +1746,6 @@ const line = new Or("line", [
1738
1746
  const grammar = new Repeat("grammar", line, { divider: newLine });
1739
1747
 
1740
1748
  class Not {
1741
- constructor(name, pattern) {
1742
- this._type = "not";
1743
- this._name = name;
1744
- this._parent = null;
1745
- this._children = [pattern.clone(pattern.name, false)];
1746
- this._children[0].parent = this;
1747
- }
1748
1749
  get type() {
1749
1750
  return this._type;
1750
1751
  }
@@ -1763,6 +1764,13 @@ class Not {
1763
1764
  get isOptional() {
1764
1765
  return false;
1765
1766
  }
1767
+ constructor(name, pattern) {
1768
+ this._type = "not";
1769
+ this._name = name;
1770
+ this._parent = null;
1771
+ this._children = [pattern.clone(pattern.name, false)];
1772
+ this._children[0].parent = this;
1773
+ }
1766
1774
  test(text) {
1767
1775
  const cursor = new Cursor(text);
1768
1776
  this.parse(cursor);
@@ -2127,10 +2135,10 @@ class Grammar {
2127
2135
  _buildOr(statementNode) {
2128
2136
  const nameNode = statementNode.find(n => n.name === "name");
2129
2137
  const orNode = statementNode.find(n => n.name === "or-literal");
2130
- const patternNodes = orNode.children.filter(n => n.name == "pattern-name");
2138
+ const patternNodes = orNode.children.filter(n => n.name === "pattern-name");
2131
2139
  const name = nameNode.value;
2132
2140
  const patterns = patternNodes.map(n => this._getPattern(n.value));
2133
- const or = new Or(name, patterns);
2141
+ const or = new Or(name, patterns, false, true);
2134
2142
  this._parseContext.patternsByName.set(name, or);
2135
2143
  }
2136
2144
  _getPattern(name) {
@@ -2143,7 +2151,7 @@ class Grammar {
2143
2151
  _buildAnd(statementNode) {
2144
2152
  const nameNode = statementNode.find(n => n.name === "name");
2145
2153
  const andNode = statementNode.find(n => n.name === "and-literal");
2146
- const patternNodes = andNode.children.filter(n => n.name == "pattern");
2154
+ const patternNodes = andNode.children.filter(n => n.name === "pattern");
2147
2155
  const name = nameNode.value;
2148
2156
  const patterns = patternNodes.map(n => {
2149
2157
  const nameNode = n.find(n => n.name === "pattern-name");
@@ -2162,7 +2170,7 @@ class Grammar {
2162
2170
  _buildRepeat(statementNode) {
2163
2171
  const nameNode = statementNode.find(n => n.name === "name");
2164
2172
  const repeatNode = statementNode.find(n => n.name === "repeat-literal");
2165
- const patternNode = repeatNode.find(n => n.name == "pattern");
2173
+ const patternNode = repeatNode.find(n => n.name === "pattern");
2166
2174
  const patternNameNode = patternNode.find(n => n.name === "pattern-name");
2167
2175
  const dividerNode = repeatNode.find(n => n.name === "divider-pattern");
2168
2176
  const bounds = repeatNode.find(n => n.name === "bounds");