clarity-pattern-parser 9.0.0 → 9.1.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.
@@ -477,7 +477,7 @@
477
477
  }
478
478
  }
479
479
 
480
- let idIndex$8 = 0;
480
+ let idIndex$9 = 0;
481
481
  class Literal {
482
482
  get id() {
483
483
  return this._id;
@@ -488,6 +488,9 @@
488
488
  get name() {
489
489
  return this._name;
490
490
  }
491
+ get value() {
492
+ return this._text;
493
+ }
491
494
  get parent() {
492
495
  return this._parent;
493
496
  }
@@ -497,19 +500,15 @@
497
500
  get children() {
498
501
  return [];
499
502
  }
500
- get isOptional() {
501
- return this._isOptional;
502
- }
503
- constructor(name, value, isOptional = false) {
503
+ constructor(name, value) {
504
504
  if (value.length === 0) {
505
505
  throw new Error("Value Cannot be empty.");
506
506
  }
507
- this._id = `literal-${idIndex$8++}`;
507
+ this._id = `literal-${idIndex$9++}`;
508
508
  this._type = "literal";
509
509
  this._name = name;
510
510
  this._text = value;
511
511
  this._runes = Array.from(value);
512
- this._isOptional = isOptional;
513
512
  this._parent = null;
514
513
  this._firstIndex = 0;
515
514
  this._lastIndex = 0;
@@ -540,13 +539,7 @@
540
539
  cursor.endParse();
541
540
  return node;
542
541
  }
543
- if (!this._isOptional) {
544
- cursor.recordErrorAt(this._firstIndex, this._endIndex, this);
545
- cursor.endParse();
546
- return null;
547
- }
548
- cursor.resolveError();
549
- cursor.moveTo(this._firstIndex);
542
+ cursor.recordErrorAt(this._firstIndex, this._endIndex, this);
550
543
  cursor.endParse();
551
544
  return null;
552
545
  }
@@ -576,8 +569,8 @@
576
569
  _createNode() {
577
570
  return new Node("literal", this._name, this._firstIndex, this._lastIndex, undefined, this._text);
578
571
  }
579
- clone(name = this._name, isOptional = this._isOptional) {
580
- const clone = new Literal(name, this._text, isOptional);
572
+ clone(name = this._name) {
573
+ const clone = new Literal(name, this._text);
581
574
  clone._id = this._id;
582
575
  return clone;
583
576
  }
@@ -613,7 +606,7 @@
613
606
  }
614
607
  }
615
608
 
616
- let idIndex$7 = 0;
609
+ let idIndex$8 = 0;
617
610
  class Regex {
618
611
  get id() {
619
612
  return this._id;
@@ -624,6 +617,9 @@
624
617
  get name() {
625
618
  return this._name;
626
619
  }
620
+ get value() {
621
+ return this._originalRegexString;
622
+ }
627
623
  get parent() {
628
624
  return this._parent;
629
625
  }
@@ -633,19 +629,15 @@
633
629
  get children() {
634
630
  return [];
635
631
  }
636
- get isOptional() {
637
- return this._isOptional;
638
- }
639
- constructor(name, regex, isOptional = false) {
632
+ constructor(name, regex) {
640
633
  this._node = null;
641
634
  this._cursor = null;
642
635
  this._firstIndex = -1;
643
636
  this._substring = "";
644
637
  this._tokens = [];
645
- this._id = `regex-${idIndex$7++}`;
638
+ this._id = `regex-${idIndex$8++}`;
646
639
  this._type = "regex";
647
640
  this._name = name;
648
- this._isOptional = isOptional;
649
641
  this._parent = null;
650
642
  this._originalRegexString = regex;
651
643
  this._regex = new RegExp(`^${regex}`, "g");
@@ -707,13 +699,11 @@
707
699
  cursor.recordMatch(this, this._node);
708
700
  }
709
701
  processError(cursor) {
710
- if (!this._isOptional) {
711
- cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
712
- }
702
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
713
703
  this._node = null;
714
704
  }
715
- clone(name = this._name, isOptional = this._isOptional) {
716
- const clone = new Regex(name, this._originalRegexString, isOptional);
705
+ clone(name = this._name) {
706
+ const clone = new Regex(name, this._originalRegexString);
717
707
  clone._tokens = this._tokens.slice();
718
708
  clone._id = this._id;
719
709
  return clone;
@@ -775,7 +765,7 @@
775
765
  }
776
766
  }
777
767
 
778
- let idIndex$6 = 0;
768
+ let idIndex$7 = 0;
779
769
  class Reference {
780
770
  get id() {
781
771
  return this._id;
@@ -795,15 +785,11 @@
795
785
  get children() {
796
786
  return this._children;
797
787
  }
798
- get isOptional() {
799
- return this._isOptional;
800
- }
801
- constructor(name, isOptional = false) {
802
- this._id = `reference-${idIndex$6++}`;
788
+ constructor(name) {
789
+ this._id = `reference-${idIndex$7++}`;
803
790
  this._type = "reference";
804
791
  this._name = name;
805
792
  this._parent = null;
806
- this._isOptional = isOptional;
807
793
  this._pattern = null;
808
794
  this._children = [];
809
795
  }
@@ -830,7 +816,7 @@
830
816
  if (pattern === null) {
831
817
  throw new Error(`Couldn't find '${this._name}' pattern within tree.`);
832
818
  }
833
- const clonedPattern = pattern.clone(this._name, this._isOptional);
819
+ const clonedPattern = pattern.clone();
834
820
  clonedPattern.parent = this;
835
821
  this._pattern = clonedPattern;
836
822
  this._children = [this._pattern];
@@ -889,8 +875,8 @@
889
875
  find(_predicate) {
890
876
  return null;
891
877
  }
892
- clone(name = this._name, isOptional = this._isOptional) {
893
- const clone = new Reference(name, isOptional);
878
+ clone(name = this._name) {
879
+ const clone = new Reference(name);
894
880
  clone._id = this._id;
895
881
  return clone;
896
882
  }
@@ -899,12 +885,12 @@
899
885
  }
900
886
  }
901
887
 
902
- function clonePatterns(patterns, isOptional) {
903
- return patterns.map(p => p.clone(p.name, isOptional));
888
+ function clonePatterns(patterns) {
889
+ return patterns.map(p => p.clone());
904
890
  }
905
891
 
906
- let idIndex$5 = 0;
907
- class Or {
892
+ let idIndex$6 = 0;
893
+ class Options {
908
894
  get id() {
909
895
  return this._id;
910
896
  }
@@ -923,21 +909,17 @@
923
909
  get children() {
924
910
  return this._children;
925
911
  }
926
- get isOptional() {
927
- return this._isOptional;
928
- }
929
- constructor(name, options, isOptional = false, isGreedy = false) {
912
+ constructor(name, options, isGreedy = false) {
930
913
  if (options.length === 0) {
931
914
  throw new Error("Need at least one pattern with an 'or' pattern.");
932
915
  }
933
- const children = clonePatterns(options, false);
916
+ const children = clonePatterns(options);
934
917
  this._assignChildrenToParent(children);
935
- this._id = `or-${idIndex$5++}`;
918
+ this._id = `or-${idIndex$6++}`;
936
919
  this._type = "or";
937
920
  this._name = name;
938
921
  this._parent = null;
939
922
  this._children = children;
940
- this._isOptional = isOptional;
941
923
  this._firstIndex = 0;
942
924
  this._isGreedy = isGreedy;
943
925
  }
@@ -970,13 +952,7 @@
970
952
  cursor.endParse();
971
953
  return node;
972
954
  }
973
- if (!this._isOptional) {
974
- cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
975
- cursor.endParse();
976
- return null;
977
- }
978
- cursor.resolveError();
979
- cursor.moveTo(this._firstIndex);
955
+ cursor.recordErrorAt(this._firstIndex, this._firstIndex, this);
980
956
  cursor.endParse();
981
957
  return null;
982
958
  }
@@ -988,7 +964,7 @@
988
964
  if (this._isGreedy) {
989
965
  results.push(result);
990
966
  }
991
- if (!cursor.hasError && !this._isGreedy) {
967
+ if (result != null && !this._isGreedy) {
992
968
  return result;
993
969
  }
994
970
  cursor.resolveError();
@@ -1038,8 +1014,8 @@
1038
1014
  find(predicate) {
1039
1015
  return findPattern(this, predicate);
1040
1016
  }
1041
- clone(name = this._name, isOptional = this._isOptional) {
1042
- const or = new Or(name, this._children, isOptional, this._isGreedy);
1017
+ clone(name = this._name) {
1018
+ const or = new Options(name, this._children, this._isGreedy);
1043
1019
  or._id = this._id;
1044
1020
  return or;
1045
1021
  }
@@ -1048,7 +1024,7 @@
1048
1024
  }
1049
1025
  }
1050
1026
 
1051
- let idIndex$4 = 0;
1027
+ let idIndex$5 = 0;
1052
1028
  class FiniteRepeat {
1053
1029
  get id() {
1054
1030
  return this._id;
@@ -1068,29 +1044,30 @@
1068
1044
  get children() {
1069
1045
  return this._children;
1070
1046
  }
1071
- get isOptional() {
1072
- return this._min === 0;
1073
- }
1074
1047
  get min() {
1075
1048
  return this._min;
1076
1049
  }
1077
1050
  get max() {
1078
1051
  return this._max;
1079
1052
  }
1080
- constructor(name, pattern, repeatAmount, options = {}) {
1081
- this._id = `finite-repeat-${idIndex$4++}`;
1053
+ constructor(name, pattern, options = {}) {
1054
+ this._id = `finite-repeat-${idIndex$5++}`;
1082
1055
  this._type = "finite-repeat";
1083
1056
  this._name = name;
1084
1057
  this._parent = null;
1085
1058
  this._children = [];
1086
1059
  this._hasDivider = options.divider != null;
1087
- this._min = options.min != null ? options.min : 1;
1088
- this._max = repeatAmount;
1060
+ this._min = options.min != null ? Math.max(options.min, 1) : 1;
1061
+ this._max = Math.max(this.min, options.max || this.min);
1089
1062
  this._trimDivider = options.trimDivider == null ? false : options.trimDivider;
1090
- for (let i = 0; i < repeatAmount; i++) {
1091
- this._children.push(pattern.clone(pattern.name));
1092
- if (options.divider != null && (i < repeatAmount - 1 || !this._trimDivider)) {
1093
- this._children.push(options.divider.clone(options.divider.name, false));
1063
+ for (let i = 0; i < this._max; i++) {
1064
+ const child = pattern.clone();
1065
+ child.parent = this;
1066
+ this._children.push(child);
1067
+ if (options.divider != null && (i < this._max - 1 || !this._trimDivider)) {
1068
+ const divider = options.divider.clone();
1069
+ divider.parent = this;
1070
+ this._children.push(divider);
1094
1071
  }
1095
1072
  }
1096
1073
  }
@@ -1102,15 +1079,18 @@
1102
1079
  let matchCount = 0;
1103
1080
  for (let i = 0; i < this._children.length; i++) {
1104
1081
  const childPattern = this._children[i];
1082
+ const runningIndex = cursor.index;
1105
1083
  const node = childPattern.parse(cursor);
1084
+ if (cursor.hasError) {
1085
+ break;
1086
+ }
1106
1087
  if (i % modulo === 0 && !cursor.hasError) {
1107
1088
  matchCount++;
1108
1089
  }
1109
- if (cursor.hasError) {
1110
- cursor.resolveError();
1111
- break;
1090
+ if (node == null) {
1091
+ cursor.moveTo(runningIndex);
1112
1092
  }
1113
- if (node != null) {
1093
+ else {
1114
1094
  nodes.push(node);
1115
1095
  if (cursor.hasNext()) {
1116
1096
  cursor.next();
@@ -1121,7 +1101,8 @@
1121
1101
  }
1122
1102
  }
1123
1103
  if (this._trimDivider && this._hasDivider) {
1124
- if (cursor.leafMatch.pattern === this.children[1]) {
1104
+ const isDividerLastMatch = cursor.leafMatch.pattern === this.children[1];
1105
+ if (isDividerLastMatch) {
1125
1106
  const node = nodes.pop();
1126
1107
  cursor.moveTo(node.firstIndex);
1127
1108
  }
@@ -1133,14 +1114,14 @@
1133
1114
  cursor.endParse();
1134
1115
  return null;
1135
1116
  }
1136
- else if (nodes.length === 0) {
1137
- cursor.resolveError();
1117
+ if (nodes.length === 0 && !cursor.hasError) {
1138
1118
  cursor.moveTo(startIndex);
1139
1119
  cursor.endParse();
1140
1120
  return null;
1141
1121
  }
1142
1122
  const firstIndex = nodes[0].firstIndex;
1143
1123
  const lastIndex = nodes[nodes.length - 1].lastIndex;
1124
+ cursor.resolveError();
1144
1125
  cursor.moveTo(lastIndex);
1145
1126
  cursor.endParse();
1146
1127
  return new Node(this._type, this.name, firstIndex, lastIndex, nodes);
@@ -1159,19 +1140,13 @@
1159
1140
  cursor
1160
1141
  };
1161
1142
  }
1162
- clone(name = this._name, isOptional) {
1143
+ clone(name = this._name) {
1163
1144
  let min = this._min;
1164
- if (isOptional != null) {
1165
- if (isOptional) {
1166
- min = 0;
1167
- }
1168
- else {
1169
- min = Math.max(this._min, 1);
1170
- }
1171
- }
1172
- const clone = new FiniteRepeat(name, this._children[0], this._max, {
1145
+ let max = this._max;
1146
+ const clone = new FiniteRepeat(name, this._children[0], {
1173
1147
  divider: this._hasDivider ? this._children[1] : undefined,
1174
1148
  min,
1149
+ max,
1175
1150
  trimDivider: this._trimDivider
1176
1151
  });
1177
1152
  clone._id = this._id;
@@ -1228,7 +1203,7 @@
1228
1203
  }
1229
1204
  }
1230
1205
 
1231
- let idIndex$3 = 0;
1206
+ let idIndex$4 = 0;
1232
1207
  class InfiniteRepeat {
1233
1208
  get id() {
1234
1209
  return this._id;
@@ -1248,24 +1223,21 @@
1248
1223
  get children() {
1249
1224
  return this._children;
1250
1225
  }
1251
- get isOptional() {
1252
- return this._min === 0;
1253
- }
1254
1226
  get min() {
1255
1227
  return this._min;
1256
1228
  }
1257
1229
  constructor(name, pattern, options = {}) {
1258
- const min = options.min != null ? options.min : 1;
1230
+ const min = options.min != null ? Math.max(options.min, 1) : 1;
1259
1231
  const divider = options.divider;
1260
1232
  let children;
1261
1233
  if (divider != null) {
1262
- children = [pattern.clone(pattern.name, false), divider.clone(divider.name, false)];
1234
+ children = [pattern.clone(), divider.clone()];
1263
1235
  }
1264
1236
  else {
1265
- children = [pattern.clone(pattern.name, false)];
1237
+ children = [pattern.clone()];
1266
1238
  }
1267
1239
  this._assignChildrenToParent(children);
1268
- this._id = `infinite-repeat-${idIndex$3++}`;
1240
+ this._id = `infinite-repeat-${idIndex$4++}`;
1269
1241
  this._type = "infinite-repeat";
1270
1242
  this._name = name;
1271
1243
  this._min = min;
@@ -1330,8 +1302,12 @@
1330
1302
  let passed = false;
1331
1303
  while (true) {
1332
1304
  const runningCursorIndex = cursor.index;
1333
- const repeatedNode = this._pattern.parse(cursor);
1334
- if (cursor.hasError) {
1305
+ const repeatNode = this._pattern.parse(cursor);
1306
+ const hasError = cursor.hasError;
1307
+ const hasNoErrorAndNoResult = !cursor.hasError && repeatNode == null;
1308
+ const hasDivider = this._divider != null;
1309
+ const hasNoDivider = !hasDivider;
1310
+ if (hasError) {
1335
1311
  const lastValidNode = this._getLastValidNode();
1336
1312
  if (lastValidNode != null) {
1337
1313
  passed = true;
@@ -1344,8 +1320,12 @@
1344
1320
  break;
1345
1321
  }
1346
1322
  else {
1347
- if (repeatedNode != null) {
1348
- this._nodes.push(repeatedNode);
1323
+ if (hasNoErrorAndNoResult && hasNoDivider) {
1324
+ // If we didn't match and didn't error we need to get out. Nothing different will happen.
1325
+ break;
1326
+ }
1327
+ if (repeatNode != null) {
1328
+ this._nodes.push(repeatNode);
1349
1329
  if (!cursor.hasNext()) {
1350
1330
  passed = true;
1351
1331
  break;
@@ -1353,18 +1333,29 @@
1353
1333
  cursor.next();
1354
1334
  }
1355
1335
  if (this._divider != null) {
1336
+ const dividerStartIndex = cursor.index;
1356
1337
  const dividerNode = this._divider.parse(cursor);
1357
1338
  if (cursor.hasError) {
1358
1339
  passed = true;
1359
1340
  break;
1360
1341
  }
1361
- else if (dividerNode != null) {
1362
- this._nodes.push(dividerNode);
1363
- if (!cursor.hasNext()) {
1364
- passed = true;
1365
- break;
1342
+ else {
1343
+ if (dividerNode == null) {
1344
+ cursor.moveTo(dividerStartIndex);
1345
+ if (dividerNode == null && repeatNode == null) {
1346
+ // If neither the repeat pattern or divider pattern matched get out.
1347
+ passed = true;
1348
+ break;
1349
+ }
1350
+ }
1351
+ else {
1352
+ this._nodes.push(dividerNode);
1353
+ if (!cursor.hasNext()) {
1354
+ passed = true;
1355
+ break;
1356
+ }
1357
+ cursor.next();
1366
1358
  }
1367
- cursor.next();
1368
1359
  }
1369
1360
  }
1370
1361
  }
@@ -1388,10 +1379,10 @@
1388
1379
  const dividerNode = this._nodes.pop();
1389
1380
  cursor.moveTo(dividerNode.firstIndex);
1390
1381
  }
1391
- // if (this._nodes.length === 0) {
1392
- // cursor.moveTo(this._firstIndex);
1393
- // return null;
1394
- // }
1382
+ if (this._nodes.length === 0) {
1383
+ cursor.moveTo(this._firstIndex);
1384
+ return null;
1385
+ }
1395
1386
  const lastIndex = this._nodes[this._nodes.length - 1].lastIndex;
1396
1387
  cursor.moveTo(lastIndex);
1397
1388
  return new Node(this._type, this._name, this._firstIndex, lastIndex, this._nodes);
@@ -1460,16 +1451,8 @@
1460
1451
  find(predicate) {
1461
1452
  return findPattern(this, predicate);
1462
1453
  }
1463
- clone(name = this._name, isOptional) {
1454
+ clone(name = this._name) {
1464
1455
  let min = this._min;
1465
- if (isOptional != null) {
1466
- if (isOptional) {
1467
- min = 0;
1468
- }
1469
- else {
1470
- min = Math.max(this._min, 1);
1471
- }
1472
- }
1473
1456
  const clone = new InfiniteRepeat(name, this._pattern, {
1474
1457
  divider: this._divider == null ? undefined : this._divider,
1475
1458
  min: min,
@@ -1483,7 +1466,7 @@
1483
1466
  }
1484
1467
  }
1485
1468
 
1486
- let idIndex$2 = 0;
1469
+ let idIndex$3 = 0;
1487
1470
  class Repeat {
1488
1471
  get id() {
1489
1472
  return this._id;
@@ -1503,16 +1486,13 @@
1503
1486
  get children() {
1504
1487
  return this._children;
1505
1488
  }
1506
- get isOptional() {
1507
- return this._repeatPattern.isOptional;
1508
- }
1509
1489
  constructor(name, pattern, options = {}) {
1510
- this._id = `repeat-${idIndex$2++}`;
1490
+ this._id = `repeat-${idIndex$3++}`;
1511
1491
  this._pattern = pattern;
1512
1492
  this._parent = null;
1513
1493
  this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1514
1494
  if (this._options.max !== Infinity) {
1515
- this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
1495
+ this._repeatPattern = new FiniteRepeat(name, pattern, this._options);
1516
1496
  }
1517
1497
  else {
1518
1498
  this._repeatPattern = new InfiniteRepeat(name, pattern, this._options);
@@ -1529,16 +1509,8 @@
1529
1509
  test(text) {
1530
1510
  return this._repeatPattern.test(text);
1531
1511
  }
1532
- clone(name = this.name, isOptional) {
1512
+ clone(name = this.name) {
1533
1513
  let min = this._options.min;
1534
- if (isOptional != null) {
1535
- if (isOptional) {
1536
- min = 0;
1537
- }
1538
- else {
1539
- min = Math.max(this._options.min, 1);
1540
- }
1541
- }
1542
1514
  const clone = new Repeat(name, this._pattern, Object.assign(Object.assign({}, this._options), { min }));
1543
1515
  clone._id = this._id;
1544
1516
  return clone;
@@ -1582,6 +1554,7 @@
1582
1554
  }
1583
1555
 
1584
1556
  const comment = new Regex("comment", "#[^\r\n]+");
1557
+ comment.setTokens(["# "]);
1585
1558
 
1586
1559
  function filterOutNull(nodes) {
1587
1560
  const filteredNodes = [];
@@ -1593,8 +1566,8 @@
1593
1566
  return filteredNodes;
1594
1567
  }
1595
1568
 
1596
- let idIndex$1 = 0;
1597
- class And {
1569
+ let idIndex$2 = 0;
1570
+ class Sequence {
1598
1571
  get id() {
1599
1572
  return this._id;
1600
1573
  }
@@ -1613,19 +1586,15 @@
1613
1586
  get children() {
1614
1587
  return this._children;
1615
1588
  }
1616
- get isOptional() {
1617
- return this._isOptional;
1618
- }
1619
- constructor(name, sequence, isOptional = false) {
1589
+ constructor(name, sequence) {
1620
1590
  if (sequence.length === 0) {
1621
- throw new Error("Need at least one pattern with an 'and' pattern.");
1591
+ throw new Error("Need at least one pattern with a 'sequence' pattern.");
1622
1592
  }
1623
1593
  const children = clonePatterns(sequence);
1624
1594
  this._assignChildrenToParent(children);
1625
- this._id = `and-${idIndex$1++}`;
1626
- this._type = "and";
1595
+ this._id = `sequence-${idIndex$2++}`;
1596
+ this._type = "sequence";
1627
1597
  this._name = name;
1628
- this._isOptional = isOptional;
1629
1598
  this._parent = null;
1630
1599
  this._children = children;
1631
1600
  this._firstIndex = -1;
@@ -1663,9 +1632,6 @@
1663
1632
  cursor.endParse();
1664
1633
  return node;
1665
1634
  }
1666
- if (this._isOptional) {
1667
- cursor.resolveError();
1668
- }
1669
1635
  cursor.endParse();
1670
1636
  return null;
1671
1637
  }
@@ -1738,7 +1704,7 @@
1738
1704
  const length = this._children.length;
1739
1705
  for (let i = startOnIndex; i < length; i++) {
1740
1706
  const pattern = this._children[i];
1741
- if (!pattern.isOptional) {
1707
+ if (pattern.type !== "optional") {
1742
1708
  return false;
1743
1709
  }
1744
1710
  }
@@ -1748,13 +1714,13 @@
1748
1714
  const children = filterOutNull(this._nodes);
1749
1715
  const lastIndex = children[children.length - 1].lastIndex;
1750
1716
  cursor.moveTo(lastIndex);
1751
- return new Node("and", this._name, this._firstIndex, lastIndex, children);
1717
+ return new Node("sequence", this._name, this._firstIndex, lastIndex, children);
1752
1718
  }
1753
1719
  getTokens() {
1754
1720
  const tokens = [];
1755
1721
  for (const child of this._children) {
1756
1722
  tokens.push(...child.getTokens());
1757
- if (!child.isOptional) {
1723
+ if (child.type !== "optional") {
1758
1724
  break;
1759
1725
  }
1760
1726
  }
@@ -1774,9 +1740,9 @@
1774
1740
  }
1775
1741
  getPatterns() {
1776
1742
  const patterns = [];
1777
- for (const pattern of this._children) {
1778
- patterns.push(...pattern.getPatterns());
1779
- if (!pattern.isOptional) {
1743
+ for (const child of this._children) {
1744
+ patterns.push(...child.getPatterns());
1745
+ if (child.type !== "optional") {
1780
1746
  break;
1781
1747
  }
1782
1748
  }
@@ -1805,7 +1771,7 @@
1805
1771
  for (let i = nextSiblingIndex; i < this._children.length; i++) {
1806
1772
  const child = this._children[i];
1807
1773
  patterns.push(child);
1808
- if (!child.isOptional) {
1774
+ if (child.type !== "optional") {
1809
1775
  break;
1810
1776
  }
1811
1777
  // If we are on the last child and its options then ask for the next pattern from the parent.
@@ -1824,8 +1790,8 @@
1824
1790
  find(predicate) {
1825
1791
  return findPattern(this, predicate);
1826
1792
  }
1827
- clone(name = this._name, isOptional = this._isOptional) {
1828
- const clone = new And(name, this._children, isOptional);
1793
+ clone(name = this._name) {
1794
+ const clone = new Sequence(name, this._children);
1829
1795
  clone._id = this._id;
1830
1796
  return clone;
1831
1797
  }
@@ -1835,77 +1801,183 @@
1835
1801
  }
1836
1802
 
1837
1803
  const literal = new Regex("literal", '"(?:\\\\.|[^"\\\\])*"');
1804
+ literal.setTokens(["[LITERAL]"]);
1838
1805
 
1839
1806
  const tabs$1 = new Regex("tabs", "\\t+");
1807
+ tabs$1.setTokens(["\t"]);
1840
1808
  const spaces$1 = new Regex("spaces", "[ ]+");
1841
- const newLine$1 = new Regex("new-line", "(\\r?\\n)+");
1842
1809
  spaces$1.setTokens([" "]);
1843
- tabs$1.setTokens(["\t"]);
1810
+ const newLine$1 = new Regex("new-line", "(\\r?\\n)+");
1844
1811
  newLine$1.setTokens(["\n"]);
1845
- const lineSpaces$1 = new Repeat("line-spaces", new Or("line-space", [tabs$1, spaces$1]));
1846
- const allSpaces = new Regex("all-spaces", "\\s+", true);
1812
+ const lineSpaces$1 = new Repeat("line-spaces", new Options("line-space", [tabs$1, spaces$1]));
1813
+ const allSpaces = new Regex("all-spaces", "\\s+");
1814
+ allSpaces.setTokens([" "]);
1847
1815
 
1848
1816
  const name$1 = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
1849
1817
 
1850
1818
  const regexLiteral = new Regex("regex-literal", "/(\\\\/|[^/\\n\\r])*/");
1819
+ regexLiteral.setTokens(["[REGEX_EXPRESSION]"]);
1851
1820
 
1852
1821
  const patternName$3 = name$1.clone("pattern-name");
1853
- const anonymousLiterals = new Or("anonymous-literals", [
1822
+ const anonymousLiterals = new Options("anonymous-literals", [
1854
1823
  literal,
1855
1824
  regexLiteral,
1856
1825
  patternName$3,
1857
1826
  new Reference("repeat-literal"),
1858
1827
  ]);
1859
- const anonymousWrappedLiterals = new Or("anonymous-wrapped-literals", [
1860
- new Reference("or-literal"),
1861
- new Reference("and-literal"),
1828
+ const anonymousWrappedLiterals = new Options("anonymous-wrapped-literals", [
1829
+ new Reference("options-literal"),
1830
+ new Reference("sequence-literal"),
1862
1831
  new Reference("complex-anonymous-pattern")
1863
1832
  ]);
1864
1833
 
1834
+ let idIndex$1 = 0;
1835
+ class Optional {
1836
+ get id() {
1837
+ return this._id;
1838
+ }
1839
+ get type() {
1840
+ return this._type;
1841
+ }
1842
+ get name() {
1843
+ return this._name;
1844
+ }
1845
+ get parent() {
1846
+ return this._parent;
1847
+ }
1848
+ set parent(pattern) {
1849
+ this._parent = pattern;
1850
+ }
1851
+ get children() {
1852
+ return this._children;
1853
+ }
1854
+ constructor(name, pattern) {
1855
+ this._id = `optional-${idIndex$1++}`;
1856
+ this._type = "optional";
1857
+ this._name = name;
1858
+ this._parent = null;
1859
+ this._children = [pattern.clone()];
1860
+ this._children[0].parent = this;
1861
+ }
1862
+ test(text) {
1863
+ const cursor = new Cursor(text);
1864
+ this.parse(cursor);
1865
+ return !cursor.hasError;
1866
+ }
1867
+ exec(text, record = false) {
1868
+ const cursor = new Cursor(text);
1869
+ record && cursor.startRecording();
1870
+ const ast = this.parse(cursor);
1871
+ return {
1872
+ ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
1873
+ cursor
1874
+ };
1875
+ }
1876
+ parse(cursor) {
1877
+ cursor.startParseWith(this);
1878
+ const firstIndex = cursor.index;
1879
+ const node = this._children[0].parse(cursor);
1880
+ if (cursor.hasError) {
1881
+ cursor.resolveError();
1882
+ cursor.moveTo(firstIndex);
1883
+ cursor.endParse();
1884
+ return null;
1885
+ }
1886
+ else {
1887
+ cursor.endParse();
1888
+ return node;
1889
+ }
1890
+ }
1891
+ clone(name = this._name) {
1892
+ const optional = new Optional(name, this._children[0]);
1893
+ optional._id = this._id;
1894
+ return optional;
1895
+ }
1896
+ getTokens() {
1897
+ return this._children[0].getTokens();
1898
+ }
1899
+ getTokensAfter(_childReference) {
1900
+ const parent = this._parent;
1901
+ if (parent != null) {
1902
+ return parent.getTokensAfter(this);
1903
+ }
1904
+ return [];
1905
+ }
1906
+ getNextTokens() {
1907
+ if (this.parent == null) {
1908
+ return [];
1909
+ }
1910
+ return this.parent.getTokensAfter(this);
1911
+ }
1912
+ getPatterns() {
1913
+ return this._children[0].getPatterns();
1914
+ }
1915
+ getPatternsAfter(_childReference) {
1916
+ const parent = this._parent;
1917
+ if (parent != null) {
1918
+ return parent.getPatternsAfter(this);
1919
+ }
1920
+ return [];
1921
+ }
1922
+ getNextPatterns() {
1923
+ if (this.parent == null) {
1924
+ return [];
1925
+ }
1926
+ return this.parent.getPatternsAfter(this);
1927
+ }
1928
+ find(predicate) {
1929
+ return predicate(this._children[0]) ? this._children[0] : null;
1930
+ }
1931
+ isEqual(pattern) {
1932
+ return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
1933
+ }
1934
+ }
1935
+
1865
1936
  const inlinePatternOpenParen = new Literal("anonymous-pattern-open-paren", "(");
1866
1937
  const inlinePatternCloseParen = new Literal("anonymous-pattern-close-paren", ")");
1867
- const optionalLineSpaces$1 = lineSpaces$1.clone(undefined, true);
1868
- const complexAnonymousPattern = new And("complex-anonymous-pattern", [
1938
+ const optionalLineSpaces$3 = new Optional("optional-line-spaces", lineSpaces$1);
1939
+ const complexAnonymousPattern = new Sequence("complex-anonymous-pattern", [
1869
1940
  inlinePatternOpenParen,
1870
- optionalLineSpaces$1,
1941
+ optionalLineSpaces$3,
1871
1942
  anonymousWrappedLiterals,
1872
- optionalLineSpaces$1,
1943
+ optionalLineSpaces$3,
1873
1944
  inlinePatternCloseParen,
1874
1945
  ]);
1875
- const anonymousPattern = new Or("anonymous-pattern", [
1946
+ const anonymousPattern = new Options("anonymous-pattern", [
1876
1947
  anonymousLiterals,
1877
1948
  complexAnonymousPattern
1878
1949
  ]);
1879
1950
 
1880
- const optionalSpaces$2 = spaces$1.clone("optional-spaces", true);
1951
+ const optionalSpaces$3 = new Optional("optional-spaces", spaces$1);
1881
1952
  const openBracket$1 = new Literal("open-bracket", "{");
1882
1953
  const closeBracket$1 = new Literal("close-bracket", "}");
1883
1954
  const comma = new Literal("comma", ",");
1884
1955
  const integer = new Regex("integer", "([1-9][0-9]*)|0");
1885
1956
  integer.setTokens(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]);
1886
- const optionalInteger = integer.clone("integer", true);
1887
- const trimKeyword = new Literal("trim-keyword", "trim", true);
1888
- const trimFlag = new And("trim-flag", [lineSpaces$1, trimKeyword], true);
1889
- const bounds = new And("bounds", [
1957
+ const min = new Optional("optional-min", integer.clone("min"));
1958
+ const max = new Optional("optional-max", integer.clone("max"));
1959
+ const trimKeyword = new Literal("trim-keyword", "trim");
1960
+ const trimFlag = new Optional("optional-trim-flag", new Sequence("trim-flag", [lineSpaces$1, trimKeyword]));
1961
+ const bounds = new Sequence("bounds", [
1890
1962
  openBracket$1,
1891
- optionalSpaces$2,
1892
- optionalInteger.clone("min"),
1893
- optionalSpaces$2,
1963
+ optionalSpaces$3,
1964
+ min,
1965
+ optionalSpaces$3,
1894
1966
  comma,
1895
- optionalSpaces$2,
1896
- optionalInteger.clone("max"),
1967
+ optionalSpaces$3,
1968
+ max,
1897
1969
  closeBracket$1
1898
1970
  ]);
1899
- const exactCount = new And("exact-count", [
1971
+ const exactCount = new Sequence("exact-count", [
1900
1972
  openBracket$1,
1901
- optionalSpaces$2,
1973
+ optionalSpaces$3,
1902
1974
  integer,
1903
- optionalSpaces$2,
1975
+ optionalSpaces$3,
1904
1976
  closeBracket$1,
1905
1977
  ]);
1906
1978
  const quantifierShorthand = new Regex("quantifier-shorthand", "\\*|\\+");
1907
1979
  quantifierShorthand.setTokens(["*", "+"]);
1908
- const quantifier = new Or("quantifier", [
1980
+ const quantifier = new Options("quantifier", [
1909
1981
  quantifierShorthand,
1910
1982
  exactCount,
1911
1983
  bounds
@@ -1915,127 +1987,134 @@
1915
1987
  const dividerComma = new Regex("divider-comma", "\\s*,\\s*");
1916
1988
  dividerComma.setTokens([", "]);
1917
1989
  const patternName$2 = name$1.clone("pattern-name");
1918
- const patterns$3 = new Or("or-patterns", [patternName$2, anonymousPattern]);
1990
+ const patterns$3 = new Options("or-patterns", [patternName$2, anonymousPattern]);
1919
1991
  const dividerPattern = patterns$3.clone("divider-pattern");
1920
- const repeatLiteral = new And("repeat-literal", [
1992
+ const dividerSection = new Sequence("divider-section", [dividerComma, dividerPattern, trimFlag]);
1993
+ const optionalDividerSection = new Optional("optional-divider-section", dividerSection);
1994
+ const repeatLiteral = new Sequence("repeat-literal", [
1921
1995
  openParen,
1922
- optionalSpaces$2,
1996
+ optionalSpaces$3,
1923
1997
  patterns$3,
1924
- new And("optional-divider-section", [dividerComma, dividerPattern, trimFlag], true),
1925
- optionalSpaces$2,
1998
+ optionalDividerSection,
1999
+ optionalSpaces$3,
1926
2000
  closeParen,
1927
- new And("quantifier-section", [quantifier]),
2001
+ new Sequence("quantifier-section", [quantifier]),
1928
2002
  ]);
1929
2003
 
1930
- const optionalNot = new Literal("not", "!", true);
1931
- const optionalIsOptional$1 = new Literal("is-optional", "?", true);
2004
+ const optionalNot = new Optional("optional-not", new Literal("not", "!"));
2005
+ const optionalIsOptional$1 = new Optional("optional-is-optional", new Literal("is-optional", "?"));
1932
2006
  const patternName$1 = name$1.clone("pattern-name");
1933
- const patterns$2 = new Or("and-patterns", [patternName$1, anonymousPattern]);
1934
- const pattern$1 = new And("and-child-pattern", [
2007
+ const patterns$2 = new Options("and-patterns", [patternName$1, anonymousPattern]);
2008
+ const pattern$1 = new Sequence("and-child-pattern", [
1935
2009
  optionalNot,
1936
2010
  patterns$2,
1937
2011
  optionalIsOptional$1,
1938
2012
  ]);
1939
2013
  const divider$1 = new Regex("and-divider", "\\s*[+]\\s*");
1940
2014
  divider$1.setTokens([" + "]);
1941
- const andLiteral = new Repeat("and-literal", pattern$1, { divider: divider$1, min: 2, trimDivider: true });
2015
+ const sequenceLiteral = new Repeat("sequence-literal", pattern$1, { divider: divider$1, min: 2, trimDivider: true });
1942
2016
 
1943
2017
  const patternName = name$1.clone("pattern-name");
1944
- const patterns$1 = new Or("or-patterns", [patternName, anonymousPattern]);
2018
+ patternName.setTokens(["[PATTERN_NAME]"]);
2019
+ const patterns$1 = new Options("or-patterns", [patternName, anonymousPattern]);
1945
2020
  const defaultDivider = new Regex("default-divider", "\\s*[|]\\s*");
2021
+ defaultDivider.setTokens(["|"]);
1946
2022
  const greedyDivider = new Regex("greedy-divider", "\\s*[<][|][>]\\s*");
1947
- const divider = new Or("or-divider", [defaultDivider, greedyDivider]);
1948
- defaultDivider.setTokens([" | "]);
1949
- greedyDivider.setTokens([" <|> "]);
1950
- const orLiteral = new Repeat("or-literal", patterns$1, { divider, min: 2, trimDivider: true });
2023
+ greedyDivider.setTokens(["<|>"]);
2024
+ const divider = new Options("options-divider", [defaultDivider, greedyDivider]);
2025
+ const optionsLiteral = new Repeat("options-literal", patterns$1, { divider, min: 2, trimDivider: true });
1951
2026
 
1952
2027
  const aliasLiteral = name$1.clone("alias-literal");
1953
- const optionalIsOptional = new Literal("is-optional", "?", true);
1954
- const configurableAnonymousPattern = new And("configurable-anonymous-pattern", [anonymousPattern, optionalIsOptional]);
1955
- const pattern = new Or("pattern", [
2028
+ aliasLiteral.setTokens(["[ALIAS_LITERAL]"]);
2029
+ const optionalIsOptional = new Optional("optional-flag", new Literal("is-optional", "?"));
2030
+ const configurableAnonymousPattern = new Sequence("configurable-anonymous-pattern", [anonymousPattern, optionalIsOptional]);
2031
+ const pattern = new Options("pattern", [
1956
2032
  literal,
1957
2033
  regexLiteral,
1958
2034
  repeatLiteral,
1959
2035
  aliasLiteral,
1960
- orLiteral,
1961
- andLiteral,
2036
+ optionsLiteral,
2037
+ sequenceLiteral,
1962
2038
  configurableAnonymousPattern,
1963
- ], false, true);
2039
+ ], true);
1964
2040
 
1965
- const optionalSpaces$1 = spaces$1.clone("optional-spaces", true);
2041
+ const optionalSpaces$2 = new Optional("optional-spaces", spaces$1);
1966
2042
  const assignOperator = new Literal("assign-operator", "=");
1967
- const assignStatement = new And("assign-statement", [
1968
- optionalSpaces$1,
2043
+ const assignStatement = new Sequence("assign-statement", [
2044
+ optionalSpaces$2,
1969
2045
  name$1,
1970
- optionalSpaces$1,
2046
+ optionalSpaces$2,
1971
2047
  assignOperator,
1972
- optionalSpaces$1,
2048
+ optionalSpaces$2,
1973
2049
  pattern
1974
2050
  ]);
1975
- const statement = new Or("statement", [assignStatement, name$1.clone("export-name")]);
2051
+ const statement = new Options("statement", [assignStatement, name$1.clone("export-name")]);
1976
2052
 
1977
- const bodyLineContent = new Or("body-line-content", [
2053
+ const bodyLineContent = new Options("body-line-content", [
1978
2054
  comment,
1979
2055
  statement
1980
2056
  ]);
1981
- const bodyLine = new And("body-line", [
1982
- lineSpaces$1.clone("line-spaces", true),
2057
+ const optionalLineSpaces$2 = new Optional("optional-line-spaces", lineSpaces$1);
2058
+ const bodyLine = new Sequence("body-line", [
2059
+ optionalLineSpaces$2,
1983
2060
  bodyLineContent,
1984
- lineSpaces$1.clone("line-spaces", true),
2061
+ optionalLineSpaces$2,
1985
2062
  ]);
1986
2063
  const body = new Repeat("body", bodyLine, { divider: newLine$1, min: 0 });
1987
2064
 
1988
- const optionalSpaces = allSpaces.clone("optional-spaces", true);
1989
- const optionalLineSpaces = lineSpaces$1.clone("options-line-spaces", true);
2065
+ const optionalSpaces$1 = new Optional("optional-spaces", allSpaces);
2066
+ const optionalLineSpaces$1 = new Optional("options-line-spaces", lineSpaces$1);
1990
2067
  const importNameDivider = new Regex("import-name-divider", "(\\s+)?,(\\s+)?");
2068
+ importNameDivider.setTokens([", "]);
2069
+ const name = new Regex("import-name", "[^}\\s,]+");
2070
+ name.setTokens(["[IMPORT_NAME]"]);
1991
2071
  const importKeyword = new Literal("import", "import");
1992
2072
  const useParamsKeyword = new Literal("use-params", "use params");
1993
2073
  const asKeyword = new Literal("as", "as");
1994
2074
  const fromKeyword = new Literal("from", "from");
1995
2075
  const openBracket = new Literal("open-bracket", "{");
1996
2076
  const closeBracket = new Literal("close-bracket", "}");
1997
- const name = new Regex("import-name", "[^}\\s,]+");
1998
2077
  const importNameAlias = name.clone("import-name-alias");
1999
- const importAlias = new And("import-alias", [name, lineSpaces$1, asKeyword, lineSpaces$1, importNameAlias]);
2000
- const importedNames = new Repeat("imported-names", new Or("import-names", [importAlias, name]), { divider: importNameDivider });
2078
+ const importAlias = new Sequence("import-alias", [name, lineSpaces$1, asKeyword, lineSpaces$1, importNameAlias]);
2079
+ const importedNames = new Repeat("imported-names", new Options("import-names", [importAlias, name]), { divider: importNameDivider });
2001
2080
  const paramName = name.clone("param-name");
2002
2081
  const paramNames = new Repeat("param-names", paramName, { divider: importNameDivider });
2003
2082
  const resource = literal.clone("resource");
2004
- const useParams = new And("import-params", [
2083
+ const useParams = new Sequence("import-params", [
2005
2084
  useParamsKeyword,
2006
- optionalLineSpaces,
2085
+ optionalLineSpaces$1,
2007
2086
  openBracket,
2008
- optionalSpaces,
2087
+ optionalSpaces$1,
2009
2088
  paramNames,
2010
- optionalSpaces,
2089
+ optionalSpaces$1,
2011
2090
  closeBracket
2012
2091
  ]);
2013
2092
  const withParamsKeyword = new Literal("with-params", "with params");
2014
- const withParamsStatement = new And("with-params-statement", [
2093
+ const withParamsStatement = new Optional("optional-with-params-statement", new Sequence("with-params-statement", [
2015
2094
  withParamsKeyword,
2016
- optionalLineSpaces,
2095
+ optionalLineSpaces$1,
2017
2096
  openBracket,
2018
- optionalSpaces,
2097
+ optionalSpaces$1,
2019
2098
  body.clone("with-params-body"),
2020
- optionalSpaces,
2099
+ optionalSpaces$1,
2021
2100
  closeBracket
2022
- ], true);
2023
- const importFromStatement = new And("import-from", [
2101
+ ]));
2102
+ const importFromStatement = new Sequence("import-from", [
2024
2103
  importKeyword,
2025
- optionalLineSpaces,
2104
+ optionalLineSpaces$1,
2026
2105
  openBracket,
2027
- optionalSpaces,
2106
+ optionalSpaces$1,
2028
2107
  importedNames,
2029
- optionalSpaces,
2108
+ optionalSpaces$1,
2030
2109
  closeBracket,
2031
- optionalLineSpaces,
2110
+ optionalLineSpaces$1,
2032
2111
  fromKeyword,
2033
- optionalLineSpaces,
2112
+ optionalLineSpaces$1,
2034
2113
  resource,
2035
- optionalLineSpaces,
2114
+ optionalLineSpaces$1,
2036
2115
  withParamsStatement
2037
2116
  ]);
2038
- const importStatement = new Or("import-statement", [
2117
+ const importStatement = new Options("import-statement", [
2039
2118
  useParams,
2040
2119
  importFromStatement
2041
2120
  ]);
@@ -2046,23 +2125,25 @@
2046
2125
  spaces.setTokens([" "]);
2047
2126
  tabs.setTokens(["\t"]);
2048
2127
  newLine.setTokens(["\n"]);
2049
- const lineSpaces = new Repeat("line-spaces", new Or("line-space", [tabs, spaces]));
2050
- const headLineContent = new Or("head-line-content", [
2128
+ const lineSpaces = new Repeat("line-spaces", new Options("line-space", [tabs, spaces]));
2129
+ const optionalLineSpaces = new Optional("optional-line-spaces", lineSpaces);
2130
+ const headLineContent = new Options("head-line-content", [
2051
2131
  comment,
2052
2132
  importStatement
2053
2133
  ]);
2054
- const headLine = new And("head-line-content", [
2055
- lineSpaces.clone("line-spaces", true),
2134
+ const headLine = new Sequence("head-line-content", [
2135
+ optionalLineSpaces,
2056
2136
  headLineContent,
2057
- lineSpaces.clone("line-spaces", true),
2137
+ optionalLineSpaces,
2058
2138
  ]);
2059
- const head = new Repeat("head", headLine, { divider: newLine, min: 0 });
2060
- const grammar = new And("grammar", [
2061
- allSpaces,
2139
+ const head = new Optional("optional-head", new Repeat("head", headLine, { divider: newLine }));
2140
+ const optionalSpaces = new Optional("optional-spaces", allSpaces);
2141
+ const grammar = new Sequence("grammar", [
2142
+ optionalSpaces,
2062
2143
  head,
2063
- allSpaces,
2144
+ optionalSpaces,
2064
2145
  body,
2065
- allSpaces
2146
+ optionalSpaces
2066
2147
  ]);
2067
2148
 
2068
2149
  let idIndex = 0;
@@ -2093,7 +2174,7 @@
2093
2174
  this._type = "not";
2094
2175
  this._name = name;
2095
2176
  this._parent = null;
2096
- this._children = [pattern.clone(pattern.name, false)];
2177
+ this._children = [pattern.clone()];
2097
2178
  this._children[0].parent = this;
2098
2179
  }
2099
2180
  test(text) {
@@ -2381,8 +2462,8 @@
2381
2462
  const patternNodes = {
2382
2463
  "literal": true,
2383
2464
  "regex-literal": true,
2384
- "or-literal": true,
2385
- "and-literal": true,
2465
+ "options-literal": true,
2466
+ "sequence-literal": true,
2386
2467
  "repeat-literal": true,
2387
2468
  "alias-literal": true,
2388
2469
  "configurable-anonymous-pattern": true
@@ -2485,12 +2566,12 @@
2485
2566
  this._saveRegex(n);
2486
2567
  break;
2487
2568
  }
2488
- case "or-literal": {
2489
- this._saveOr(n);
2569
+ case "options-literal": {
2570
+ this._saveOptions(n);
2490
2571
  break;
2491
2572
  }
2492
- case "and-literal": {
2493
- this._saveAnd(n);
2573
+ case "sequence-literal": {
2574
+ this._saveSequence(n);
2494
2575
  break;
2495
2576
  }
2496
2577
  case "repeat-literal": {
@@ -2545,18 +2626,18 @@
2545
2626
  const value = node.value.slice(1, node.value.length - 1);
2546
2627
  return new Regex(name, value);
2547
2628
  }
2548
- _saveOr(statementNode) {
2629
+ _saveOptions(statementNode) {
2549
2630
  const nameNode = statementNode.find(n => n.name === "name");
2550
2631
  const name = nameNode.value;
2551
- const orNode = statementNode.find(n => n.name === "or-literal");
2552
- const or = this._buildOr(name, orNode);
2553
- this._parseContext.patternsByName.set(name, or);
2632
+ const optionsNode = statementNode.find(n => n.name === "options-literal");
2633
+ const options = this._buildOptions(name, optionsNode);
2634
+ this._parseContext.patternsByName.set(name, options);
2554
2635
  }
2555
- _buildOr(name, node) {
2636
+ _buildOptions(name, node) {
2556
2637
  const patternNodes = node.children.filter(n => n.name !== "default-divider" && n.name !== "greedy-divider");
2557
2638
  const isGreedy = node.find(n => n.name === "greedy-divider") != null;
2558
2639
  const patterns = patternNodes.map(n => this._buildPattern(n));
2559
- const or = new Or(name, patterns, false, isGreedy);
2640
+ const or = new Options(name, patterns, isGreedy);
2560
2641
  return or;
2561
2642
  }
2562
2643
  _buildPattern(node) {
@@ -2575,11 +2656,11 @@
2575
2656
  case "repeat-literal": {
2576
2657
  return this._buildRepeat(name, node);
2577
2658
  }
2578
- case "or-literal": {
2579
- return this._buildOr(name, node);
2659
+ case "options-literal": {
2660
+ return this._buildOptions(name, node);
2580
2661
  }
2581
- case "and-literal": {
2582
- return this._buildAnd(name, node);
2662
+ case "sequence-literal": {
2663
+ return this._buildSequence(name, node);
2583
2664
  }
2584
2665
  case "complex-anonymous-pattern": {
2585
2666
  return this._buildComplexAnonymousPattern(node);
@@ -2587,26 +2668,27 @@
2587
2668
  }
2588
2669
  throw new Error(`Couldn't build node: ${node.name}.`);
2589
2670
  }
2590
- _saveAnd(statementNode) {
2671
+ _saveSequence(statementNode) {
2591
2672
  const nameNode = statementNode.find(n => n.name === "name");
2592
2673
  const name = nameNode.value;
2593
- const andNode = statementNode.find(n => n.name === "and-literal");
2594
- const and = this._buildAnd(name, andNode);
2595
- this._parseContext.patternsByName.set(name, and);
2674
+ const sequenceNode = statementNode.find(n => n.name === "sequence-literal");
2675
+ const sequence = this._buildSequence(name, sequenceNode);
2676
+ this._parseContext.patternsByName.set(name, sequence);
2596
2677
  }
2597
- _buildAnd(name, node) {
2678
+ _buildSequence(name, node) {
2598
2679
  const patternNodes = node.children.filter(n => n.name !== "and-divider");
2599
2680
  const patterns = patternNodes.map(n => {
2600
2681
  const patternNode = n.children[0].name === "not" ? n.children[1] : n.children[0];
2601
2682
  const isNot = n.find(n => n.name === "not") != null;
2602
2683
  const isOptional = n.find(n => n.name === "is-optional");
2603
- const pattern = this._buildPattern(patternNode).clone(undefined, isOptional == null ? undefined : true);
2684
+ const pattern = this._buildPattern(patternNode);
2685
+ const finalPattern = isOptional ? new Optional(pattern.name, pattern) : pattern;
2604
2686
  if (isNot) {
2605
- return new Not(`not-${pattern.name}`, pattern);
2687
+ return new Not(`not-${finalPattern.name}`, finalPattern);
2606
2688
  }
2607
- return pattern;
2689
+ return finalPattern;
2608
2690
  });
2609
- return new And(name, patterns);
2691
+ return new Sequence(name, patterns);
2610
2692
  }
2611
2693
  _saveRepeat(statementNode) {
2612
2694
  const nameNode = statementNode.find(n => n.name === "name");
@@ -2616,13 +2698,14 @@
2616
2698
  this._parseContext.patternsByName.set(name, repeat);
2617
2699
  }
2618
2700
  _buildRepeat(name, repeatNode) {
2701
+ let isOptional = false;
2619
2702
  const bounds = repeatNode.find(n => n.name === "bounds");
2620
2703
  const exactCount = repeatNode.find(n => n.name === "exact-count");
2621
2704
  const quantifier = repeatNode.find(n => n.name === "quantifier-shorthand");
2622
2705
  const trimDivider = repeatNode.find(n => n.name === "trim-flag") != null;
2623
- const patterNode = repeatNode.children[1].type === "optional-spaces" ? repeatNode.children[2] : repeatNode.children[1];
2706
+ const patterNode = repeatNode.children[1].type === "spaces" ? repeatNode.children[2] : repeatNode.children[1];
2624
2707
  const pattern = this._buildPattern(patterNode);
2625
- const dividerSectionNode = repeatNode.find(n => n.name === "optional-divider-section");
2708
+ const dividerSectionNode = repeatNode.find(n => n.name === "divider-section");
2626
2709
  const options = {
2627
2710
  min: 1,
2628
2711
  max: Infinity
@@ -2655,18 +2738,17 @@
2655
2738
  options.max = Infinity;
2656
2739
  }
2657
2740
  else {
2658
- options.min = 0;
2659
- options.max = Infinity;
2741
+ isOptional = true;
2660
2742
  }
2661
2743
  }
2662
- return new Repeat(name, pattern.clone(pattern.name), options);
2744
+ return isOptional ? new Optional(name, new Repeat(name, pattern, options)) : new Repeat(name, pattern, options);
2663
2745
  }
2664
2746
  _saveConfigurableAnonymous(node) {
2665
2747
  const nameNode = node.find(n => n.name === "name");
2666
2748
  const name = nameNode.value;
2667
2749
  const anonymousNode = node.find(n => n.name === "complex-anonymous-pattern");
2668
2750
  const isOptional = node.children[1] != null;
2669
- const anonymous = this._buildPattern(anonymousNode).clone(name, isOptional);
2751
+ const anonymous = isOptional ? new Optional(name, this._buildPattern(anonymousNode)) : this._buildPattern(anonymousNode);
2670
2752
  this._parseContext.patternsByName.set(name, anonymous);
2671
2753
  }
2672
2754
  _buildComplexAnonymousPattern(node) {
@@ -2809,7 +2891,6 @@
2809
2891
  return result;
2810
2892
  }
2811
2893
 
2812
- exports.And = And;
2813
2894
  exports.AutoComplete = AutoComplete;
2814
2895
  exports.Cursor = Cursor;
2815
2896
  exports.CursorHistory = CursorHistory;
@@ -2817,11 +2898,13 @@
2817
2898
  exports.Literal = Literal;
2818
2899
  exports.Node = Node;
2819
2900
  exports.Not = Not;
2820
- exports.Or = Or;
2901
+ exports.Optional = Optional;
2902
+ exports.Options = Options;
2821
2903
  exports.ParseError = ParseError;
2822
2904
  exports.Reference = Reference;
2823
2905
  exports.Regex = Regex;
2824
2906
  exports.Repeat = Repeat;
2907
+ exports.Sequence = Sequence;
2825
2908
  exports.arePatternsEqual = arePatternsEqual;
2826
2909
  exports.grammar = grammar;
2827
2910
  exports.patterns = patterns;