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