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.js CHANGED
@@ -3,16 +3,6 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  class Node {
6
- constructor(type, name, firstIndex, lastIndex, children = [], value = "") {
7
- this._type = type;
8
- this._name = name;
9
- this._firstIndex = firstIndex;
10
- this._lastIndex = lastIndex;
11
- this._parent = null;
12
- this._children = children;
13
- this._value = value;
14
- this._children.forEach(c => c._parent = this);
15
- }
16
6
  get type() {
17
7
  return this._type;
18
8
  }
@@ -43,6 +33,16 @@ class Node {
43
33
  get value() {
44
34
  return this.toString();
45
35
  }
36
+ constructor(type, name, firstIndex, lastIndex, children = [], value = "") {
37
+ this._type = type;
38
+ this._name = name;
39
+ this._firstIndex = firstIndex;
40
+ this._lastIndex = lastIndex;
41
+ this._parent = null;
42
+ this._children = children;
43
+ this._value = value;
44
+ this._children.forEach(c => c._parent = this);
45
+ }
46
46
  removeChild(node) {
47
47
  const index = this._children.indexOf(node);
48
48
  if (index > -1) {
@@ -283,12 +283,6 @@ class CursorHistory {
283
283
  }
284
284
 
285
285
  class Cursor {
286
- constructor(text) {
287
- this._text = text;
288
- this._index = 0;
289
- this._length = text.length;
290
- this._history = new CursorHistory();
291
- }
292
286
  get text() {
293
287
  return this._text;
294
288
  }
@@ -331,6 +325,12 @@ class Cursor {
331
325
  get currentChar() {
332
326
  return this._text[this._index];
333
327
  }
328
+ constructor(text) {
329
+ this._text = text;
330
+ this._index = 0;
331
+ this._length = text.length;
332
+ this._history = new CursorHistory();
333
+ }
334
334
  hasNext() {
335
335
  return this._index + 1 < this._length;
336
336
  }
@@ -382,20 +382,6 @@ class Cursor {
382
382
  }
383
383
 
384
384
  class Literal {
385
- constructor(name, value, isOptional = false) {
386
- if (value.length === 0) {
387
- throw new Error("Value Cannot be empty.");
388
- }
389
- this._type = "literal";
390
- this._name = name;
391
- this._literal = value;
392
- this._runes = Array.from(value);
393
- this._isOptional = isOptional;
394
- this._parent = null;
395
- this._firstIndex = 0;
396
- this._lastIndex = 0;
397
- this._endIndex = 0;
398
- }
399
385
  get type() {
400
386
  return this._type;
401
387
  }
@@ -414,6 +400,20 @@ class Literal {
414
400
  get isOptional() {
415
401
  return this._isOptional;
416
402
  }
403
+ constructor(name, value, isOptional = false) {
404
+ if (value.length === 0) {
405
+ throw new Error("Value Cannot be empty.");
406
+ }
407
+ this._type = "literal";
408
+ this._name = name;
409
+ this._literal = value;
410
+ this._runes = Array.from(value);
411
+ this._isOptional = isOptional;
412
+ this._parent = null;
413
+ this._firstIndex = 0;
414
+ this._lastIndex = 0;
415
+ this._endIndex = 0;
416
+ }
417
417
  test(text) {
418
418
  const cursor = new Cursor(text);
419
419
  const ast = this.parse(cursor);
@@ -504,20 +504,6 @@ class Literal {
504
504
  }
505
505
 
506
506
  class Regex {
507
- constructor(name, regex, isOptional = false) {
508
- this._node = null;
509
- this._cursor = null;
510
- this._firstIndex = -1;
511
- this._substring = "";
512
- this._tokens = [];
513
- this._type = "regex";
514
- this._name = name;
515
- this._isOptional = isOptional;
516
- this._parent = null;
517
- this._originalRegexString = regex;
518
- this._regex = new RegExp(`^${regex}`, "g");
519
- this.assertArguments();
520
- }
521
507
  get type() {
522
508
  return this._type;
523
509
  }
@@ -536,6 +522,20 @@ class Regex {
536
522
  get isOptional() {
537
523
  return this._isOptional;
538
524
  }
525
+ constructor(name, regex, isOptional = false) {
526
+ this._node = null;
527
+ this._cursor = null;
528
+ this._firstIndex = -1;
529
+ this._substring = "";
530
+ this._tokens = [];
531
+ this._type = "regex";
532
+ this._name = name;
533
+ this._isOptional = isOptional;
534
+ this._parent = null;
535
+ this._originalRegexString = regex;
536
+ this._regex = new RegExp(`^${regex}`, "g");
537
+ this.assertArguments();
538
+ }
539
539
  assertArguments() {
540
540
  if (this._originalRegexString.length < 1) {
541
541
  throw new Error("Invalid Arguments: The regex string argument needs to be at least one character long.");
@@ -654,14 +654,6 @@ function findPattern(pattern, predicate) {
654
654
  }
655
655
 
656
656
  class Reference {
657
- constructor(name, isOptional = false) {
658
- this._type = "reference";
659
- this._name = name;
660
- this._parent = null;
661
- this._isOptional = isOptional;
662
- this._pattern = null;
663
- this._children = [];
664
- }
665
657
  get type() {
666
658
  return this._type;
667
659
  }
@@ -680,6 +672,14 @@ class Reference {
680
672
  get isOptional() {
681
673
  return this._isOptional;
682
674
  }
675
+ constructor(name, isOptional = false) {
676
+ this._type = "reference";
677
+ this._name = name;
678
+ this._parent = null;
679
+ this._isOptional = isOptional;
680
+ this._pattern = null;
681
+ this._children = [];
682
+ }
683
683
  test(text) {
684
684
  const cursor = new Cursor(text);
685
685
  const ast = this.parse(cursor);
@@ -771,19 +771,6 @@ function clonePatterns(patterns, isOptional) {
771
771
  }
772
772
 
773
773
  class Or {
774
- constructor(name, options, isOptional = false) {
775
- if (options.length === 0) {
776
- throw new Error("Need at least one pattern with an 'or' pattern.");
777
- }
778
- const children = clonePatterns(options, false);
779
- this._assignChildrenToParent(children);
780
- this._type = "or";
781
- this._name = name;
782
- this._parent = null;
783
- this._children = children;
784
- this._isOptional = isOptional;
785
- this._firstIndex = 0;
786
- }
787
774
  get type() {
788
775
  return this._type;
789
776
  }
@@ -802,6 +789,20 @@ class Or {
802
789
  get isOptional() {
803
790
  return this._isOptional;
804
791
  }
792
+ constructor(name, options, isOptional = false, isGreedy = false) {
793
+ if (options.length === 0) {
794
+ throw new Error("Need at least one pattern with an 'or' pattern.");
795
+ }
796
+ const children = clonePatterns(options, false);
797
+ this._assignChildrenToParent(children);
798
+ this._type = "or";
799
+ this._name = name;
800
+ this._parent = null;
801
+ this._children = children;
802
+ this._isOptional = isOptional;
803
+ this._firstIndex = 0;
804
+ this._isGreedy = isGreedy;
805
+ }
805
806
  _assignChildrenToParent(children) {
806
807
  for (const child of children) {
807
808
  child.parent = this;
@@ -824,6 +825,7 @@ class Or {
824
825
  this._firstIndex = cursor.index;
825
826
  const node = this._tryToParse(cursor);
826
827
  if (node != null) {
828
+ cursor.moveTo(node.lastIndex);
827
829
  cursor.resolveError();
828
830
  return node;
829
831
  }
@@ -836,15 +838,21 @@ class Or {
836
838
  return null;
837
839
  }
838
840
  _tryToParse(cursor) {
841
+ const results = [];
839
842
  for (const pattern of this._children) {
840
843
  cursor.moveTo(this._firstIndex);
841
844
  const result = pattern.parse(cursor);
842
- if (!cursor.hasError) {
845
+ if (this._isGreedy) {
846
+ results.push(result);
847
+ }
848
+ if (!cursor.hasError && !this._isGreedy) {
843
849
  return result;
844
850
  }
845
851
  cursor.resolveError();
846
852
  }
847
- return null;
853
+ const nonNullResults = results.filter(r => r != null);
854
+ nonNullResults.sort((a, b) => b.endIndex - a.endIndex);
855
+ return nonNullResults[0] || null;
848
856
  }
849
857
  getTokens() {
850
858
  const tokens = [];
@@ -888,28 +896,12 @@ class Or {
888
896
  return findPattern(this, predicate);
889
897
  }
890
898
  clone(name = this._name, isOptional = this._isOptional) {
891
- const or = new Or(name, this._children, isOptional);
899
+ const or = new Or(name, this._children, isOptional, this._isGreedy);
892
900
  return or;
893
901
  }
894
902
  }
895
903
 
896
904
  class FiniteRepeat {
897
- constructor(name, pattern, repeatAmount, options = {}) {
898
- this._type = "finite-repeat";
899
- this._name = name;
900
- this._parent = null;
901
- this._children = [];
902
- this._hasDivider = options.divider != null;
903
- this._min = options.min != null ? options.min : 1;
904
- this._max = repeatAmount;
905
- this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
906
- for (let i = 0; i < repeatAmount; i++) {
907
- this._children.push(pattern.clone(pattern.name));
908
- if (options.divider != null && (i < repeatAmount - 1 || !this._trimDivider)) {
909
- this._children.push(options.divider.clone(options.divider.name, false));
910
- }
911
- }
912
- }
913
905
  get type() {
914
906
  return this._type;
915
907
  }
@@ -934,6 +926,22 @@ class FiniteRepeat {
934
926
  get max() {
935
927
  return this._max;
936
928
  }
929
+ constructor(name, pattern, repeatAmount, options = {}) {
930
+ this._type = "finite-repeat";
931
+ this._name = name;
932
+ this._parent = null;
933
+ this._children = [];
934
+ this._hasDivider = options.divider != null;
935
+ this._min = options.min != null ? options.min : 1;
936
+ this._max = repeatAmount;
937
+ this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
938
+ for (let i = 0; i < repeatAmount; i++) {
939
+ this._children.push(pattern.clone(pattern.name));
940
+ if (options.divider != null && (i < repeatAmount - 1 || !this._trimDivider)) {
941
+ this._children.push(options.divider.clone(options.divider.name, false));
942
+ }
943
+ }
944
+ }
937
945
  parse(cursor) {
938
946
  const startIndex = cursor.index;
939
947
  const nodes = [];
@@ -1058,6 +1066,27 @@ class FiniteRepeat {
1058
1066
  }
1059
1067
 
1060
1068
  class InfiniteRepeat {
1069
+ get type() {
1070
+ return this._type;
1071
+ }
1072
+ get name() {
1073
+ return this._name;
1074
+ }
1075
+ get parent() {
1076
+ return this._parent;
1077
+ }
1078
+ set parent(pattern) {
1079
+ this._parent = pattern;
1080
+ }
1081
+ get children() {
1082
+ return this._children;
1083
+ }
1084
+ get isOptional() {
1085
+ return this._min === 0;
1086
+ }
1087
+ get min() {
1088
+ return this._min;
1089
+ }
1061
1090
  constructor(name, pattern, options = {}) {
1062
1091
  const min = options.min != null ? options.min : 1;
1063
1092
  const divider = options.divider;
@@ -1080,27 +1109,6 @@ class InfiniteRepeat {
1080
1109
  this._nodes = [];
1081
1110
  this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
1082
1111
  }
1083
- get type() {
1084
- return this._type;
1085
- }
1086
- get name() {
1087
- return this._name;
1088
- }
1089
- get parent() {
1090
- return this._parent;
1091
- }
1092
- set parent(pattern) {
1093
- this._parent = pattern;
1094
- }
1095
- get children() {
1096
- return this._children;
1097
- }
1098
- get isOptional() {
1099
- return this._min === 0;
1100
- }
1101
- get min() {
1102
- return this._min;
1103
- }
1104
1112
  _assignChildrenToParent(children) {
1105
1113
  for (const child of children) {
1106
1114
  child.parent = this;
@@ -1294,19 +1302,6 @@ class InfiniteRepeat {
1294
1302
  }
1295
1303
 
1296
1304
  class Repeat {
1297
- constructor(name, pattern, options = {}) {
1298
- this._pattern = pattern;
1299
- this._parent = null;
1300
- this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1301
- if (this._options.max !== Infinity) {
1302
- this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
1303
- }
1304
- else {
1305
- this._repeatPattern = new InfiniteRepeat(name, pattern, this._options);
1306
- }
1307
- this._children = [this._repeatPattern];
1308
- this._repeatPattern.parent = this;
1309
- }
1310
1305
  get type() {
1311
1306
  return this._repeatPattern.type;
1312
1307
  }
@@ -1325,6 +1320,19 @@ class Repeat {
1325
1320
  get isOptional() {
1326
1321
  return this._repeatPattern.isOptional;
1327
1322
  }
1323
+ constructor(name, pattern, options = {}) {
1324
+ this._pattern = pattern;
1325
+ this._parent = null;
1326
+ this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1327
+ if (this._options.max !== Infinity) {
1328
+ this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
1329
+ }
1330
+ else {
1331
+ this._repeatPattern = new InfiniteRepeat(name, pattern, this._options);
1332
+ }
1333
+ this._children = [this._repeatPattern];
1334
+ this._repeatPattern.parent = this;
1335
+ }
1328
1336
  parse(cursor) {
1329
1337
  return this._repeatPattern.parse(cursor);
1330
1338
  }
@@ -1394,20 +1402,6 @@ function filterOutNull(nodes) {
1394
1402
  }
1395
1403
 
1396
1404
  class And {
1397
- constructor(name, sequence, isOptional = false) {
1398
- if (sequence.length === 0) {
1399
- throw new Error("Need at least one pattern with an 'and' pattern.");
1400
- }
1401
- const children = clonePatterns(sequence);
1402
- this._assignChildrenToParent(children);
1403
- this._type = "and";
1404
- this._name = name;
1405
- this._isOptional = isOptional;
1406
- this._parent = null;
1407
- this._children = children;
1408
- this._firstIndex = -1;
1409
- this._nodes = [];
1410
- }
1411
1405
  get type() {
1412
1406
  return this._type;
1413
1407
  }
@@ -1426,6 +1420,20 @@ class And {
1426
1420
  get isOptional() {
1427
1421
  return this._isOptional;
1428
1422
  }
1423
+ constructor(name, sequence, isOptional = false) {
1424
+ if (sequence.length === 0) {
1425
+ throw new Error("Need at least one pattern with an 'and' pattern.");
1426
+ }
1427
+ const children = clonePatterns(sequence);
1428
+ this._assignChildrenToParent(children);
1429
+ this._type = "and";
1430
+ this._name = name;
1431
+ this._isOptional = isOptional;
1432
+ this._parent = null;
1433
+ this._children = children;
1434
+ this._firstIndex = -1;
1435
+ this._nodes = [];
1436
+ }
1429
1437
  _assignChildrenToParent(children) {
1430
1438
  for (const child of children) {
1431
1439
  child.parent = this;
@@ -1742,13 +1750,6 @@ const line = new Or("line", [
1742
1750
  const grammar = new Repeat("grammar", line, { divider: newLine });
1743
1751
 
1744
1752
  class Not {
1745
- constructor(name, pattern) {
1746
- this._type = "not";
1747
- this._name = name;
1748
- this._parent = null;
1749
- this._children = [pattern.clone(pattern.name, false)];
1750
- this._children[0].parent = this;
1751
- }
1752
1753
  get type() {
1753
1754
  return this._type;
1754
1755
  }
@@ -1767,6 +1768,13 @@ class Not {
1767
1768
  get isOptional() {
1768
1769
  return false;
1769
1770
  }
1771
+ constructor(name, pattern) {
1772
+ this._type = "not";
1773
+ this._name = name;
1774
+ this._parent = null;
1775
+ this._children = [pattern.clone(pattern.name, false)];
1776
+ this._children[0].parent = this;
1777
+ }
1770
1778
  test(text) {
1771
1779
  const cursor = new Cursor(text);
1772
1780
  this.parse(cursor);
@@ -2131,10 +2139,10 @@ class Grammar {
2131
2139
  _buildOr(statementNode) {
2132
2140
  const nameNode = statementNode.find(n => n.name === "name");
2133
2141
  const orNode = statementNode.find(n => n.name === "or-literal");
2134
- const patternNodes = orNode.children.filter(n => n.name == "pattern-name");
2142
+ const patternNodes = orNode.children.filter(n => n.name === "pattern-name");
2135
2143
  const name = nameNode.value;
2136
2144
  const patterns = patternNodes.map(n => this._getPattern(n.value));
2137
- const or = new Or(name, patterns);
2145
+ const or = new Or(name, patterns, false, true);
2138
2146
  this._parseContext.patternsByName.set(name, or);
2139
2147
  }
2140
2148
  _getPattern(name) {
@@ -2147,7 +2155,7 @@ class Grammar {
2147
2155
  _buildAnd(statementNode) {
2148
2156
  const nameNode = statementNode.find(n => n.name === "name");
2149
2157
  const andNode = statementNode.find(n => n.name === "and-literal");
2150
- const patternNodes = andNode.children.filter(n => n.name == "pattern");
2158
+ const patternNodes = andNode.children.filter(n => n.name === "pattern");
2151
2159
  const name = nameNode.value;
2152
2160
  const patterns = patternNodes.map(n => {
2153
2161
  const nameNode = n.find(n => n.name === "pattern-name");
@@ -2166,7 +2174,7 @@ class Grammar {
2166
2174
  _buildRepeat(statementNode) {
2167
2175
  const nameNode = statementNode.find(n => n.name === "name");
2168
2176
  const repeatNode = statementNode.find(n => n.name === "repeat-literal");
2169
- const patternNode = repeatNode.find(n => n.name == "pattern");
2177
+ const patternNode = repeatNode.find(n => n.name === "pattern");
2170
2178
  const patternNameNode = patternNode.find(n => n.name === "pattern-name");
2171
2179
  const dividerNode = repeatNode.find(n => n.name === "divider-pattern");
2172
2180
  const bounds = repeatNode.find(n => n.name === "bounds");