clarity-pattern-parser 8.2.0 → 8.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.
@@ -2,19 +2,9 @@
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
3
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.clarityPatternParser = {}));
5
- }(this, (function (exports) { 'use strict';
5
+ })(this, (function (exports) { 'use strict';
6
6
 
7
7
  class Node {
8
- constructor(type, name, firstIndex, lastIndex, children = [], value = "") {
9
- this._type = type;
10
- this._name = name;
11
- this._firstIndex = firstIndex;
12
- this._lastIndex = lastIndex;
13
- this._parent = null;
14
- this._children = children;
15
- this._value = value;
16
- this._children.forEach(c => c._parent = this);
17
- }
18
8
  get type() {
19
9
  return this._type;
20
10
  }
@@ -45,6 +35,16 @@
45
35
  get value() {
46
36
  return this.toString();
47
37
  }
38
+ constructor(type, name, firstIndex, lastIndex, children = [], value = "") {
39
+ this._type = type;
40
+ this._name = name;
41
+ this._firstIndex = firstIndex;
42
+ this._lastIndex = lastIndex;
43
+ this._parent = null;
44
+ this._children = children;
45
+ this._value = value;
46
+ this._children.forEach(c => c._parent = this);
47
+ }
48
48
  removeChild(node) {
49
49
  const index = this._children.indexOf(node);
50
50
  if (index > -1) {
@@ -182,6 +182,36 @@
182
182
  }
183
183
  }
184
184
 
185
+ /******************************************************************************
186
+ Copyright (c) Microsoft Corporation.
187
+
188
+ Permission to use, copy, modify, and/or distribute this software for any
189
+ purpose with or without fee is hereby granted.
190
+
191
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
192
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
193
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
194
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
195
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
196
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
197
+ PERFORMANCE OF THIS SOFTWARE.
198
+ ***************************************************************************** */
199
+
200
+ function __awaiter(thisArg, _arguments, P, generator) {
201
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
202
+ return new (P || (P = Promise))(function (resolve, reject) {
203
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
204
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
205
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
206
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
207
+ });
208
+ }
209
+
210
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
211
+ var e = new Error(message);
212
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
213
+ };
214
+
185
215
  class ParseError {
186
216
  constructor(startIndex, endIndex, pattern) {
187
217
  this.startIndex = startIndex;
@@ -285,12 +315,6 @@
285
315
  }
286
316
 
287
317
  class Cursor {
288
- constructor(text) {
289
- this._text = text;
290
- this._index = 0;
291
- this._length = text.length;
292
- this._history = new CursorHistory();
293
- }
294
318
  get text() {
295
319
  return this._text;
296
320
  }
@@ -333,6 +357,12 @@
333
357
  get currentChar() {
334
358
  return this._text[this._index];
335
359
  }
360
+ constructor(text) {
361
+ this._text = text;
362
+ this._index = 0;
363
+ this._length = text.length;
364
+ this._history = new CursorHistory();
365
+ }
336
366
  hasNext() {
337
367
  return this._index + 1 < this._length;
338
368
  }
@@ -384,20 +414,6 @@
384
414
  }
385
415
 
386
416
  class Literal {
387
- constructor(name, value, isOptional = false) {
388
- if (value.length === 0) {
389
- throw new Error("Value Cannot be empty.");
390
- }
391
- this._type = "literal";
392
- this._name = name;
393
- this._literal = value;
394
- this._runes = Array.from(value);
395
- this._isOptional = isOptional;
396
- this._parent = null;
397
- this._firstIndex = 0;
398
- this._lastIndex = 0;
399
- this._endIndex = 0;
400
- }
401
417
  get type() {
402
418
  return this._type;
403
419
  }
@@ -416,6 +432,20 @@
416
432
  get isOptional() {
417
433
  return this._isOptional;
418
434
  }
435
+ constructor(name, value, isOptional = false) {
436
+ if (value.length === 0) {
437
+ throw new Error("Value Cannot be empty.");
438
+ }
439
+ this._type = "literal";
440
+ this._name = name;
441
+ this._literal = value;
442
+ this._runes = Array.from(value);
443
+ this._isOptional = isOptional;
444
+ this._parent = null;
445
+ this._firstIndex = 0;
446
+ this._lastIndex = 0;
447
+ this._endIndex = 0;
448
+ }
419
449
  test(text) {
420
450
  const cursor = new Cursor(text);
421
451
  const ast = this.parse(cursor);
@@ -506,20 +536,6 @@
506
536
  }
507
537
 
508
538
  class Regex {
509
- constructor(name, regex, isOptional = false) {
510
- this._node = null;
511
- this._cursor = null;
512
- this._firstIndex = -1;
513
- this._substring = "";
514
- this._tokens = [];
515
- this._type = "regex";
516
- this._name = name;
517
- this._isOptional = isOptional;
518
- this._parent = null;
519
- this._originalRegexString = regex;
520
- this._regex = new RegExp(`^${regex}`, "g");
521
- this.assertArguments();
522
- }
523
539
  get type() {
524
540
  return this._type;
525
541
  }
@@ -538,6 +554,20 @@
538
554
  get isOptional() {
539
555
  return this._isOptional;
540
556
  }
557
+ constructor(name, regex, isOptional = false) {
558
+ this._node = null;
559
+ this._cursor = null;
560
+ this._firstIndex = -1;
561
+ this._substring = "";
562
+ this._tokens = [];
563
+ this._type = "regex";
564
+ this._name = name;
565
+ this._isOptional = isOptional;
566
+ this._parent = null;
567
+ this._originalRegexString = regex;
568
+ this._regex = new RegExp(`^${regex}`, "g");
569
+ this.assertArguments();
570
+ }
541
571
  assertArguments() {
542
572
  if (this._originalRegexString.length < 1) {
543
573
  throw new Error("Invalid Arguments: The regex string argument needs to be at least one character long.");
@@ -656,14 +686,6 @@
656
686
  }
657
687
 
658
688
  class Reference {
659
- constructor(name, isOptional = false) {
660
- this._type = "reference";
661
- this._name = name;
662
- this._parent = null;
663
- this._isOptional = isOptional;
664
- this._pattern = null;
665
- this._children = [];
666
- }
667
689
  get type() {
668
690
  return this._type;
669
691
  }
@@ -682,6 +704,14 @@
682
704
  get isOptional() {
683
705
  return this._isOptional;
684
706
  }
707
+ constructor(name, isOptional = false) {
708
+ this._type = "reference";
709
+ this._name = name;
710
+ this._parent = null;
711
+ this._isOptional = isOptional;
712
+ this._pattern = null;
713
+ this._children = [];
714
+ }
685
715
  test(text) {
686
716
  const cursor = new Cursor(text);
687
717
  const ast = this.parse(cursor);
@@ -773,20 +803,6 @@
773
803
  }
774
804
 
775
805
  class Or {
776
- constructor(name, options, isOptional = false, isGreedy = false) {
777
- if (options.length === 0) {
778
- throw new Error("Need at least one pattern with an 'or' pattern.");
779
- }
780
- const children = clonePatterns(options, false);
781
- this._assignChildrenToParent(children);
782
- this._type = "or";
783
- this._name = name;
784
- this._parent = null;
785
- this._children = children;
786
- this._isOptional = isOptional;
787
- this._firstIndex = 0;
788
- this._isGreedy = isGreedy;
789
- }
790
806
  get type() {
791
807
  return this._type;
792
808
  }
@@ -805,6 +821,20 @@
805
821
  get isOptional() {
806
822
  return this._isOptional;
807
823
  }
824
+ constructor(name, options, isOptional = false, isGreedy = false) {
825
+ if (options.length === 0) {
826
+ throw new Error("Need at least one pattern with an 'or' pattern.");
827
+ }
828
+ const children = clonePatterns(options, false);
829
+ this._assignChildrenToParent(children);
830
+ this._type = "or";
831
+ this._name = name;
832
+ this._parent = null;
833
+ this._children = children;
834
+ this._isOptional = isOptional;
835
+ this._firstIndex = 0;
836
+ this._isGreedy = isGreedy;
837
+ }
808
838
  _assignChildrenToParent(children) {
809
839
  for (const child of children) {
810
840
  child.parent = this;
@@ -827,6 +857,7 @@
827
857
  this._firstIndex = cursor.index;
828
858
  const node = this._tryToParse(cursor);
829
859
  if (node != null) {
860
+ cursor.moveTo(node.lastIndex);
830
861
  cursor.resolveError();
831
862
  return node;
832
863
  }
@@ -897,28 +928,12 @@
897
928
  return findPattern(this, predicate);
898
929
  }
899
930
  clone(name = this._name, isOptional = this._isOptional) {
900
- const or = new Or(name, this._children, isOptional);
931
+ const or = new Or(name, this._children, isOptional, this._isGreedy);
901
932
  return or;
902
933
  }
903
934
  }
904
935
 
905
936
  class FiniteRepeat {
906
- constructor(name, pattern, repeatAmount, options = {}) {
907
- this._type = "finite-repeat";
908
- this._name = name;
909
- this._parent = null;
910
- this._children = [];
911
- this._hasDivider = options.divider != null;
912
- this._min = options.min != null ? options.min : 1;
913
- this._max = repeatAmount;
914
- this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
915
- for (let i = 0; i < repeatAmount; i++) {
916
- this._children.push(pattern.clone(pattern.name));
917
- if (options.divider != null && (i < repeatAmount - 1 || !this._trimDivider)) {
918
- this._children.push(options.divider.clone(options.divider.name, false));
919
- }
920
- }
921
- }
922
937
  get type() {
923
938
  return this._type;
924
939
  }
@@ -943,6 +958,22 @@
943
958
  get max() {
944
959
  return this._max;
945
960
  }
961
+ constructor(name, pattern, repeatAmount, options = {}) {
962
+ this._type = "finite-repeat";
963
+ this._name = name;
964
+ this._parent = null;
965
+ this._children = [];
966
+ this._hasDivider = options.divider != null;
967
+ this._min = options.min != null ? options.min : 1;
968
+ this._max = repeatAmount;
969
+ this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
970
+ for (let i = 0; i < repeatAmount; i++) {
971
+ this._children.push(pattern.clone(pattern.name));
972
+ if (options.divider != null && (i < repeatAmount - 1 || !this._trimDivider)) {
973
+ this._children.push(options.divider.clone(options.divider.name, false));
974
+ }
975
+ }
976
+ }
946
977
  parse(cursor) {
947
978
  const startIndex = cursor.index;
948
979
  const nodes = [];
@@ -975,8 +1006,9 @@
975
1006
  }
976
1007
  }
977
1008
  if (matchCount < this._min) {
1009
+ const lastIndex = cursor.index;
978
1010
  cursor.moveTo(startIndex);
979
- cursor.recordErrorAt(startIndex, startIndex, this);
1011
+ cursor.recordErrorAt(startIndex, lastIndex, this);
980
1012
  return null;
981
1013
  }
982
1014
  else if (nodes.length === 0) {
@@ -1067,28 +1099,6 @@
1067
1099
  }
1068
1100
 
1069
1101
  class InfiniteRepeat {
1070
- constructor(name, pattern, options = {}) {
1071
- const min = options.min != null ? options.min : 1;
1072
- const divider = options.divider;
1073
- let children;
1074
- if (divider != null) {
1075
- children = [pattern.clone(), divider.clone(divider.name, false)];
1076
- }
1077
- else {
1078
- children = [pattern.clone()];
1079
- }
1080
- this._assignChildrenToParent(children);
1081
- this._type = "infinite-repeat";
1082
- this._name = name;
1083
- this._min = min;
1084
- this._parent = null;
1085
- this._children = children;
1086
- this._pattern = children[0];
1087
- this._divider = children[1];
1088
- this._firstIndex = -1;
1089
- this._nodes = [];
1090
- this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
1091
- }
1092
1102
  get type() {
1093
1103
  return this._type;
1094
1104
  }
@@ -1110,6 +1120,28 @@
1110
1120
  get min() {
1111
1121
  return this._min;
1112
1122
  }
1123
+ constructor(name, pattern, options = {}) {
1124
+ const min = options.min != null ? options.min : 1;
1125
+ const divider = options.divider;
1126
+ let children;
1127
+ if (divider != null) {
1128
+ children = [pattern.clone(pattern.name, false), divider.clone(divider.name, false)];
1129
+ }
1130
+ else {
1131
+ children = [pattern.clone(pattern.name, false)];
1132
+ }
1133
+ this._assignChildrenToParent(children);
1134
+ this._type = "infinite-repeat";
1135
+ this._name = name;
1136
+ this._min = min;
1137
+ this._parent = null;
1138
+ this._children = children;
1139
+ this._pattern = children[0];
1140
+ this._divider = children[1];
1141
+ this._firstIndex = -1;
1142
+ this._nodes = [];
1143
+ this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
1144
+ }
1113
1145
  _assignChildrenToParent(children) {
1114
1146
  for (const child of children) {
1115
1147
  child.parent = this;
@@ -1216,6 +1248,10 @@
1216
1248
  const dividerNode = this._nodes.pop();
1217
1249
  cursor.moveTo(dividerNode.firstIndex);
1218
1250
  }
1251
+ // if (this._nodes.length === 0) {
1252
+ // cursor.moveTo(this._firstIndex);
1253
+ // return null;
1254
+ // }
1219
1255
  const lastIndex = this._nodes[this._nodes.length - 1].lastIndex;
1220
1256
  cursor.moveTo(lastIndex);
1221
1257
  return new Node(this._type, this._name, this._firstIndex, lastIndex, this._nodes);
@@ -1303,19 +1339,6 @@
1303
1339
  }
1304
1340
 
1305
1341
  class Repeat {
1306
- constructor(name, pattern, options = {}) {
1307
- this._pattern = pattern;
1308
- this._parent = null;
1309
- this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1310
- if (this._options.max !== Infinity) {
1311
- this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
1312
- }
1313
- else {
1314
- this._repeatPattern = new InfiniteRepeat(name, pattern, this._options);
1315
- }
1316
- this._children = [this._repeatPattern];
1317
- this._repeatPattern.parent = this;
1318
- }
1319
1342
  get type() {
1320
1343
  return this._repeatPattern.type;
1321
1344
  }
@@ -1334,6 +1357,19 @@
1334
1357
  get isOptional() {
1335
1358
  return this._repeatPattern.isOptional;
1336
1359
  }
1360
+ constructor(name, pattern, options = {}) {
1361
+ this._pattern = pattern;
1362
+ this._parent = null;
1363
+ this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1364
+ if (this._options.max !== Infinity) {
1365
+ this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
1366
+ }
1367
+ else {
1368
+ this._repeatPattern = new InfiniteRepeat(name, pattern, this._options);
1369
+ }
1370
+ this._children = [this._repeatPattern];
1371
+ this._repeatPattern.parent = this;
1372
+ }
1337
1373
  parse(cursor) {
1338
1374
  return this._repeatPattern.parse(cursor);
1339
1375
  }
@@ -1403,20 +1439,6 @@
1403
1439
  }
1404
1440
 
1405
1441
  class And {
1406
- constructor(name, sequence, isOptional = false) {
1407
- if (sequence.length === 0) {
1408
- throw new Error("Need at least one pattern with an 'and' pattern.");
1409
- }
1410
- const children = clonePatterns(sequence);
1411
- this._assignChildrenToParent(children);
1412
- this._type = "and";
1413
- this._name = name;
1414
- this._isOptional = isOptional;
1415
- this._parent = null;
1416
- this._children = children;
1417
- this._firstIndex = -1;
1418
- this._nodes = [];
1419
- }
1420
1442
  get type() {
1421
1443
  return this._type;
1422
1444
  }
@@ -1435,6 +1457,20 @@
1435
1457
  get isOptional() {
1436
1458
  return this._isOptional;
1437
1459
  }
1460
+ constructor(name, sequence, isOptional = false) {
1461
+ if (sequence.length === 0) {
1462
+ throw new Error("Need at least one pattern with an 'and' pattern.");
1463
+ }
1464
+ const children = clonePatterns(sequence);
1465
+ this._assignChildrenToParent(children);
1466
+ this._type = "and";
1467
+ this._name = name;
1468
+ this._isOptional = isOptional;
1469
+ this._parent = null;
1470
+ this._children = children;
1471
+ this._firstIndex = -1;
1472
+ this._nodes = [];
1473
+ }
1438
1474
  _assignChildrenToParent(children) {
1439
1475
  for (const child of children) {
1440
1476
  child.parent = this;
@@ -1547,7 +1583,6 @@
1547
1583
  createNode(cursor) {
1548
1584
  const children = filterOutNull(this._nodes);
1549
1585
  const lastIndex = children[children.length - 1].lastIndex;
1550
- cursor.getChars(this._firstIndex, lastIndex);
1551
1586
  cursor.moveTo(lastIndex);
1552
1587
  return new Node("and", this._name, this._firstIndex, lastIndex, children);
1553
1588
  }
@@ -1589,9 +1624,6 @@
1589
1624
  let index = -1;
1590
1625
  for (let i = 0; i < this._children.length; i++) {
1591
1626
  if (this._children[i] === childReference) {
1592
- if (i + 1 < this._children.length) {
1593
- this._children[i + 1];
1594
- }
1595
1627
  nextSiblingIndex = i + 1;
1596
1628
  index = i;
1597
1629
  break;
@@ -1633,11 +1665,11 @@
1633
1665
  }
1634
1666
  }
1635
1667
 
1636
- const name = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
1668
+ const name$1 = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
1637
1669
 
1638
1670
  const optionalNot = new Literal("not", "!", true);
1639
1671
  const optionalIsOptional$1 = new Literal("is-optional", "?", true);
1640
- const patternName$1 = name.clone("pattern-name");
1672
+ const patternName$1 = name$1.clone("pattern-name");
1641
1673
  const pattern$1 = new And("pattern", [
1642
1674
  optionalNot,
1643
1675
  patternName$1,
@@ -1650,44 +1682,44 @@
1650
1682
 
1651
1683
  const divider = new Regex("or-divider", "\\s*[|]\\s*");
1652
1684
  divider.setTokens([" | "]);
1653
- const orLiteral = new Repeat("or-literal", name.clone("pattern-name"), { divider, min: 2 });
1685
+ const orLiteral = new Repeat("or-literal", name$1.clone("pattern-name"), { divider, min: 2 });
1654
1686
 
1655
1687
  const regexLiteral = new Regex("regex-literal", "/(\\\\/|[^/\\n\\r])*/");
1656
1688
 
1657
- const spaces = new Regex("spaces", "[ \\t]+");
1658
- spaces.setTokens([" "]);
1689
+ const spaces$1 = new Regex("spaces", "[ \\t]+");
1690
+ spaces$1.setTokens([" "]);
1659
1691
 
1660
1692
  const optionalIsOptional = new Literal("is-optional", "?", true);
1661
- const patternName = name.clone("pattern-name");
1693
+ const patternName = name$1.clone("pattern-name");
1662
1694
  const pattern = new And("pattern", [
1663
1695
  patternName,
1664
1696
  optionalIsOptional,
1665
1697
  ]);
1666
- const optionalSpaces$1 = spaces.clone("optional-spaces", true);
1667
- const dividerPattern = name.clone("divider-pattern");
1668
- const openBracket = new Literal("open-bracket", "{");
1669
- const closeBracket = new Literal("close-bracket", "}");
1698
+ const optionalSpaces$2 = spaces$1.clone("optional-spaces", true);
1699
+ const dividerPattern = name$1.clone("divider-pattern");
1700
+ const openBracket$1 = new Literal("open-bracket", "{");
1701
+ const closeBracket$1 = new Literal("close-bracket", "}");
1670
1702
  const comma = new Literal("comma", ",");
1671
1703
  const integer = new Regex("integer", "([1-9][0-9]*)|0");
1672
1704
  integer.setTokens(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
1673
1705
  const optionalInteger = integer.clone("integer", true);
1674
1706
  const bounds = new And("bounds", [
1675
- openBracket,
1676
- optionalSpaces$1,
1707
+ openBracket$1,
1708
+ optionalSpaces$2,
1677
1709
  optionalInteger.clone("min"),
1678
- optionalSpaces$1,
1710
+ optionalSpaces$2,
1679
1711
  comma,
1680
- optionalSpaces$1,
1712
+ optionalSpaces$2,
1681
1713
  optionalInteger.clone("max"),
1682
- optionalSpaces$1,
1683
- closeBracket
1714
+ optionalSpaces$2,
1715
+ closeBracket$1
1684
1716
  ]);
1685
1717
  const exactCount = new And("exact-count", [
1686
- openBracket,
1687
- optionalSpaces$1,
1718
+ openBracket$1,
1719
+ optionalSpaces$2,
1688
1720
  integer,
1689
- optionalSpaces$1,
1690
- closeBracket,
1721
+ optionalSpaces$2,
1722
+ closeBracket$1,
1691
1723
  ]);
1692
1724
  const quantifierShorthand = new Regex("quantifier-shorthand", "\\*|\\+");
1693
1725
  quantifierShorthand.setTokens(["*", "+"]);
@@ -1704,19 +1736,19 @@
1704
1736
  dividerComma.setTokens([", "]);
1705
1737
  const repeatLiteral = new And("repeat-literal", [
1706
1738
  openParen,
1707
- optionalSpaces$1,
1739
+ optionalSpaces$2,
1708
1740
  pattern,
1709
1741
  optional,
1710
1742
  new And("optional-divider-section", [dividerComma, dividerPattern], true),
1711
- optionalSpaces$1,
1743
+ optionalSpaces$2,
1712
1744
  closeParen,
1713
- new And("quantifier-section", [optionalSpaces$1, quantifier]),
1714
- new And("optional-trim-divider-section", [spaces, trimDivider], true)
1745
+ new And("quantifier-section", [optionalSpaces$2, quantifier]),
1746
+ new And("optional-trim-divider-section", [spaces$1, trimDivider], true)
1715
1747
  ]);
1716
1748
 
1717
1749
  const literal = new Regex("literal", "\"(?:\\\\[\"\\\\]|[^\n\"\\\\])*\"");
1718
1750
 
1719
- const optionalSpaces = spaces.clone("optional-spaces", true);
1751
+ const optionalSpaces$1 = spaces$1.clone("optional-spaces", true);
1720
1752
  const assignOperator = new Literal("assign-operator", "=");
1721
1753
  const optionalComment = comment.clone("inline-comment", true);
1722
1754
  const statements = new Or("statements", [
@@ -1725,39 +1757,57 @@
1725
1757
  orLiteral,
1726
1758
  andLiteral,
1727
1759
  repeatLiteral,
1728
- name.clone("alias-literal"),
1760
+ name$1.clone("alias-literal"),
1729
1761
  ]);
1730
1762
  const statement = new And("statement", [
1731
- optionalSpaces,
1732
- name,
1733
- optionalSpaces,
1763
+ optionalSpaces$1,
1764
+ name$1,
1765
+ optionalSpaces$1,
1734
1766
  assignOperator,
1735
- optionalSpaces,
1767
+ optionalSpaces$1,
1736
1768
  statements,
1737
- optionalSpaces,
1769
+ optionalSpaces$1,
1738
1770
  optionalComment,
1771
+ optionalSpaces$1,
1772
+ ]);
1773
+
1774
+ const spaces = new Regex("spaces", "\\s+", true);
1775
+ const importNameDivider = new Regex("import-name-divider", "(\\s+)?,(\\s+)?");
1776
+ const importKeyword = new Literal("import", "import");
1777
+ const fromKeyword = new Literal("from", "from");
1778
+ const openBracket = new Literal("open-bracket", "{");
1779
+ const closeBracket = new Literal("close-bracket", "}");
1780
+ const name = new Regex("import-name", "[^}\\s,]+");
1781
+ const importedNames = new Repeat("imported-names", name, { divider: importNameDivider });
1782
+ const optionalSpaces = spaces.clone("optional-spaces", true);
1783
+ const importStatement = new And("import-statement", [
1784
+ importKeyword,
1785
+ optionalSpaces,
1786
+ openBracket,
1787
+ optionalSpaces,
1788
+ importedNames,
1739
1789
  optionalSpaces,
1790
+ closeBracket,
1791
+ optionalSpaces,
1792
+ fromKeyword,
1793
+ spaces,
1794
+ literal.clone("url"),
1740
1795
  ]);
1741
1796
 
1742
- const whitespace = new Regex("whitespace", "[ \\t]+");
1797
+ const whitespace = new Regex("whitespace", "[ \\t]+((\\r?\\n)+)?");
1743
1798
  const newLine = new Regex("new-line", "(\\r?\\n)+");
1744
1799
  whitespace.setTokens([" "]);
1745
1800
  newLine.setTokens(["\n"]);
1746
1801
  const line = new Or("line", [
1802
+ newLine,
1803
+ whitespace,
1747
1804
  comment,
1748
- statement,
1749
- whitespace
1750
- ], true);
1751
- const grammar = new Repeat("grammar", line, { divider: newLine });
1805
+ importStatement,
1806
+ statement
1807
+ ]);
1808
+ const grammar = new Repeat("grammer", line);
1752
1809
 
1753
1810
  class Not {
1754
- constructor(name, pattern) {
1755
- this._type = "not";
1756
- this._name = name;
1757
- this._parent = null;
1758
- this._children = [pattern.clone(pattern.name, false)];
1759
- this._children[0].parent = this;
1760
- }
1761
1811
  get type() {
1762
1812
  return this._type;
1763
1813
  }
@@ -1776,6 +1826,13 @@
1776
1826
  get isOptional() {
1777
1827
  return false;
1778
1828
  }
1829
+ constructor(name, pattern) {
1830
+ this._type = "not";
1831
+ this._name = name;
1832
+ this._parent = null;
1833
+ this._children = [pattern.clone(pattern.name, false)];
1834
+ this._children[0].parent = this;
1835
+ }
1779
1836
  test(text) {
1780
1837
  const cursor = new Cursor(text);
1781
1838
  this.parse(cursor);
@@ -2045,10 +2102,16 @@
2045
2102
  class ParseContext {
2046
2103
  constructor() {
2047
2104
  this.patternsByName = new Map();
2105
+ this.importedPatternsByName = new Map();
2048
2106
  }
2049
2107
  }
2108
+ function defaultImportResolver(_path, _basePath) {
2109
+ throw new Error("No import resolver supplied.");
2110
+ }
2050
2111
  class Grammar {
2051
- constructor() {
2112
+ constructor(options = {}) {
2113
+ this._meta = options.meta == null ? null : options.meta;
2114
+ this._resolveImport = options.resolveImport == null ? defaultImportResolver : options.resolveImport;
2052
2115
  this._parseContext = new ParseContext();
2053
2116
  this._autoComplete = new AutoComplete(grammar, {
2054
2117
  greedyPatternNames: ["spaces", "optional-spaces", "whitespace", "new-line"],
@@ -2060,9 +2123,31 @@
2060
2123
  }
2061
2124
  });
2062
2125
  }
2126
+ import(path) {
2127
+ return __awaiter(this, void 0, void 0, function* () {
2128
+ const grammarFile = yield this._resolveImport(path, null);
2129
+ const grammar = new Grammar({ resolveImport: this._resolveImport, meta: { originPath: grammarFile.path } });
2130
+ return grammar.parse(grammarFile.expression);
2131
+ });
2132
+ }
2063
2133
  parse(expression) {
2134
+ return __awaiter(this, void 0, void 0, function* () {
2135
+ this._parseContext = new ParseContext();
2136
+ const ast = this._tryToParse(expression);
2137
+ yield this._resolveImports(ast);
2138
+ this._buildPatterns(ast);
2139
+ this._cleanAst(ast);
2140
+ return this._parseContext.patternsByName;
2141
+ });
2142
+ }
2143
+ parseString(expression) {
2064
2144
  this._parseContext = new ParseContext();
2065
- this._tryToParse(expression);
2145
+ const ast = this._tryToParse(expression);
2146
+ if (this._hasImports(ast)) {
2147
+ throw new Error("Cannot use imports on parseString, use parse instead.");
2148
+ }
2149
+ this._buildPatterns(ast);
2150
+ this._cleanAst(ast);
2066
2151
  return this._parseContext.patternsByName;
2067
2152
  }
2068
2153
  _tryToParse(expression) {
@@ -2079,8 +2164,14 @@
2079
2164
  throw new Error(message);
2080
2165
  }
2081
2166
  // If it is complete it will always have a node. So we have to cast it.
2082
- this._cleanAst(ast);
2083
- this._buildPatterns(ast);
2167
+ return ast;
2168
+ }
2169
+ _hasImports(ast) {
2170
+ const importBlock = ast.find(n => n.name === "import-block");
2171
+ if (importBlock == null) {
2172
+ return false;
2173
+ }
2174
+ return importBlock && importBlock.children.length > 0;
2084
2175
  }
2085
2176
  _cleanAst(ast) {
2086
2177
  ast.findAll(n => n.name === "spaces" ||
@@ -2121,6 +2212,36 @@
2121
2212
  }
2122
2213
  });
2123
2214
  }
2215
+ _resolveImports(ast) {
2216
+ var _a;
2217
+ return __awaiter(this, void 0, void 0, function* () {
2218
+ const parseContext = this._parseContext;
2219
+ const importStatements = ast.findAll(n => n.name === "import-statement");
2220
+ for (const importStatement of importStatements) {
2221
+ const urlNode = importStatement.find(n => n.name === "url");
2222
+ const url = urlNode.value.slice(1, -1);
2223
+ const grammarFile = yield this._resolveImport(url, ((_a = this._meta) === null || _a === void 0 ? void 0 : _a.originPath) || null);
2224
+ const grammar = new Grammar({ resolveImport: this._resolveImport, meta: { originPath: grammarFile.path } });
2225
+ try {
2226
+ const patterns = yield grammar.parse(grammarFile.expression);
2227
+ const importNames = importStatement.findAll(n => n.name === "import-name").map(n => n.value);
2228
+ importNames.forEach((importName) => {
2229
+ if (parseContext.importedPatternsByName.has(importName)) {
2230
+ throw new Error(`'${importName}' was already used within another import.`);
2231
+ }
2232
+ const pattern = patterns.get(importName);
2233
+ if (pattern == null) {
2234
+ throw new Error(`Couldn't find pattern with name: ${importName}, from import: ${url}.`);
2235
+ }
2236
+ parseContext.importedPatternsByName.set(importName, pattern);
2237
+ });
2238
+ }
2239
+ catch (e) {
2240
+ throw new Error(`Failed loading expression from: "${url}". Error details: "${e.message}"`);
2241
+ }
2242
+ }
2243
+ });
2244
+ }
2124
2245
  _buildLiteral(statementNode) {
2125
2246
  const nameNode = statementNode.find(n => n.name === "name");
2126
2247
  const literalNode = statementNode.find(n => n.name === "literal");
@@ -2140,14 +2261,17 @@
2140
2261
  _buildOr(statementNode) {
2141
2262
  const nameNode = statementNode.find(n => n.name === "name");
2142
2263
  const orNode = statementNode.find(n => n.name === "or-literal");
2143
- const patternNodes = orNode.children.filter(n => n.name == "pattern-name");
2264
+ const patternNodes = orNode.children.filter(n => n.name === "pattern-name");
2144
2265
  const name = nameNode.value;
2145
2266
  const patterns = patternNodes.map(n => this._getPattern(n.value));
2146
- const or = new Or(name, patterns);
2267
+ const or = new Or(name, patterns, false, true);
2147
2268
  this._parseContext.patternsByName.set(name, or);
2148
2269
  }
2149
2270
  _getPattern(name) {
2150
- const pattern = this._parseContext.patternsByName.get(name);
2271
+ let pattern = this._parseContext.patternsByName.get(name);
2272
+ if (pattern == null) {
2273
+ pattern = this._parseContext.importedPatternsByName.get(name);
2274
+ }
2151
2275
  if (pattern == null) {
2152
2276
  return new Reference(name);
2153
2277
  }
@@ -2156,7 +2280,7 @@
2156
2280
  _buildAnd(statementNode) {
2157
2281
  const nameNode = statementNode.find(n => n.name === "name");
2158
2282
  const andNode = statementNode.find(n => n.name === "and-literal");
2159
- const patternNodes = andNode.children.filter(n => n.name == "pattern");
2283
+ const patternNodes = andNode.children.filter(n => n.name === "pattern");
2160
2284
  const name = nameNode.value;
2161
2285
  const patterns = patternNodes.map(n => {
2162
2286
  const nameNode = n.find(n => n.name === "pattern-name");
@@ -2175,7 +2299,7 @@
2175
2299
  _buildRepeat(statementNode) {
2176
2300
  const nameNode = statementNode.find(n => n.name === "name");
2177
2301
  const repeatNode = statementNode.find(n => n.name === "repeat-literal");
2178
- const patternNode = repeatNode.find(n => n.name == "pattern");
2302
+ const patternNode = repeatNode.find(n => n.name === "pattern");
2179
2303
  const patternNameNode = patternNode.find(n => n.name === "pattern-name");
2180
2304
  const dividerNode = repeatNode.find(n => n.name === "divider-pattern");
2181
2305
  const bounds = repeatNode.find(n => n.name === "bounds");
@@ -2232,10 +2356,18 @@
2232
2356
  const alias = pattern.clone(name);
2233
2357
  this._parseContext.patternsByName.set(name, alias);
2234
2358
  }
2235
- static parse(expression) {
2236
- const grammar = new Grammar();
2359
+ static parse(expression, options) {
2360
+ const grammar = new Grammar(options);
2237
2361
  return grammar.parse(expression);
2238
2362
  }
2363
+ static import(path, options) {
2364
+ const grammar = new Grammar(options);
2365
+ return grammar.import(path);
2366
+ }
2367
+ static parseString(expression) {
2368
+ const grammar = new Grammar();
2369
+ return grammar.parseString(expression);
2370
+ }
2239
2371
  }
2240
2372
 
2241
2373
  exports.And = And;
@@ -2254,5 +2386,5 @@
2254
2386
 
2255
2387
  Object.defineProperty(exports, '__esModule', { value: true });
2256
2388
 
2257
- })));
2389
+ }));
2258
2390
  //# sourceMappingURL=index.browser.js.map