clarity-pattern-parser 9.0.0 → 9.2.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,19 @@
1503
1486
  get children() {
1504
1487
  return this._children;
1505
1488
  }
1506
- get isOptional() {
1507
- return this._repeatPattern.isOptional;
1489
+ get min() {
1490
+ return this.children[0].min;
1491
+ }
1492
+ get max() {
1493
+ return this.children[0].max || Infinity;
1508
1494
  }
1509
1495
  constructor(name, pattern, options = {}) {
1510
- this._id = `repeat-${idIndex$2++}`;
1496
+ this._id = `repeat-${idIndex$3++}`;
1511
1497
  this._pattern = pattern;
1512
1498
  this._parent = null;
1513
1499
  this._options = Object.assign(Object.assign({}, options), { min: options.min == null ? 1 : options.min, max: options.max == null ? Infinity : options.max });
1514
1500
  if (this._options.max !== Infinity) {
1515
- this._repeatPattern = new FiniteRepeat(name, pattern, this._options.max, this._options);
1501
+ this._repeatPattern = new FiniteRepeat(name, pattern, this._options);
1516
1502
  }
1517
1503
  else {
1518
1504
  this._repeatPattern = new InfiniteRepeat(name, pattern, this._options);
@@ -1529,16 +1515,8 @@
1529
1515
  test(text) {
1530
1516
  return this._repeatPattern.test(text);
1531
1517
  }
1532
- clone(name = this.name, isOptional) {
1518
+ clone(name = this.name) {
1533
1519
  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
1520
  const clone = new Repeat(name, this._pattern, Object.assign(Object.assign({}, this._options), { min }));
1543
1521
  clone._id = this._id;
1544
1522
  return clone;
@@ -1582,6 +1560,7 @@
1582
1560
  }
1583
1561
 
1584
1562
  const comment = new Regex("comment", "#[^\r\n]+");
1563
+ comment.setTokens(["# "]);
1585
1564
 
1586
1565
  function filterOutNull(nodes) {
1587
1566
  const filteredNodes = [];
@@ -1593,8 +1572,8 @@
1593
1572
  return filteredNodes;
1594
1573
  }
1595
1574
 
1596
- let idIndex$1 = 0;
1597
- class And {
1575
+ let idIndex$2 = 0;
1576
+ class Sequence {
1598
1577
  get id() {
1599
1578
  return this._id;
1600
1579
  }
@@ -1613,19 +1592,15 @@
1613
1592
  get children() {
1614
1593
  return this._children;
1615
1594
  }
1616
- get isOptional() {
1617
- return this._isOptional;
1618
- }
1619
- constructor(name, sequence, isOptional = false) {
1595
+ constructor(name, sequence) {
1620
1596
  if (sequence.length === 0) {
1621
- throw new Error("Need at least one pattern with an 'and' pattern.");
1597
+ throw new Error("Need at least one pattern with a 'sequence' pattern.");
1622
1598
  }
1623
1599
  const children = clonePatterns(sequence);
1624
1600
  this._assignChildrenToParent(children);
1625
- this._id = `and-${idIndex$1++}`;
1626
- this._type = "and";
1601
+ this._id = `sequence-${idIndex$2++}`;
1602
+ this._type = "sequence";
1627
1603
  this._name = name;
1628
- this._isOptional = isOptional;
1629
1604
  this._parent = null;
1630
1605
  this._children = children;
1631
1606
  this._firstIndex = -1;
@@ -1663,9 +1638,6 @@
1663
1638
  cursor.endParse();
1664
1639
  return node;
1665
1640
  }
1666
- if (this._isOptional) {
1667
- cursor.resolveError();
1668
- }
1669
1641
  cursor.endParse();
1670
1642
  return null;
1671
1643
  }
@@ -1738,7 +1710,7 @@
1738
1710
  const length = this._children.length;
1739
1711
  for (let i = startOnIndex; i < length; i++) {
1740
1712
  const pattern = this._children[i];
1741
- if (!pattern.isOptional) {
1713
+ if (pattern.type !== "optional") {
1742
1714
  return false;
1743
1715
  }
1744
1716
  }
@@ -1748,13 +1720,13 @@
1748
1720
  const children = filterOutNull(this._nodes);
1749
1721
  const lastIndex = children[children.length - 1].lastIndex;
1750
1722
  cursor.moveTo(lastIndex);
1751
- return new Node("and", this._name, this._firstIndex, lastIndex, children);
1723
+ return new Node("sequence", this._name, this._firstIndex, lastIndex, children);
1752
1724
  }
1753
1725
  getTokens() {
1754
1726
  const tokens = [];
1755
1727
  for (const child of this._children) {
1756
1728
  tokens.push(...child.getTokens());
1757
- if (!child.isOptional) {
1729
+ if (child.type !== "optional") {
1758
1730
  break;
1759
1731
  }
1760
1732
  }
@@ -1774,9 +1746,9 @@
1774
1746
  }
1775
1747
  getPatterns() {
1776
1748
  const patterns = [];
1777
- for (const pattern of this._children) {
1778
- patterns.push(...pattern.getPatterns());
1779
- if (!pattern.isOptional) {
1749
+ for (const child of this._children) {
1750
+ patterns.push(...child.getPatterns());
1751
+ if (child.type !== "optional") {
1780
1752
  break;
1781
1753
  }
1782
1754
  }
@@ -1805,7 +1777,7 @@
1805
1777
  for (let i = nextSiblingIndex; i < this._children.length; i++) {
1806
1778
  const child = this._children[i];
1807
1779
  patterns.push(child);
1808
- if (!child.isOptional) {
1780
+ if (child.type !== "optional") {
1809
1781
  break;
1810
1782
  }
1811
1783
  // If we are on the last child and its options then ask for the next pattern from the parent.
@@ -1824,8 +1796,8 @@
1824
1796
  find(predicate) {
1825
1797
  return findPattern(this, predicate);
1826
1798
  }
1827
- clone(name = this._name, isOptional = this._isOptional) {
1828
- const clone = new And(name, this._children, isOptional);
1799
+ clone(name = this._name) {
1800
+ const clone = new Sequence(name, this._children);
1829
1801
  clone._id = this._id;
1830
1802
  return clone;
1831
1803
  }
@@ -1835,77 +1807,183 @@
1835
1807
  }
1836
1808
 
1837
1809
  const literal = new Regex("literal", '"(?:\\\\.|[^"\\\\])*"');
1810
+ literal.setTokens(["[LITERAL]"]);
1838
1811
 
1839
1812
  const tabs$1 = new Regex("tabs", "\\t+");
1813
+ tabs$1.setTokens(["\t"]);
1840
1814
  const spaces$1 = new Regex("spaces", "[ ]+");
1841
- const newLine$1 = new Regex("new-line", "(\\r?\\n)+");
1842
1815
  spaces$1.setTokens([" "]);
1843
- tabs$1.setTokens(["\t"]);
1816
+ const newLine$1 = new Regex("new-line", "(\\r?\\n)+");
1844
1817
  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);
1818
+ const lineSpaces$1 = new Repeat("line-spaces", new Options("line-space", [tabs$1, spaces$1]));
1819
+ const allSpaces = new Regex("all-spaces", "\\s+");
1820
+ allSpaces.setTokens([" "]);
1847
1821
 
1848
1822
  const name$1 = new Regex("name", "[a-zA-Z_-]+[a-zA-Z0-9_-]*");
1849
1823
 
1850
1824
  const regexLiteral = new Regex("regex-literal", "/(\\\\/|[^/\\n\\r])*/");
1825
+ regexLiteral.setTokens(["[REGEX_EXPRESSION]"]);
1851
1826
 
1852
1827
  const patternName$3 = name$1.clone("pattern-name");
1853
- const anonymousLiterals = new Or("anonymous-literals", [
1828
+ const anonymousLiterals = new Options("anonymous-literals", [
1854
1829
  literal,
1855
1830
  regexLiteral,
1856
1831
  patternName$3,
1857
1832
  new Reference("repeat-literal"),
1858
1833
  ]);
1859
- const anonymousWrappedLiterals = new Or("anonymous-wrapped-literals", [
1860
- new Reference("or-literal"),
1861
- new Reference("and-literal"),
1834
+ const anonymousWrappedLiterals = new Options("anonymous-wrapped-literals", [
1835
+ new Reference("options-literal"),
1836
+ new Reference("sequence-literal"),
1862
1837
  new Reference("complex-anonymous-pattern")
1863
1838
  ]);
1864
1839
 
1840
+ let idIndex$1 = 0;
1841
+ class Optional {
1842
+ get id() {
1843
+ return this._id;
1844
+ }
1845
+ get type() {
1846
+ return this._type;
1847
+ }
1848
+ get name() {
1849
+ return this._name;
1850
+ }
1851
+ get parent() {
1852
+ return this._parent;
1853
+ }
1854
+ set parent(pattern) {
1855
+ this._parent = pattern;
1856
+ }
1857
+ get children() {
1858
+ return this._children;
1859
+ }
1860
+ constructor(name, pattern) {
1861
+ this._id = `optional-${idIndex$1++}`;
1862
+ this._type = "optional";
1863
+ this._name = name;
1864
+ this._parent = null;
1865
+ this._children = [pattern.clone()];
1866
+ this._children[0].parent = this;
1867
+ }
1868
+ test(text) {
1869
+ const cursor = new Cursor(text);
1870
+ this.parse(cursor);
1871
+ return !cursor.hasError;
1872
+ }
1873
+ exec(text, record = false) {
1874
+ const cursor = new Cursor(text);
1875
+ record && cursor.startRecording();
1876
+ const ast = this.parse(cursor);
1877
+ return {
1878
+ ast: (ast === null || ast === void 0 ? void 0 : ast.value) === text ? ast : null,
1879
+ cursor
1880
+ };
1881
+ }
1882
+ parse(cursor) {
1883
+ cursor.startParseWith(this);
1884
+ const firstIndex = cursor.index;
1885
+ const node = this._children[0].parse(cursor);
1886
+ if (cursor.hasError) {
1887
+ cursor.resolveError();
1888
+ cursor.moveTo(firstIndex);
1889
+ cursor.endParse();
1890
+ return null;
1891
+ }
1892
+ else {
1893
+ cursor.endParse();
1894
+ return node;
1895
+ }
1896
+ }
1897
+ clone(name = this._name) {
1898
+ const optional = new Optional(name, this._children[0]);
1899
+ optional._id = this._id;
1900
+ return optional;
1901
+ }
1902
+ getTokens() {
1903
+ return this._children[0].getTokens();
1904
+ }
1905
+ getTokensAfter(_childReference) {
1906
+ const parent = this._parent;
1907
+ if (parent != null) {
1908
+ return parent.getTokensAfter(this);
1909
+ }
1910
+ return [];
1911
+ }
1912
+ getNextTokens() {
1913
+ if (this.parent == null) {
1914
+ return [];
1915
+ }
1916
+ return this.parent.getTokensAfter(this);
1917
+ }
1918
+ getPatterns() {
1919
+ return this._children[0].getPatterns();
1920
+ }
1921
+ getPatternsAfter(_childReference) {
1922
+ const parent = this._parent;
1923
+ if (parent != null) {
1924
+ return parent.getPatternsAfter(this);
1925
+ }
1926
+ return [];
1927
+ }
1928
+ getNextPatterns() {
1929
+ if (this.parent == null) {
1930
+ return [];
1931
+ }
1932
+ return this.parent.getPatternsAfter(this);
1933
+ }
1934
+ find(predicate) {
1935
+ return predicate(this._children[0]) ? this._children[0] : null;
1936
+ }
1937
+ isEqual(pattern) {
1938
+ return pattern.type === this.type && this.children.every((c, index) => c.isEqual(pattern.children[index]));
1939
+ }
1940
+ }
1941
+
1865
1942
  const inlinePatternOpenParen = new Literal("anonymous-pattern-open-paren", "(");
1866
1943
  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", [
1944
+ const optionalLineSpaces$3 = new Optional("optional-line-spaces", lineSpaces$1);
1945
+ const complexAnonymousPattern = new Sequence("complex-anonymous-pattern", [
1869
1946
  inlinePatternOpenParen,
1870
- optionalLineSpaces$1,
1947
+ optionalLineSpaces$3,
1871
1948
  anonymousWrappedLiterals,
1872
- optionalLineSpaces$1,
1949
+ optionalLineSpaces$3,
1873
1950
  inlinePatternCloseParen,
1874
1951
  ]);
1875
- const anonymousPattern = new Or("anonymous-pattern", [
1952
+ const anonymousPattern = new Options("anonymous-pattern", [
1876
1953
  anonymousLiterals,
1877
1954
  complexAnonymousPattern
1878
1955
  ]);
1879
1956
 
1880
- const optionalSpaces$2 = spaces$1.clone("optional-spaces", true);
1957
+ const optionalSpaces$3 = new Optional("optional-spaces", spaces$1);
1881
1958
  const openBracket$1 = new Literal("open-bracket", "{");
1882
1959
  const closeBracket$1 = new Literal("close-bracket", "}");
1883
1960
  const comma = new Literal("comma", ",");
1884
1961
  const integer = new Regex("integer", "([1-9][0-9]*)|0");
1885
1962
  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", [
1963
+ const min = new Optional("optional-min", integer.clone("min"));
1964
+ const max = new Optional("optional-max", integer.clone("max"));
1965
+ const trimKeyword = new Literal("trim-keyword", "trim");
1966
+ const trimFlag = new Optional("optional-trim-flag", new Sequence("trim-flag", [lineSpaces$1, trimKeyword]));
1967
+ const bounds = new Sequence("bounds", [
1890
1968
  openBracket$1,
1891
- optionalSpaces$2,
1892
- optionalInteger.clone("min"),
1893
- optionalSpaces$2,
1969
+ optionalSpaces$3,
1970
+ min,
1971
+ optionalSpaces$3,
1894
1972
  comma,
1895
- optionalSpaces$2,
1896
- optionalInteger.clone("max"),
1973
+ optionalSpaces$3,
1974
+ max,
1897
1975
  closeBracket$1
1898
1976
  ]);
1899
- const exactCount = new And("exact-count", [
1977
+ const exactCount = new Sequence("exact-count", [
1900
1978
  openBracket$1,
1901
- optionalSpaces$2,
1979
+ optionalSpaces$3,
1902
1980
  integer,
1903
- optionalSpaces$2,
1981
+ optionalSpaces$3,
1904
1982
  closeBracket$1,
1905
1983
  ]);
1906
1984
  const quantifierShorthand = new Regex("quantifier-shorthand", "\\*|\\+");
1907
1985
  quantifierShorthand.setTokens(["*", "+"]);
1908
- const quantifier = new Or("quantifier", [
1986
+ const quantifier = new Options("quantifier", [
1909
1987
  quantifierShorthand,
1910
1988
  exactCount,
1911
1989
  bounds
@@ -1915,127 +1993,134 @@
1915
1993
  const dividerComma = new Regex("divider-comma", "\\s*,\\s*");
1916
1994
  dividerComma.setTokens([", "]);
1917
1995
  const patternName$2 = name$1.clone("pattern-name");
1918
- const patterns$3 = new Or("or-patterns", [patternName$2, anonymousPattern]);
1996
+ const patterns$3 = new Options("or-patterns", [patternName$2, anonymousPattern]);
1919
1997
  const dividerPattern = patterns$3.clone("divider-pattern");
1920
- const repeatLiteral = new And("repeat-literal", [
1998
+ const dividerSection = new Sequence("divider-section", [dividerComma, dividerPattern, trimFlag]);
1999
+ const optionalDividerSection = new Optional("optional-divider-section", dividerSection);
2000
+ const repeatLiteral = new Sequence("repeat-literal", [
1921
2001
  openParen,
1922
- optionalSpaces$2,
2002
+ optionalSpaces$3,
1923
2003
  patterns$3,
1924
- new And("optional-divider-section", [dividerComma, dividerPattern, trimFlag], true),
1925
- optionalSpaces$2,
2004
+ optionalDividerSection,
2005
+ optionalSpaces$3,
1926
2006
  closeParen,
1927
- new And("quantifier-section", [quantifier]),
2007
+ new Sequence("quantifier-section", [quantifier]),
1928
2008
  ]);
1929
2009
 
1930
- const optionalNot = new Literal("not", "!", true);
1931
- const optionalIsOptional$1 = new Literal("is-optional", "?", true);
2010
+ const optionalNot = new Optional("optional-not", new Literal("not", "!"));
2011
+ const optionalIsOptional$1 = new Optional("optional-is-optional", new Literal("is-optional", "?"));
1932
2012
  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", [
2013
+ const patterns$2 = new Options("and-patterns", [patternName$1, anonymousPattern]);
2014
+ const pattern$1 = new Sequence("and-child-pattern", [
1935
2015
  optionalNot,
1936
2016
  patterns$2,
1937
2017
  optionalIsOptional$1,
1938
2018
  ]);
1939
2019
  const divider$1 = new Regex("and-divider", "\\s*[+]\\s*");
1940
2020
  divider$1.setTokens([" + "]);
1941
- const andLiteral = new Repeat("and-literal", pattern$1, { divider: divider$1, min: 2, trimDivider: true });
2021
+ const sequenceLiteral = new Repeat("sequence-literal", pattern$1, { divider: divider$1, min: 2, trimDivider: true });
1942
2022
 
1943
2023
  const patternName = name$1.clone("pattern-name");
1944
- const patterns$1 = new Or("or-patterns", [patternName, anonymousPattern]);
2024
+ patternName.setTokens(["[PATTERN_NAME]"]);
2025
+ const patterns$1 = new Options("or-patterns", [patternName, anonymousPattern]);
1945
2026
  const defaultDivider = new Regex("default-divider", "\\s*[|]\\s*");
2027
+ defaultDivider.setTokens(["|"]);
1946
2028
  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 });
2029
+ greedyDivider.setTokens(["<|>"]);
2030
+ const divider = new Options("options-divider", [defaultDivider, greedyDivider]);
2031
+ const optionsLiteral = new Repeat("options-literal", patterns$1, { divider, min: 2, trimDivider: true });
1951
2032
 
1952
2033
  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", [
2034
+ aliasLiteral.setTokens(["[ALIAS_LITERAL]"]);
2035
+ const optionalIsOptional = new Optional("optional-flag", new Literal("is-optional", "?"));
2036
+ const configurableAnonymousPattern = new Sequence("configurable-anonymous-pattern", [anonymousPattern, optionalIsOptional]);
2037
+ const pattern = new Options("pattern", [
1956
2038
  literal,
1957
2039
  regexLiteral,
1958
2040
  repeatLiteral,
1959
2041
  aliasLiteral,
1960
- orLiteral,
1961
- andLiteral,
2042
+ optionsLiteral,
2043
+ sequenceLiteral,
1962
2044
  configurableAnonymousPattern,
1963
- ], false, true);
2045
+ ], true);
1964
2046
 
1965
- const optionalSpaces$1 = spaces$1.clone("optional-spaces", true);
2047
+ const optionalSpaces$2 = new Optional("optional-spaces", spaces$1);
1966
2048
  const assignOperator = new Literal("assign-operator", "=");
1967
- const assignStatement = new And("assign-statement", [
1968
- optionalSpaces$1,
2049
+ const assignStatement = new Sequence("assign-statement", [
2050
+ optionalSpaces$2,
1969
2051
  name$1,
1970
- optionalSpaces$1,
2052
+ optionalSpaces$2,
1971
2053
  assignOperator,
1972
- optionalSpaces$1,
2054
+ optionalSpaces$2,
1973
2055
  pattern
1974
2056
  ]);
1975
- const statement = new Or("statement", [assignStatement, name$1.clone("export-name")]);
2057
+ const statement = new Options("statement", [assignStatement, name$1.clone("export-name")]);
1976
2058
 
1977
- const bodyLineContent = new Or("body-line-content", [
2059
+ const bodyLineContent = new Options("body-line-content", [
1978
2060
  comment,
1979
2061
  statement
1980
2062
  ]);
1981
- const bodyLine = new And("body-line", [
1982
- lineSpaces$1.clone("line-spaces", true),
2063
+ const optionalLineSpaces$2 = new Optional("optional-line-spaces", lineSpaces$1);
2064
+ const bodyLine = new Sequence("body-line", [
2065
+ optionalLineSpaces$2,
1983
2066
  bodyLineContent,
1984
- lineSpaces$1.clone("line-spaces", true),
2067
+ optionalLineSpaces$2,
1985
2068
  ]);
1986
2069
  const body = new Repeat("body", bodyLine, { divider: newLine$1, min: 0 });
1987
2070
 
1988
- const optionalSpaces = allSpaces.clone("optional-spaces", true);
1989
- const optionalLineSpaces = lineSpaces$1.clone("options-line-spaces", true);
2071
+ const optionalSpaces$1 = new Optional("optional-spaces", allSpaces);
2072
+ const optionalLineSpaces$1 = new Optional("options-line-spaces", lineSpaces$1);
1990
2073
  const importNameDivider = new Regex("import-name-divider", "(\\s+)?,(\\s+)?");
2074
+ importNameDivider.setTokens([", "]);
2075
+ const name = new Regex("import-name", "[^}\\s,]+");
2076
+ name.setTokens(["[IMPORT_NAME]"]);
1991
2077
  const importKeyword = new Literal("import", "import");
1992
2078
  const useParamsKeyword = new Literal("use-params", "use params");
1993
2079
  const asKeyword = new Literal("as", "as");
1994
2080
  const fromKeyword = new Literal("from", "from");
1995
2081
  const openBracket = new Literal("open-bracket", "{");
1996
2082
  const closeBracket = new Literal("close-bracket", "}");
1997
- const name = new Regex("import-name", "[^}\\s,]+");
1998
2083
  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 });
2084
+ const importAlias = new Sequence("import-alias", [name, lineSpaces$1, asKeyword, lineSpaces$1, importNameAlias]);
2085
+ const importedNames = new Repeat("imported-names", new Options("import-names", [importAlias, name]), { divider: importNameDivider });
2001
2086
  const paramName = name.clone("param-name");
2002
2087
  const paramNames = new Repeat("param-names", paramName, { divider: importNameDivider });
2003
2088
  const resource = literal.clone("resource");
2004
- const useParams = new And("import-params", [
2089
+ const useParams = new Sequence("import-params", [
2005
2090
  useParamsKeyword,
2006
- optionalLineSpaces,
2091
+ optionalLineSpaces$1,
2007
2092
  openBracket,
2008
- optionalSpaces,
2093
+ optionalSpaces$1,
2009
2094
  paramNames,
2010
- optionalSpaces,
2095
+ optionalSpaces$1,
2011
2096
  closeBracket
2012
2097
  ]);
2013
2098
  const withParamsKeyword = new Literal("with-params", "with params");
2014
- const withParamsStatement = new And("with-params-statement", [
2099
+ const withParamsStatement = new Optional("optional-with-params-statement", new Sequence("with-params-statement", [
2015
2100
  withParamsKeyword,
2016
- optionalLineSpaces,
2101
+ optionalLineSpaces$1,
2017
2102
  openBracket,
2018
- optionalSpaces,
2103
+ optionalSpaces$1,
2019
2104
  body.clone("with-params-body"),
2020
- optionalSpaces,
2105
+ optionalSpaces$1,
2021
2106
  closeBracket
2022
- ], true);
2023
- const importFromStatement = new And("import-from", [
2107
+ ]));
2108
+ const importFromStatement = new Sequence("import-from", [
2024
2109
  importKeyword,
2025
- optionalLineSpaces,
2110
+ optionalLineSpaces$1,
2026
2111
  openBracket,
2027
- optionalSpaces,
2112
+ optionalSpaces$1,
2028
2113
  importedNames,
2029
- optionalSpaces,
2114
+ optionalSpaces$1,
2030
2115
  closeBracket,
2031
- optionalLineSpaces,
2116
+ optionalLineSpaces$1,
2032
2117
  fromKeyword,
2033
- optionalLineSpaces,
2118
+ optionalLineSpaces$1,
2034
2119
  resource,
2035
- optionalLineSpaces,
2120
+ optionalLineSpaces$1,
2036
2121
  withParamsStatement
2037
2122
  ]);
2038
- const importStatement = new Or("import-statement", [
2123
+ const importStatement = new Options("import-statement", [
2039
2124
  useParams,
2040
2125
  importFromStatement
2041
2126
  ]);
@@ -2046,23 +2131,25 @@
2046
2131
  spaces.setTokens([" "]);
2047
2132
  tabs.setTokens(["\t"]);
2048
2133
  newLine.setTokens(["\n"]);
2049
- const lineSpaces = new Repeat("line-spaces", new Or("line-space", [tabs, spaces]));
2050
- const headLineContent = new Or("head-line-content", [
2134
+ const lineSpaces = new Repeat("line-spaces", new Options("line-space", [tabs, spaces]));
2135
+ const optionalLineSpaces = new Optional("optional-line-spaces", lineSpaces);
2136
+ const headLineContent = new Options("head-line-content", [
2051
2137
  comment,
2052
2138
  importStatement
2053
2139
  ]);
2054
- const headLine = new And("head-line-content", [
2055
- lineSpaces.clone("line-spaces", true),
2140
+ const headLine = new Sequence("head-line-content", [
2141
+ optionalLineSpaces,
2056
2142
  headLineContent,
2057
- lineSpaces.clone("line-spaces", true),
2143
+ optionalLineSpaces,
2058
2144
  ]);
2059
- const head = new Repeat("head", headLine, { divider: newLine, min: 0 });
2060
- const grammar = new And("grammar", [
2061
- allSpaces,
2145
+ const head = new Optional("optional-head", new Repeat("head", headLine, { divider: newLine }));
2146
+ const optionalSpaces = new Optional("optional-spaces", allSpaces);
2147
+ const grammar = new Sequence("grammar", [
2148
+ optionalSpaces,
2062
2149
  head,
2063
- allSpaces,
2150
+ optionalSpaces,
2064
2151
  body,
2065
- allSpaces
2152
+ optionalSpaces
2066
2153
  ]);
2067
2154
 
2068
2155
  let idIndex = 0;
@@ -2093,7 +2180,7 @@
2093
2180
  this._type = "not";
2094
2181
  this._name = name;
2095
2182
  this._parent = null;
2096
- this._children = [pattern.clone(pattern.name, false)];
2183
+ this._children = [pattern.clone()];
2097
2184
  this._children[0].parent = this;
2098
2185
  }
2099
2186
  test(text) {
@@ -2381,8 +2468,8 @@
2381
2468
  const patternNodes = {
2382
2469
  "literal": true,
2383
2470
  "regex-literal": true,
2384
- "or-literal": true,
2385
- "and-literal": true,
2471
+ "options-literal": true,
2472
+ "sequence-literal": true,
2386
2473
  "repeat-literal": true,
2387
2474
  "alias-literal": true,
2388
2475
  "configurable-anonymous-pattern": true
@@ -2485,12 +2572,12 @@
2485
2572
  this._saveRegex(n);
2486
2573
  break;
2487
2574
  }
2488
- case "or-literal": {
2489
- this._saveOr(n);
2575
+ case "options-literal": {
2576
+ this._saveOptions(n);
2490
2577
  break;
2491
2578
  }
2492
- case "and-literal": {
2493
- this._saveAnd(n);
2579
+ case "sequence-literal": {
2580
+ this._saveSequence(n);
2494
2581
  break;
2495
2582
  }
2496
2583
  case "repeat-literal": {
@@ -2545,18 +2632,18 @@
2545
2632
  const value = node.value.slice(1, node.value.length - 1);
2546
2633
  return new Regex(name, value);
2547
2634
  }
2548
- _saveOr(statementNode) {
2635
+ _saveOptions(statementNode) {
2549
2636
  const nameNode = statementNode.find(n => n.name === "name");
2550
2637
  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);
2638
+ const optionsNode = statementNode.find(n => n.name === "options-literal");
2639
+ const options = this._buildOptions(name, optionsNode);
2640
+ this._parseContext.patternsByName.set(name, options);
2554
2641
  }
2555
- _buildOr(name, node) {
2642
+ _buildOptions(name, node) {
2556
2643
  const patternNodes = node.children.filter(n => n.name !== "default-divider" && n.name !== "greedy-divider");
2557
2644
  const isGreedy = node.find(n => n.name === "greedy-divider") != null;
2558
2645
  const patterns = patternNodes.map(n => this._buildPattern(n));
2559
- const or = new Or(name, patterns, false, isGreedy);
2646
+ const or = new Options(name, patterns, isGreedy);
2560
2647
  return or;
2561
2648
  }
2562
2649
  _buildPattern(node) {
@@ -2575,11 +2662,11 @@
2575
2662
  case "repeat-literal": {
2576
2663
  return this._buildRepeat(name, node);
2577
2664
  }
2578
- case "or-literal": {
2579
- return this._buildOr(name, node);
2665
+ case "options-literal": {
2666
+ return this._buildOptions(name, node);
2580
2667
  }
2581
- case "and-literal": {
2582
- return this._buildAnd(name, node);
2668
+ case "sequence-literal": {
2669
+ return this._buildSequence(name, node);
2583
2670
  }
2584
2671
  case "complex-anonymous-pattern": {
2585
2672
  return this._buildComplexAnonymousPattern(node);
@@ -2587,26 +2674,27 @@
2587
2674
  }
2588
2675
  throw new Error(`Couldn't build node: ${node.name}.`);
2589
2676
  }
2590
- _saveAnd(statementNode) {
2677
+ _saveSequence(statementNode) {
2591
2678
  const nameNode = statementNode.find(n => n.name === "name");
2592
2679
  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);
2680
+ const sequenceNode = statementNode.find(n => n.name === "sequence-literal");
2681
+ const sequence = this._buildSequence(name, sequenceNode);
2682
+ this._parseContext.patternsByName.set(name, sequence);
2596
2683
  }
2597
- _buildAnd(name, node) {
2684
+ _buildSequence(name, node) {
2598
2685
  const patternNodes = node.children.filter(n => n.name !== "and-divider");
2599
2686
  const patterns = patternNodes.map(n => {
2600
2687
  const patternNode = n.children[0].name === "not" ? n.children[1] : n.children[0];
2601
2688
  const isNot = n.find(n => n.name === "not") != null;
2602
2689
  const isOptional = n.find(n => n.name === "is-optional");
2603
- const pattern = this._buildPattern(patternNode).clone(undefined, isOptional == null ? undefined : true);
2690
+ const pattern = this._buildPattern(patternNode);
2691
+ const finalPattern = isOptional ? new Optional(pattern.name, pattern) : pattern;
2604
2692
  if (isNot) {
2605
- return new Not(`not-${pattern.name}`, pattern);
2693
+ return new Not(`not-${finalPattern.name}`, finalPattern);
2606
2694
  }
2607
- return pattern;
2695
+ return finalPattern;
2608
2696
  });
2609
- return new And(name, patterns);
2697
+ return new Sequence(name, patterns);
2610
2698
  }
2611
2699
  _saveRepeat(statementNode) {
2612
2700
  const nameNode = statementNode.find(n => n.name === "name");
@@ -2616,13 +2704,14 @@
2616
2704
  this._parseContext.patternsByName.set(name, repeat);
2617
2705
  }
2618
2706
  _buildRepeat(name, repeatNode) {
2707
+ let isOptional = false;
2619
2708
  const bounds = repeatNode.find(n => n.name === "bounds");
2620
2709
  const exactCount = repeatNode.find(n => n.name === "exact-count");
2621
2710
  const quantifier = repeatNode.find(n => n.name === "quantifier-shorthand");
2622
2711
  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];
2712
+ const patterNode = repeatNode.children[1].type === "spaces" ? repeatNode.children[2] : repeatNode.children[1];
2624
2713
  const pattern = this._buildPattern(patterNode);
2625
- const dividerSectionNode = repeatNode.find(n => n.name === "optional-divider-section");
2714
+ const dividerSectionNode = repeatNode.find(n => n.name === "divider-section");
2626
2715
  const options = {
2627
2716
  min: 1,
2628
2717
  max: Infinity
@@ -2655,18 +2744,17 @@
2655
2744
  options.max = Infinity;
2656
2745
  }
2657
2746
  else {
2658
- options.min = 0;
2659
- options.max = Infinity;
2747
+ isOptional = true;
2660
2748
  }
2661
2749
  }
2662
- return new Repeat(name, pattern.clone(pattern.name), options);
2750
+ return isOptional ? new Optional(name, new Repeat(name, pattern, options)) : new Repeat(name, pattern, options);
2663
2751
  }
2664
2752
  _saveConfigurableAnonymous(node) {
2665
2753
  const nameNode = node.find(n => n.name === "name");
2666
2754
  const name = nameNode.value;
2667
2755
  const anonymousNode = node.find(n => n.name === "complex-anonymous-pattern");
2668
2756
  const isOptional = node.children[1] != null;
2669
- const anonymous = this._buildPattern(anonymousNode).clone(name, isOptional);
2757
+ const anonymous = isOptional ? new Optional(name, this._buildPattern(anonymousNode)) : this._buildPattern(anonymousNode);
2670
2758
  this._parseContext.patternsByName.set(name, anonymous);
2671
2759
  }
2672
2760
  _buildComplexAnonymousPattern(node) {
@@ -2809,7 +2897,6 @@
2809
2897
  return result;
2810
2898
  }
2811
2899
 
2812
- exports.And = And;
2813
2900
  exports.AutoComplete = AutoComplete;
2814
2901
  exports.Cursor = Cursor;
2815
2902
  exports.CursorHistory = CursorHistory;
@@ -2817,11 +2904,13 @@
2817
2904
  exports.Literal = Literal;
2818
2905
  exports.Node = Node;
2819
2906
  exports.Not = Not;
2820
- exports.Or = Or;
2907
+ exports.Optional = Optional;
2908
+ exports.Options = Options;
2821
2909
  exports.ParseError = ParseError;
2822
2910
  exports.Reference = Reference;
2823
2911
  exports.Regex = Regex;
2824
2912
  exports.Repeat = Repeat;
2913
+ exports.Sequence = Sequence;
2825
2914
  exports.arePatternsEqual = arePatternsEqual;
2826
2915
  exports.grammar = grammar;
2827
2916
  exports.patterns = patterns;