ohm-js 17.2.1 → 17.4.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.
Files changed (52) hide show
  1. package/dist/ohm-extras.cjs +568 -471
  2. package/dist/ohm-extras.js +568 -471
  3. package/dist/ohm.cjs +511 -464
  4. package/dist/ohm.cjs.map +1 -1
  5. package/dist/ohm.js +512 -465
  6. package/dist/ohm.min.js +1 -1
  7. package/extras/VisitorFamily.js +9 -9
  8. package/extras/index.d.ts +7 -11
  9. package/extras/index.mjs +1 -0
  10. package/extras/recoverSourceOrder.js +48 -0
  11. package/extras/semantics-toAST.js +1 -1
  12. package/index.d.ts +24 -4
  13. package/package.json +4 -4
  14. package/src/Builder.js +8 -8
  15. package/src/CaseInsensitiveTerminal.js +3 -3
  16. package/src/Grammar.js +69 -70
  17. package/src/GrammarDecl.js +5 -5
  18. package/src/IndentationSensitive.js +6 -6
  19. package/src/InputStream.js +3 -0
  20. package/src/Interval.js +19 -7
  21. package/src/MatchResult.js +14 -16
  22. package/src/MatchState.js +17 -17
  23. package/src/PosInfo.js +7 -7
  24. package/src/Semantics.js +43 -43
  25. package/src/Trace.js +19 -19
  26. package/src/buildGrammar.js +4 -4
  27. package/src/common.js +9 -9
  28. package/src/errors.js +36 -36
  29. package/src/main.js +3 -3
  30. package/src/nodes.js +4 -4
  31. package/src/ohm-cmd.js +5 -5
  32. package/src/pexprs-allowsSkippingPrecedingSpace.js +2 -2
  33. package/src/pexprs-assertAllApplicationsAreValid.js +11 -11
  34. package/src/pexprs-assertChoicesHaveUniformArity.js +9 -9
  35. package/src/pexprs-assertIteratedExprsAreNotNullable.js +7 -7
  36. package/src/pexprs-eval.js +40 -36
  37. package/src/pexprs-getArity.js +6 -6
  38. package/src/pexprs-introduceParams.js +5 -5
  39. package/src/pexprs-isNullable.js +9 -9
  40. package/src/pexprs-main.js +12 -4
  41. package/src/pexprs-outputRecipe.js +15 -15
  42. package/src/pexprs-substituteParams.js +6 -6
  43. package/src/pexprs-toArgumentNameList.js +20 -20
  44. package/src/pexprs-toDisplayString.js +5 -5
  45. package/src/pexprs-toFailure.js +12 -12
  46. package/src/pexprs-toString.js +20 -20
  47. package/src/semanticsDeferredInit.js +8 -8
  48. package/src/unicode.js +54 -0
  49. package/src/util.js +3 -3
  50. package/src/version.js +1 -1
  51. package/dist/ohm-grammar.js.new +0 -0
  52. package/src/UnicodeCategories.js +0 -30
@@ -10,14 +10,14 @@ Object.defineProperty(exports, '__esModule', { value: true });
10
10
 
11
11
  function abstract(optMethodName) {
12
12
  const methodName = optMethodName || '';
13
- return function() {
13
+ return function () {
14
14
  throw new Error(
15
- 'this method ' +
15
+ 'this method ' +
16
16
  methodName +
17
17
  ' is abstract! ' +
18
18
  '(it has no implementation in class ' +
19
19
  this.constructor.name +
20
- ')',
20
+ ')'
21
21
  );
22
22
  };
23
23
  }
@@ -110,11 +110,11 @@ function StringBuffer() {
110
110
  this.strings = [];
111
111
  }
112
112
 
113
- StringBuffer.prototype.append = function(str) {
113
+ StringBuffer.prototype.append = function (str) {
114
114
  this.strings.push(str);
115
115
  };
116
116
 
117
- StringBuffer.prototype.contents = function() {
117
+ StringBuffer.prototype.contents = function () {
118
118
  return this.strings.join('');
119
119
  };
120
120
 
@@ -138,9 +138,9 @@ function unescapeCodePoint(s) {
138
138
  case 'x':
139
139
  return escapeUnicode(s.slice(2, 4));
140
140
  case 'u':
141
- return s.charAt(2) === '{' ?
142
- escapeUnicode(s.slice(3, -1)) :
143
- escapeUnicode(s.slice(2, 6));
141
+ return s.charAt(2) === '{'
142
+ ? escapeUnicode(s.slice(3, -1))
143
+ : escapeUnicode(s.slice(2, 6));
144
144
  default:
145
145
  return s.charAt(1);
146
146
  }
@@ -166,7 +166,7 @@ function unexpectedObjToString(obj) {
166
166
  typeName = typeof obj;
167
167
  }
168
168
  return typeName + ': ' + JSON.stringify(String(obj));
169
- } catch (e) {
169
+ } catch {
170
170
  return baseToString;
171
171
  }
172
172
  }
@@ -332,9 +332,9 @@ function getLineAndColumn(str, offset) {
332
332
  // Get the next line.
333
333
  const nextLineEndOffset = str.indexOf('\n', lineEndOffset + 1);
334
334
  nextLine =
335
- nextLineEndOffset === -1 ?
336
- str.slice(lineEndOffset) :
337
- str.slice(lineEndOffset, nextLineEndOffset);
335
+ nextLineEndOffset === -1
336
+ ? str.slice(lineEndOffset)
337
+ : str.slice(lineEndOffset, nextLineEndOffset);
338
338
  // Strip leading and trailing EOL char(s).
339
339
  nextLine = nextLine.replace(/^\r?\n/, '').replace(/\r$/, '');
340
340
  }
@@ -446,11 +446,11 @@ class VisitorFamily {
446
446
  this._shapes = config.shapes;
447
447
  this._getTag = config.getTag;
448
448
 
449
- this.Adapter = function(thing, family) {
449
+ this.Adapter = function (thing, family) {
450
450
  this._adaptee = thing;
451
451
  this._family = family;
452
452
  };
453
- this.Adapter.prototype.valueOf = function() {
453
+ this.Adapter.prototype.valueOf = function () {
454
454
  throw new Error('heeey!');
455
455
  };
456
456
  this.operations = {};
@@ -479,15 +479,15 @@ class VisitorFamily {
479
479
  assert(k in this._getChildren, "Unrecognized action name '" + k + "'");
480
480
  const action = dict[k];
481
481
  assert(
482
- typeof action === 'function',
483
- "Key '" + k + "': expected function, got " + action,
482
+ typeof action === 'function',
483
+ "Key '" + k + "': expected function, got " + action
484
484
  );
485
485
  if (k in this._arities) {
486
486
  const expected = this._arities[k];
487
487
  const actual = dict[k].length;
488
488
  assert(
489
- actual === expected,
490
- "Action '" + k + "' has the wrong arity: expected " + expected + ', got ' + actual,
489
+ actual === expected,
490
+ "Action '" + k + "' has the wrong arity: expected " + expected + ', got ' + actual
491
491
  );
492
492
  }
493
493
  });
@@ -504,7 +504,7 @@ class VisitorFamily {
504
504
  };
505
505
 
506
506
  const family = this;
507
- this.Adapter.prototype[name] = function(...args) {
507
+ this.Adapter.prototype[name] = function (...args) {
508
508
  const tag = family._getTag(this._adaptee);
509
509
  assert(tag in family._getChildren, "getTag returned unrecognized tag '" + tag + "'");
510
510
  assert(tag in actions, "No action for '" + tag + "' in operation '" + name + "'");
@@ -519,8 +519,8 @@ class VisitorFamily {
519
519
  const oldArgs = this.args;
520
520
  this.args = argsObj;
521
521
  const ans = actions[tag].apply(
522
- this,
523
- family._getChildren[tag](this._adaptee, family._wrap),
522
+ this,
523
+ family._getChildren[tag](this._adaptee, family._wrap)
524
524
  );
525
525
  this.args = oldArgs;
526
526
  return ans;
@@ -586,7 +586,7 @@ const defaultOperation = {
586
586
  const node = {
587
587
  type: ctorName,
588
588
  };
589
- // eslint-disable-next-line guard-for-in
589
+
590
590
  for (const prop in propMap) {
591
591
  const mappedProp = mapping[ctorName] && mapping[ctorName][prop];
592
592
  if (typeof mappedProp === 'number') {
@@ -661,36 +661,60 @@ function semanticsForToAST(g) {
661
661
  return g.createSemantics().addOperation('toAST(mapping)', defaultOperation);
662
662
  }
663
663
 
664
- // These are just categories that are used in ES5/ES2015.
665
- // The full list of Unicode categories is here: http://www.fileformat.info/info/unicode/category/index.htm.
666
- const UnicodeCategories = {
667
- // Letters
668
- Lu: /\p{Lu}/u,
669
- Ll: /\p{Ll}/u,
670
- Lt: /\p{Lt}/u,
671
- Lm: /\p{Lm}/u,
672
- Lo: /\p{Lo}/u,
673
-
674
- // Numbers
675
- Nl: /\p{Nl}/u,
676
- Nd: /\p{Nd}/u,
677
-
678
- // Marks
679
- Mn: /\p{Mn}/u,
680
- Mc: /\p{Mc}/u,
681
-
682
- // Punctuation, Connector
683
- Pc: /\p{Pc}/u,
684
-
685
- // Separator, Space
686
- Zs: /\p{Zs}/u,
687
-
688
- // These two are not real Unicode categories, but our useful for Ohm.
689
- // L is a combination of all the letter categories.
690
- // Ltmo is a combination of Lt, Lm, and Lo.
691
- L: /\p{Letter}/u,
692
- Ltmo: /\p{Lt}|\p{Lm}|\p{Lo}/u,
693
- };
664
+ // The full list of categories from:
665
+ // https://www.unicode.org/Public/UCD/latest/ucd/extracted/DerivedGeneralCategory.txt.
666
+
667
+ const toRegExp = val => new RegExp(String.raw`\p{${val}}`, 'u');
668
+
669
+ /*
670
+ grep -v '^#' DerivedGeneralCategory.txt \
671
+ | cut -d';' -f2 \
672
+ | awk 'NF{print $1}' \
673
+ | sort -u \
674
+ | awk '{printf "\x27%s\x27,\n",$1}'
675
+ */
676
+
677
+ const UnicodeCategories = Object.fromEntries(
678
+ [
679
+ 'Cc',
680
+ 'Cf',
681
+ 'Cn',
682
+ 'Co',
683
+ 'Cs',
684
+ 'Ll',
685
+ 'Lm',
686
+ 'Lo',
687
+ 'Lt',
688
+ 'Lu',
689
+ 'Mc',
690
+ 'Me',
691
+ 'Mn',
692
+ 'Nd',
693
+ 'Nl',
694
+ 'No',
695
+ 'Pc',
696
+ 'Pd',
697
+ 'Pe',
698
+ 'Pf',
699
+ 'Pi',
700
+ 'Po',
701
+ 'Ps',
702
+ 'Sc',
703
+ 'Sk',
704
+ 'Sm',
705
+ 'So',
706
+ 'Zl',
707
+ 'Zp',
708
+ 'Zs',
709
+ ].map(cat => [cat, toRegExp(cat)])
710
+ );
711
+ UnicodeCategories['Ltmo'] = /\p{Lt}|\p{Lm}|\p{Lo}/u;
712
+
713
+ // We only support a few of these for now, but could add more later.
714
+ // See https://www.unicode.org/Public/UCD/latest/ucd/PropertyAliases.txt
715
+ const UnicodeBinaryProperties = Object.fromEntries(
716
+ ['XID_Start', 'XID_Continue', 'White_Space'].map(prop => [prop, toRegExp(prop)])
717
+ );
694
718
 
695
719
  // --------------------------------------------------------------------
696
720
  // Private stuff
@@ -871,10 +895,18 @@ class Apply extends PExpr {
871
895
  // Unicode character
872
896
 
873
897
  class UnicodeChar extends PExpr {
874
- constructor(category) {
898
+ constructor(categoryOrProp) {
875
899
  super();
876
- this.category = category;
877
- this.pattern = UnicodeCategories[category];
900
+ this.categoryOrProp = categoryOrProp;
901
+ if (categoryOrProp in UnicodeCategories) {
902
+ this.pattern = UnicodeCategories[categoryOrProp];
903
+ } else if (categoryOrProp in UnicodeBinaryProperties) {
904
+ this.pattern = UnicodeBinaryProperties[categoryOrProp];
905
+ } else {
906
+ throw new Error(
907
+ `Invalid Unicode category or property name: ${JSON.stringify(categoryOrProp)}`
908
+ );
909
+ }
878
910
  }
879
911
  }
880
912
 
@@ -925,9 +957,9 @@ function grammarSyntaxError(matchFailure) {
925
957
  // Undeclared grammar
926
958
 
927
959
  function undeclaredGrammar(grammarName, namespace, interval) {
928
- const message = namespace ?
929
- `Grammar ${grammarName} is not declared in namespace '${namespace}'` :
930
- 'Undeclared grammar ' + grammarName;
960
+ const message = namespace
961
+ ? `Grammar ${grammarName} is not declared in namespace '${namespace}'`
962
+ : 'Undeclared grammar ' + grammarName;
931
963
  return createError(message, interval);
932
964
  }
933
965
 
@@ -947,8 +979,8 @@ function grammarDoesNotSupportIncrementalParsing(grammar) {
947
979
 
948
980
  function undeclaredRule(ruleName, grammarName, optInterval) {
949
981
  return createError(
950
- 'Rule ' + ruleName + ' is not declared in grammar ' + grammarName,
951
- optInterval,
982
+ 'Rule ' + ruleName + ' is not declared in grammar ' + grammarName,
983
+ optInterval
952
984
  );
953
985
  }
954
986
 
@@ -956,8 +988,8 @@ function undeclaredRule(ruleName, grammarName, optInterval) {
956
988
 
957
989
  function cannotOverrideUndeclaredRule(ruleName, grammarName, optSource) {
958
990
  return createError(
959
- 'Cannot override rule ' + ruleName + ' because it is not declared in ' + grammarName,
960
- optSource,
991
+ 'Cannot override rule ' + ruleName + ' because it is not declared in ' + grammarName,
992
+ optSource
961
993
  );
962
994
  }
963
995
 
@@ -965,8 +997,8 @@ function cannotOverrideUndeclaredRule(ruleName, grammarName, optSource) {
965
997
 
966
998
  function cannotExtendUndeclaredRule(ruleName, grammarName, optSource) {
967
999
  return createError(
968
- 'Cannot extend rule ' + ruleName + ' because it is not declared in ' + grammarName,
969
- optSource,
1000
+ 'Cannot extend rule ' + ruleName + ' because it is not declared in ' + grammarName,
1001
+ optSource
970
1002
  );
971
1003
  }
972
1004
 
@@ -985,14 +1017,14 @@ function duplicateRuleDeclaration(ruleName, grammarName, declGrammarName, optSou
985
1017
 
986
1018
  function wrongNumberOfParameters(ruleName, expected, actual, source) {
987
1019
  return createError(
988
- 'Wrong number of parameters for rule ' +
1020
+ 'Wrong number of parameters for rule ' +
989
1021
  ruleName +
990
1022
  ' (expected ' +
991
1023
  expected +
992
1024
  ', got ' +
993
1025
  actual +
994
1026
  ')',
995
- source,
1027
+ source
996
1028
  );
997
1029
  }
998
1030
 
@@ -1000,14 +1032,14 @@ function wrongNumberOfParameters(ruleName, expected, actual, source) {
1000
1032
 
1001
1033
  function wrongNumberOfArguments(ruleName, expected, actual, expr) {
1002
1034
  return createError(
1003
- 'Wrong number of arguments for rule ' +
1035
+ 'Wrong number of arguments for rule ' +
1004
1036
  ruleName +
1005
1037
  ' (expected ' +
1006
1038
  expected +
1007
1039
  ', got ' +
1008
1040
  actual +
1009
1041
  ')',
1010
- expr,
1042
+ expr
1011
1043
  );
1012
1044
  }
1013
1045
 
@@ -1015,8 +1047,8 @@ function wrongNumberOfArguments(ruleName, expected, actual, expr) {
1015
1047
 
1016
1048
  function duplicateParameterNames(ruleName, duplicates, source) {
1017
1049
  return createError(
1018
- 'Duplicate parameter names in rule ' + ruleName + ': ' + duplicates.join(', '),
1019
- source,
1050
+ 'Duplicate parameter names in rule ' + ruleName + ': ' + duplicates.join(', '),
1051
+ source
1020
1052
  );
1021
1053
  }
1022
1054
 
@@ -1024,14 +1056,14 @@ function duplicateParameterNames(ruleName, duplicates, source) {
1024
1056
 
1025
1057
  function invalidParameter(ruleName, expr) {
1026
1058
  return createError(
1027
- 'Invalid parameter to rule ' +
1059
+ 'Invalid parameter to rule ' +
1028
1060
  ruleName +
1029
1061
  ': ' +
1030
1062
  expr +
1031
1063
  ' has arity ' +
1032
1064
  expr.getArity() +
1033
1065
  ', but parameter expressions must have arity 1',
1034
- expr.source,
1066
+ expr.source
1035
1067
  );
1036
1068
  }
1037
1069
 
@@ -1043,8 +1075,8 @@ const syntacticVsLexicalNote =
1043
1075
 
1044
1076
  function applicationOfSyntacticRuleFromLexicalContext(ruleName, applyExpr) {
1045
1077
  return createError(
1046
- 'Cannot apply syntactic rule ' + ruleName + ' from here (inside a lexical context)',
1047
- applyExpr.source,
1078
+ 'Cannot apply syntactic rule ' + ruleName + ' from here (inside a lexical context)',
1079
+ applyExpr.source
1048
1080
  );
1049
1081
  }
1050
1082
 
@@ -1053,9 +1085,9 @@ function applicationOfSyntacticRuleFromLexicalContext(ruleName, applyExpr) {
1053
1085
  function applySyntacticWithLexicalRuleApplication(applyExpr) {
1054
1086
  const {ruleName} = applyExpr;
1055
1087
  return createError(
1056
- `applySyntactic is for syntactic rules, but '${ruleName}' is a lexical rule. ` +
1088
+ `applySyntactic is for syntactic rules, but '${ruleName}' is a lexical rule. ` +
1057
1089
  syntacticVsLexicalNote,
1058
- applyExpr.source,
1090
+ applyExpr.source
1059
1091
  );
1060
1092
  }
1061
1093
 
@@ -1063,8 +1095,8 @@ function applySyntacticWithLexicalRuleApplication(applyExpr) {
1063
1095
 
1064
1096
  function unnecessaryExperimentalApplySyntactic(applyExpr) {
1065
1097
  return createError(
1066
- 'applySyntactic is not required here (in a syntactic context)',
1067
- applyExpr.source,
1098
+ 'applySyntactic is not required here (in a syntactic context)',
1099
+ applyExpr.source
1068
1100
  );
1069
1101
  }
1070
1102
 
@@ -1090,8 +1122,8 @@ function invalidCodePoint(applyWrapper) {
1090
1122
  const digitIntervals = applyWrapper.children.slice(1, -1).map(d => d.source);
1091
1123
  const fullInterval = digitIntervals[0].coverageWith(...digitIntervals.slice(1));
1092
1124
  return createError(
1093
- `U+${fullInterval.contents} is not a valid Unicode code point`,
1094
- fullInterval,
1125
+ `U+${fullInterval.contents} is not a valid Unicode code point`,
1126
+ fullInterval
1095
1127
  );
1096
1128
  }
1097
1129
 
@@ -1109,8 +1141,8 @@ function kleeneExprHasNullableOperand(kleeneExpr, applicationStack) {
1109
1141
  "' (possible infinite loop)";
1110
1142
  if (applicationStack.length > 0) {
1111
1143
  const stackTrace = applicationStack
1112
- .map(app => new Apply(app.ruleName, app.args))
1113
- .join('\n');
1144
+ .map(app => new Apply(app.ruleName, app.args))
1145
+ .join('\n');
1114
1146
  message += '\nApplication stack (most recent application last):\n' + stackTrace;
1115
1147
  }
1116
1148
  return createError(message, kleeneExpr.expr.source);
@@ -1120,7 +1152,7 @@ function kleeneExprHasNullableOperand(kleeneExpr, applicationStack) {
1120
1152
 
1121
1153
  function inconsistentArity(ruleName, expected, actual, expr) {
1122
1154
  return createError(
1123
- 'Rule ' +
1155
+ 'Rule ' +
1124
1156
  ruleName +
1125
1157
  ' involves an alternation which has inconsistent arity ' +
1126
1158
  '(expected ' +
@@ -1128,7 +1160,7 @@ function inconsistentArity(ruleName, expected, actual, expr) {
1128
1160
  ', got ' +
1129
1161
  actual +
1130
1162
  ')',
1131
- expr.source,
1163
+ expr.source
1132
1164
  );
1133
1165
  }
1134
1166
 
@@ -1143,12 +1175,12 @@ function multipleErrors(errors) {
1143
1175
 
1144
1176
  function missingSemanticAction(ctorName, name, type, stack) {
1145
1177
  let stackTrace = stack
1146
- .slice(0, -1)
1147
- .map(info => {
1148
- const ans = ' ' + info[0].name + ' > ' + info[1];
1149
- return info.length === 3 ? ans + " for '" + info[2] + "'" : ans;
1150
- })
1151
- .join('\n');
1178
+ .slice(0, -1)
1179
+ .map(info => {
1180
+ const ans = ' ' + info[0].name + ' > ' + info[1];
1181
+ return info.length === 3 ? ans + " for '" + info[2] + "'" : ans;
1182
+ })
1183
+ .join('\n');
1152
1184
  stackTrace += '\n ' + name + ' > ' + ctorName;
1153
1185
 
1154
1186
  let moreInfo = '';
@@ -1185,11 +1217,23 @@ function throwErrors(errors) {
1185
1217
 
1186
1218
  class Interval {
1187
1219
  constructor(sourceString, startIdx, endIdx) {
1188
- this.sourceString = sourceString;
1220
+ // Store the full source in a non-enumerable property, so that when
1221
+ // grammars and other objects are printed in the REPL, it's not
1222
+ // cluttered with multiple copies of the same long string.
1223
+ Object.defineProperty(this, '_sourceString', {
1224
+ value: sourceString,
1225
+ configurable: false,
1226
+ enumerable: false,
1227
+ writable: false,
1228
+ });
1189
1229
  this.startIdx = startIdx;
1190
1230
  this.endIdx = endIdx;
1191
1231
  }
1192
1232
 
1233
+ get sourceString() {
1234
+ return this._sourceString;
1235
+ }
1236
+
1193
1237
  get contents() {
1194
1238
  if (this._contents === undefined) {
1195
1239
  this._contents = this.sourceString.slice(this.startIdx, this.endIdx);
@@ -1255,13 +1299,13 @@ class Interval {
1255
1299
  throw intervalSourcesDontMatch();
1256
1300
  }
1257
1301
  assert(
1258
- this.startIdx >= that.startIdx && this.endIdx <= that.endIdx,
1259
- 'other interval does not cover this one',
1302
+ this.startIdx >= that.startIdx && this.endIdx <= that.endIdx,
1303
+ 'other interval does not cover this one'
1260
1304
  );
1261
1305
  return new Interval(
1262
- this.sourceString,
1263
- this.startIdx - that.startIdx,
1264
- this.endIdx - that.startIdx,
1306
+ this.sourceString,
1307
+ this.startIdx - that.startIdx,
1308
+ this.endIdx - that.startIdx
1265
1309
  );
1266
1310
  }
1267
1311
 
@@ -1280,7 +1324,7 @@ class Interval {
1280
1324
  }
1281
1325
  }
1282
1326
 
1283
- Interval.coverage = function(firstInterval, ...intervals) {
1327
+ Interval.coverage = function (firstInterval, ...intervals) {
1284
1328
  let {startIdx, endIdx} = firstInterval;
1285
1329
  for (const interval of intervals) {
1286
1330
  if (interval.sourceString !== firstInterval.sourceString) {
@@ -1294,6 +1338,7 @@ Interval.coverage = function(firstInterval, ...intervals) {
1294
1338
  };
1295
1339
 
1296
1340
  const MAX_CHAR_CODE = 0xffff;
1341
+ const MAX_CODE_POINT = 0x10ffff;
1297
1342
 
1298
1343
  class InputStream {
1299
1344
  constructor(source) {
@@ -1339,6 +1384,8 @@ class InputStream {
1339
1384
 
1340
1385
  This is intended to be a locale-invariant comparison, which means it may not obey
1341
1386
  locale-specific expectations (e.g. "i" => "İ").
1387
+
1388
+ See also https://unicode.org/faq/casemap_charprop.html#casemap
1342
1389
  */
1343
1390
  for (idx = 0; idx < s.length; idx++) {
1344
1391
  const actual = this.next();
@@ -1373,13 +1420,13 @@ class InputStream {
1373
1420
 
1374
1421
  class MatchResult {
1375
1422
  constructor(
1376
- matcher,
1377
- input,
1378
- startExpr,
1379
- cst,
1380
- cstOffset,
1381
- rightmostFailurePosition,
1382
- optRecordedFailures,
1423
+ matcher,
1424
+ input,
1425
+ startExpr,
1426
+ cst,
1427
+ cstOffset,
1428
+ rightmostFailurePosition,
1429
+ optRecordedFailures
1383
1430
  ) {
1384
1431
  this.matcher = matcher;
1385
1432
  this.input = input;
@@ -1390,22 +1437,20 @@ class MatchResult {
1390
1437
  this._rightmostFailures = optRecordedFailures;
1391
1438
 
1392
1439
  if (this.failed()) {
1393
- /* eslint-disable no-invalid-this */
1394
- defineLazyProperty(this, 'message', function() {
1440
+ defineLazyProperty(this, 'message', function () {
1395
1441
  const detail = 'Expected ' + this.getExpectedText();
1396
1442
  return (
1397
1443
  getLineAndColumnMessage(this.input, this.getRightmostFailurePosition()) + detail
1398
1444
  );
1399
1445
  });
1400
- defineLazyProperty(this, 'shortMessage', function() {
1446
+ defineLazyProperty(this, 'shortMessage', function () {
1401
1447
  const detail = 'expected ' + this.getExpectedText();
1402
1448
  const errorInfo = getLineAndColumn(
1403
- this.input,
1404
- this.getRightmostFailurePosition(),
1449
+ this.input,
1450
+ this.getRightmostFailurePosition()
1405
1451
  );
1406
1452
  return 'Line ' + errorInfo.lineNum + ', col ' + errorInfo.colNum + ': ' + detail;
1407
1453
  });
1408
- /* eslint-enable no-invalid-this */
1409
1454
  }
1410
1455
  }
1411
1456
 
@@ -1434,9 +1479,9 @@ class MatchResult {
1434
1479
  }
1435
1480
 
1436
1481
  toString() {
1437
- return this.succeeded() ?
1438
- '[match succeeded]' :
1439
- '[match failed at position ' + this.getRightmostFailurePosition() + ']';
1482
+ return this.succeeded()
1483
+ ? '[match succeeded]'
1484
+ : '[match failed at position ' + this.getRightmostFailurePosition() + ']';
1440
1485
  }
1441
1486
 
1442
1487
  // Return a string summarizing the expected contents of the input stream when
@@ -1502,14 +1547,14 @@ class PosInfo {
1502
1547
  const indexOfFirstInvolvedRule =
1503
1548
  applicationMemoKeyStack.indexOf(headApplication.toMemoKey()) + 1;
1504
1549
  const involvedApplicationMemoKeys = applicationMemoKeyStack.slice(
1505
- indexOfFirstInvolvedRule,
1550
+ indexOfFirstInvolvedRule
1506
1551
  );
1507
1552
 
1508
- memoRec.isInvolved = function(applicationMemoKey) {
1553
+ memoRec.isInvolved = function (applicationMemoKey) {
1509
1554
  return involvedApplicationMemoKeys.indexOf(applicationMemoKey) >= 0;
1510
1555
  };
1511
1556
 
1512
- memoRec.updateInvolvedApplicationMemoKeys = function() {
1557
+ memoRec.updateInvolvedApplicationMemoKeys = function () {
1513
1558
  for (let idx = indexOfFirstInvolvedRule; idx < applicationMemoKeyStack.length; idx++) {
1514
1559
  const applicationMemoKey = applicationMemoKeyStack[idx];
1515
1560
  if (!this.isInvolved(applicationMemoKey)) {
@@ -1543,8 +1588,8 @@ class PosInfo {
1543
1588
  this.memo[memoKey] = memoRec;
1544
1589
  this.maxExaminedLength = Math.max(this.maxExaminedLength, memoRec.examinedLength);
1545
1590
  this.maxRightmostFailureOffset = Math.max(
1546
- this.maxRightmostFailureOffset,
1547
- memoRec.rightmostFailureOffset,
1591
+ this.maxRightmostFailureOffset,
1592
+ memoRec.rightmostFailureOffset
1548
1593
  );
1549
1594
  return memoRec;
1550
1595
  }
@@ -1566,8 +1611,8 @@ class PosInfo {
1566
1611
  } else {
1567
1612
  this.maxExaminedLength = Math.max(this.maxExaminedLength, memoRec.examinedLength);
1568
1613
  this.maxRightmostFailureOffset = Math.max(
1569
- this.maxRightmostFailureOffset,
1570
- memoRec.rightmostFailureOffset,
1614
+ this.maxRightmostFailureOffset,
1615
+ memoRec.rightmostFailureOffset
1571
1616
  );
1572
1617
  }
1573
1618
  });
@@ -1616,10 +1661,10 @@ function asEscapedString(obj) {
1616
1661
  if (typeof obj === 'string') {
1617
1662
  // Replace non-printable characters with visible symbols.
1618
1663
  return obj
1619
- .replace(/ /g, DOT_OPERATOR)
1620
- .replace(/\t/g, SYMBOL_FOR_HORIZONTAL_TABULATION)
1621
- .replace(/\n/g, SYMBOL_FOR_LINE_FEED)
1622
- .replace(/\r/g, SYMBOL_FOR_CARRIAGE_RETURN);
1664
+ .replace(/ /g, DOT_OPERATOR)
1665
+ .replace(/\t/g, SYMBOL_FOR_HORIZONTAL_TABULATION)
1666
+ .replace(/\n/g, SYMBOL_FOR_LINE_FEED)
1667
+ .replace(/\r/g, SYMBOL_FOR_CARRIAGE_RETURN);
1623
1668
  }
1624
1669
  return String(obj);
1625
1670
  }
@@ -1650,13 +1695,13 @@ class Trace {
1650
1695
 
1651
1696
  cloneWithExpr(expr) {
1652
1697
  const ans = new Trace(
1653
- this.input,
1654
- this.pos,
1655
- this.pos2,
1656
- expr,
1657
- this.succeeded,
1658
- this.bindings,
1659
- this.children,
1698
+ this.input,
1699
+ this.pos,
1700
+ this.pos2,
1701
+ expr,
1702
+ this.succeeded,
1703
+ this.bindings,
1704
+ this.children
1660
1705
  );
1661
1706
 
1662
1707
  ans.isHeadOfLeftRecursion = this.isHeadOfLeftRecursion;
@@ -1671,13 +1716,13 @@ class Trace {
1671
1716
  // Record the trace information for the terminating condition of the LR loop.
1672
1717
  recordLRTermination(ruleBodyTrace, value) {
1673
1718
  this.terminatingLREntry = new Trace(
1674
- this.input,
1675
- this.pos,
1676
- this.pos2,
1677
- this.expr,
1678
- false,
1679
- [value],
1680
- [ruleBodyTrace],
1719
+ this.input,
1720
+ this.pos,
1721
+ this.pos2,
1722
+ this.expr,
1723
+ false,
1724
+ [value],
1725
+ [ruleBodyTrace]
1681
1726
  );
1682
1727
  this.terminatingLREntry.terminatesLR = true;
1683
1728
  }
@@ -1737,7 +1782,7 @@ class Trace {
1737
1782
  const ctorName = node.expr.constructor.name;
1738
1783
  // Don't print anything for Alt nodes.
1739
1784
  if (ctorName === 'Alt') {
1740
- return; // eslint-disable-line consistent-return
1785
+ return;
1741
1786
  }
1742
1787
  sb.append(getInputExcerpt(node.input, node.pos, 10) + spaces(depth * 2 + 1));
1743
1788
  sb.append((node.succeeded ? CHECK_MARK : BALLOT_X) + ' ' + node.displayString);
@@ -1795,7 +1840,7 @@ any.allowsSkippingPrecedingSpace =
1795
1840
  Terminal.prototype.allowsSkippingPrecedingSpace =
1796
1841
  Range.prototype.allowsSkippingPrecedingSpace =
1797
1842
  UnicodeChar.prototype.allowsSkippingPrecedingSpace =
1798
- function() {
1843
+ function () {
1799
1844
  return true;
1800
1845
  };
1801
1846
 
@@ -1809,7 +1854,7 @@ Alt.prototype.allowsSkippingPrecedingSpace =
1809
1854
  Not.prototype.allowsSkippingPrecedingSpace =
1810
1855
  Param.prototype.allowsSkippingPrecedingSpace =
1811
1856
  Seq.prototype.allowsSkippingPrecedingSpace =
1812
- function() {
1857
+ function () {
1813
1858
  return false;
1814
1859
  };
1815
1860
 
@@ -1825,13 +1870,13 @@ awaitBuiltInRules(g => {
1825
1870
 
1826
1871
  let lexifyCount;
1827
1872
 
1828
- PExpr.prototype.assertAllApplicationsAreValid = function(ruleName, grammar) {
1873
+ PExpr.prototype.assertAllApplicationsAreValid = function (ruleName, grammar) {
1829
1874
  lexifyCount = 0;
1830
1875
  this._assertAllApplicationsAreValid(ruleName, grammar);
1831
1876
  };
1832
1877
 
1833
1878
  PExpr.prototype._assertAllApplicationsAreValid = abstract(
1834
- '_assertAllApplicationsAreValid',
1879
+ '_assertAllApplicationsAreValid'
1835
1880
  );
1836
1881
 
1837
1882
  any._assertAllApplicationsAreValid =
@@ -1840,23 +1885,23 @@ any._assertAllApplicationsAreValid =
1840
1885
  Range.prototype._assertAllApplicationsAreValid =
1841
1886
  Param.prototype._assertAllApplicationsAreValid =
1842
1887
  UnicodeChar.prototype._assertAllApplicationsAreValid =
1843
- function(ruleName, grammar) {
1888
+ function (ruleName, grammar) {
1844
1889
  // no-op
1845
1890
  };
1846
1891
 
1847
- Lex.prototype._assertAllApplicationsAreValid = function(ruleName, grammar) {
1892
+ Lex.prototype._assertAllApplicationsAreValid = function (ruleName, grammar) {
1848
1893
  lexifyCount++;
1849
1894
  this.expr._assertAllApplicationsAreValid(ruleName, grammar);
1850
1895
  lexifyCount--;
1851
1896
  };
1852
1897
 
1853
- Alt.prototype._assertAllApplicationsAreValid = function(ruleName, grammar) {
1898
+ Alt.prototype._assertAllApplicationsAreValid = function (ruleName, grammar) {
1854
1899
  for (let idx = 0; idx < this.terms.length; idx++) {
1855
1900
  this.terms[idx]._assertAllApplicationsAreValid(ruleName, grammar);
1856
1901
  }
1857
1902
  };
1858
1903
 
1859
- Seq.prototype._assertAllApplicationsAreValid = function(ruleName, grammar) {
1904
+ Seq.prototype._assertAllApplicationsAreValid = function (ruleName, grammar) {
1860
1905
  for (let idx = 0; idx < this.factors.length; idx++) {
1861
1906
  this.factors[idx]._assertAllApplicationsAreValid(ruleName, grammar);
1862
1907
  }
@@ -1865,14 +1910,14 @@ Seq.prototype._assertAllApplicationsAreValid = function(ruleName, grammar) {
1865
1910
  Iter.prototype._assertAllApplicationsAreValid =
1866
1911
  Not.prototype._assertAllApplicationsAreValid =
1867
1912
  Lookahead.prototype._assertAllApplicationsAreValid =
1868
- function(ruleName, grammar) {
1913
+ function (ruleName, grammar) {
1869
1914
  this.expr._assertAllApplicationsAreValid(ruleName, grammar);
1870
1915
  };
1871
1916
 
1872
- Apply.prototype._assertAllApplicationsAreValid = function(
1873
- ruleName,
1874
- grammar,
1875
- skipSyntacticCheck = false,
1917
+ Apply.prototype._assertAllApplicationsAreValid = function (
1918
+ ruleName,
1919
+ grammar,
1920
+ skipSyntacticCheck = false
1876
1921
  ) {
1877
1922
  const ruleInfo = grammar.rules[this.ruleName];
1878
1923
  const isContextSyntactic = isSyntactic(ruleName) && lexifyCount === 0;
@@ -1935,7 +1980,7 @@ Apply.prototype._assertAllApplicationsAreValid = function(
1935
1980
  // --------------------------------------------------------------------
1936
1981
 
1937
1982
  PExpr.prototype.assertChoicesHaveUniformArity = abstract(
1938
- 'assertChoicesHaveUniformArity',
1983
+ 'assertChoicesHaveUniformArity'
1939
1984
  );
1940
1985
 
1941
1986
  any.assertChoicesHaveUniformArity =
@@ -1945,11 +1990,11 @@ any.assertChoicesHaveUniformArity =
1945
1990
  Param.prototype.assertChoicesHaveUniformArity =
1946
1991
  Lex.prototype.assertChoicesHaveUniformArity =
1947
1992
  UnicodeChar.prototype.assertChoicesHaveUniformArity =
1948
- function(ruleName) {
1993
+ function (ruleName) {
1949
1994
  // no-op
1950
1995
  };
1951
1996
 
1952
- Alt.prototype.assertChoicesHaveUniformArity = function(ruleName) {
1997
+ Alt.prototype.assertChoicesHaveUniformArity = function (ruleName) {
1953
1998
  if (this.terms.length === 0) {
1954
1999
  return;
1955
2000
  }
@@ -1964,7 +2009,7 @@ Alt.prototype.assertChoicesHaveUniformArity = function(ruleName) {
1964
2009
  }
1965
2010
  };
1966
2011
 
1967
- Extend.prototype.assertChoicesHaveUniformArity = function(ruleName) {
2012
+ Extend.prototype.assertChoicesHaveUniformArity = function (ruleName) {
1968
2013
  // Extend is a special case of Alt that's guaranteed to have exactly two
1969
2014
  // cases: [extensions, origBody].
1970
2015
  const actualArity = this.terms[0].getArity();
@@ -1974,25 +2019,25 @@ Extend.prototype.assertChoicesHaveUniformArity = function(ruleName) {
1974
2019
  }
1975
2020
  };
1976
2021
 
1977
- Seq.prototype.assertChoicesHaveUniformArity = function(ruleName) {
2022
+ Seq.prototype.assertChoicesHaveUniformArity = function (ruleName) {
1978
2023
  for (let idx = 0; idx < this.factors.length; idx++) {
1979
2024
  this.factors[idx].assertChoicesHaveUniformArity(ruleName);
1980
2025
  }
1981
2026
  };
1982
2027
 
1983
- Iter.prototype.assertChoicesHaveUniformArity = function(ruleName) {
2028
+ Iter.prototype.assertChoicesHaveUniformArity = function (ruleName) {
1984
2029
  this.expr.assertChoicesHaveUniformArity(ruleName);
1985
2030
  };
1986
2031
 
1987
- Not.prototype.assertChoicesHaveUniformArity = function(ruleName) {
2032
+ Not.prototype.assertChoicesHaveUniformArity = function (ruleName) {
1988
2033
  // no-op (not required b/c the nested expr doesn't show up in the CST)
1989
2034
  };
1990
2035
 
1991
- Lookahead.prototype.assertChoicesHaveUniformArity = function(ruleName) {
2036
+ Lookahead.prototype.assertChoicesHaveUniformArity = function (ruleName) {
1992
2037
  this.expr.assertChoicesHaveUniformArity(ruleName);
1993
2038
  };
1994
2039
 
1995
- Apply.prototype.assertChoicesHaveUniformArity = function(ruleName) {
2040
+ Apply.prototype.assertChoicesHaveUniformArity = function (ruleName) {
1996
2041
  // The arities of the parameter expressions is required to be 1 by
1997
2042
  // `assertAllApplicationsAreValid()`.
1998
2043
  };
@@ -2002,7 +2047,7 @@ Apply.prototype.assertChoicesHaveUniformArity = function(ruleName) {
2002
2047
  // --------------------------------------------------------------------
2003
2048
 
2004
2049
  PExpr.prototype.assertIteratedExprsAreNotNullable = abstract(
2005
- 'assertIteratedExprsAreNotNullable',
2050
+ 'assertIteratedExprsAreNotNullable'
2006
2051
  );
2007
2052
 
2008
2053
  any.assertIteratedExprsAreNotNullable =
@@ -2011,23 +2056,23 @@ any.assertIteratedExprsAreNotNullable =
2011
2056
  Range.prototype.assertIteratedExprsAreNotNullable =
2012
2057
  Param.prototype.assertIteratedExprsAreNotNullable =
2013
2058
  UnicodeChar.prototype.assertIteratedExprsAreNotNullable =
2014
- function(grammar) {
2059
+ function (grammar) {
2015
2060
  // no-op
2016
2061
  };
2017
2062
 
2018
- Alt.prototype.assertIteratedExprsAreNotNullable = function(grammar) {
2063
+ Alt.prototype.assertIteratedExprsAreNotNullable = function (grammar) {
2019
2064
  for (let idx = 0; idx < this.terms.length; idx++) {
2020
2065
  this.terms[idx].assertIteratedExprsAreNotNullable(grammar);
2021
2066
  }
2022
2067
  };
2023
2068
 
2024
- Seq.prototype.assertIteratedExprsAreNotNullable = function(grammar) {
2069
+ Seq.prototype.assertIteratedExprsAreNotNullable = function (grammar) {
2025
2070
  for (let idx = 0; idx < this.factors.length; idx++) {
2026
2071
  this.factors[idx].assertIteratedExprsAreNotNullable(grammar);
2027
2072
  }
2028
2073
  };
2029
2074
 
2030
- Iter.prototype.assertIteratedExprsAreNotNullable = function(grammar) {
2075
+ Iter.prototype.assertIteratedExprsAreNotNullable = function (grammar) {
2031
2076
  // Note: this is the implementation of this method for `Star` and `Plus` expressions.
2032
2077
  // It is overridden for `Opt` below.
2033
2078
  this.expr.assertIteratedExprsAreNotNullable(grammar);
@@ -2040,11 +2085,11 @@ Opt.prototype.assertIteratedExprsAreNotNullable =
2040
2085
  Not.prototype.assertIteratedExprsAreNotNullable =
2041
2086
  Lookahead.prototype.assertIteratedExprsAreNotNullable =
2042
2087
  Lex.prototype.assertIteratedExprsAreNotNullable =
2043
- function(grammar) {
2088
+ function (grammar) {
2044
2089
  this.expr.assertIteratedExprsAreNotNullable(grammar);
2045
2090
  };
2046
2091
 
2047
- Apply.prototype.assertIteratedExprsAreNotNullable = function(grammar) {
2092
+ Apply.prototype.assertIteratedExprsAreNotNullable = function (grammar) {
2048
2093
  this.args.forEach(arg => {
2049
2094
  arg.assertIteratedExprsAreNotNullable(grammar);
2050
2095
  });
@@ -2088,11 +2133,11 @@ class Node {
2088
2133
  onlyChild() {
2089
2134
  if (this.numChildren() !== 1) {
2090
2135
  throw new Error(
2091
- 'cannot get only child of a node of type ' +
2136
+ 'cannot get only child of a node of type ' +
2092
2137
  this.ctorName +
2093
2138
  ' (it has ' +
2094
2139
  this.numChildren() +
2095
- ' children)',
2140
+ ' children)'
2096
2141
  );
2097
2142
  } else {
2098
2143
  return this.firstChild();
@@ -2102,7 +2147,7 @@ class Node {
2102
2147
  firstChild() {
2103
2148
  if (this.hasNoChildren()) {
2104
2149
  throw new Error(
2105
- 'cannot get first child of a ' + this.ctorName + ' node, which has no children',
2150
+ 'cannot get first child of a ' + this.ctorName + ' node, which has no children'
2106
2151
  );
2107
2152
  } else {
2108
2153
  return this.childAt(0);
@@ -2112,7 +2157,7 @@ class Node {
2112
2157
  lastChild() {
2113
2158
  if (this.hasNoChildren()) {
2114
2159
  throw new Error(
2115
- 'cannot get last child of a ' + this.ctorName + ' node, which has no children',
2160
+ 'cannot get last child of a ' + this.ctorName + ' node, which has no children'
2116
2161
  );
2117
2162
  } else {
2118
2163
  return this.childAt(this.numChildren() - 1);
@@ -2246,7 +2291,7 @@ class IterationNode extends Node {
2246
2291
  */
2247
2292
  PExpr.prototype.eval = abstract('eval'); // function(state) { ... }
2248
2293
 
2249
- any.eval = function(state) {
2294
+ any.eval = function (state) {
2250
2295
  const {inputStream} = state;
2251
2296
  const origPos = inputStream.pos;
2252
2297
  const cp = inputStream.nextCodePoint();
@@ -2259,7 +2304,7 @@ any.eval = function(state) {
2259
2304
  }
2260
2305
  };
2261
2306
 
2262
- end.eval = function(state) {
2307
+ end.eval = function (state) {
2263
2308
  const {inputStream} = state;
2264
2309
  const origPos = inputStream.pos;
2265
2310
  if (inputStream.atEnd()) {
@@ -2271,7 +2316,7 @@ end.eval = function(state) {
2271
2316
  }
2272
2317
  };
2273
2318
 
2274
- Terminal.prototype.eval = function(state) {
2319
+ Terminal.prototype.eval = function (state) {
2275
2320
  const {inputStream} = state;
2276
2321
  const origPos = inputStream.pos;
2277
2322
  if (!inputStream.matchString(this.obj)) {
@@ -2283,7 +2328,7 @@ Terminal.prototype.eval = function(state) {
2283
2328
  }
2284
2329
  };
2285
2330
 
2286
- Range.prototype.eval = function(state) {
2331
+ Range.prototype.eval = function (state) {
2287
2332
  const {inputStream} = state;
2288
2333
  const origPos = inputStream.pos;
2289
2334
 
@@ -2302,18 +2347,18 @@ Range.prototype.eval = function(state) {
2302
2347
  }
2303
2348
  };
2304
2349
 
2305
- Param.prototype.eval = function(state) {
2350
+ Param.prototype.eval = function (state) {
2306
2351
  return state.eval(state.currentApplication().args[this.index]);
2307
2352
  };
2308
2353
 
2309
- Lex.prototype.eval = function(state) {
2354
+ Lex.prototype.eval = function (state) {
2310
2355
  state.enterLexifiedContext();
2311
2356
  const ans = state.eval(this.expr);
2312
2357
  state.exitLexifiedContext();
2313
2358
  return ans;
2314
2359
  };
2315
2360
 
2316
- Alt.prototype.eval = function(state) {
2361
+ Alt.prototype.eval = function (state) {
2317
2362
  for (let idx = 0; idx < this.terms.length; idx++) {
2318
2363
  if (state.eval(this.terms[idx])) {
2319
2364
  return true;
@@ -2322,7 +2367,7 @@ Alt.prototype.eval = function(state) {
2322
2367
  return false;
2323
2368
  };
2324
2369
 
2325
- Seq.prototype.eval = function(state) {
2370
+ Seq.prototype.eval = function (state) {
2326
2371
  for (let idx = 0; idx < this.factors.length; idx++) {
2327
2372
  const factor = this.factors[idx];
2328
2373
  if (!state.eval(factor)) {
@@ -2332,7 +2377,7 @@ Seq.prototype.eval = function(state) {
2332
2377
  return true;
2333
2378
  };
2334
2379
 
2335
- Iter.prototype.eval = function(state) {
2380
+ Iter.prototype.eval = function (state) {
2336
2381
  const {inputStream} = state;
2337
2382
  const origPos = inputStream.pos;
2338
2383
  const arity = this.getArity();
@@ -2354,8 +2399,8 @@ Iter.prototype.eval = function(state) {
2354
2399
  numMatches++;
2355
2400
  const row = state._bindings.splice(state._bindings.length - arity, arity);
2356
2401
  const rowOffsets = state._bindingOffsets.splice(
2357
- state._bindingOffsets.length - arity,
2358
- arity,
2402
+ state._bindingOffsets.length - arity,
2403
+ arity
2359
2404
  );
2360
2405
  for (idx = 0; idx < row.length; idx++) {
2361
2406
  cols[idx].push(row[idx]);
@@ -2379,14 +2424,14 @@ Iter.prototype.eval = function(state) {
2379
2424
  const isOptional = this instanceof Opt;
2380
2425
  for (idx = 0; idx < cols.length; idx++) {
2381
2426
  state._bindings.push(
2382
- new IterationNode(cols[idx], colOffsets[idx], matchLength, isOptional),
2427
+ new IterationNode(cols[idx], colOffsets[idx], matchLength, isOptional)
2383
2428
  );
2384
2429
  state._bindingOffsets.push(offset);
2385
2430
  }
2386
2431
  return true;
2387
2432
  };
2388
2433
 
2389
- Not.prototype.eval = function(state) {
2434
+ Not.prototype.eval = function (state) {
2390
2435
  /*
2391
2436
  TODO:
2392
2437
  - Right now we're just throwing away all of the failures that happen inside a `not`, and
@@ -2412,7 +2457,7 @@ Not.prototype.eval = function(state) {
2412
2457
  return true;
2413
2458
  };
2414
2459
 
2415
- Lookahead.prototype.eval = function(state) {
2460
+ Lookahead.prototype.eval = function (state) {
2416
2461
  const {inputStream} = state;
2417
2462
  const origPos = inputStream.pos;
2418
2463
  if (state.eval(this.expr)) {
@@ -2423,7 +2468,7 @@ Lookahead.prototype.eval = function(state) {
2423
2468
  }
2424
2469
  };
2425
2470
 
2426
- Apply.prototype.eval = function(state) {
2471
+ Apply.prototype.eval = function (state) {
2427
2472
  const caller = state.currentApplication();
2428
2473
  const actuals = caller ? caller.args : [];
2429
2474
  const app = this.substituteParams(actuals);
@@ -2446,7 +2491,7 @@ Apply.prototype.eval = function(state) {
2446
2491
  return app.reallyEval(state);
2447
2492
  };
2448
2493
 
2449
- Apply.prototype.handleCycle = function(state) {
2494
+ Apply.prototype.handleCycle = function (state) {
2450
2495
  const posInfo = state.getCurrentPosInfo();
2451
2496
  const {currentLeftRecursion} = posInfo;
2452
2497
  const memoKey = this.toMemoKey();
@@ -2469,7 +2514,7 @@ Apply.prototype.handleCycle = function(state) {
2469
2514
  return state.useMemoizedResult(state.inputStream.pos, memoRec);
2470
2515
  };
2471
2516
 
2472
- Apply.prototype.reallyEval = function(state) {
2517
+ Apply.prototype.reallyEval = function (state) {
2473
2518
  const {inputStream} = state;
2474
2519
  const origPos = inputStream.pos;
2475
2520
  const origPosInfo = state.getCurrentPosInfo();
@@ -2522,6 +2567,7 @@ Apply.prototype.reallyEval = function(state) {
2522
2567
  }
2523
2568
  if (memoRec) {
2524
2569
  memoRec.failuresAtRightmostPosition = state.cloneRecordedFailures();
2570
+ memoRec.rightmostFailureOffset = state._getRightmostFailureOffset();
2525
2571
  }
2526
2572
  }
2527
2573
 
@@ -2539,8 +2585,8 @@ Apply.prototype.reallyEval = function(state) {
2539
2585
  // Fix the input stream's examinedLength -- it should be the maximum examined length
2540
2586
  // across all applications, not just this one.
2541
2587
  inputStream.examinedLength = Math.max(
2542
- inputStream.examinedLength,
2543
- origInputStreamExaminedLength,
2588
+ inputStream.examinedLength,
2589
+ origInputStreamExaminedLength
2544
2590
  );
2545
2591
 
2546
2592
  state.exitApplication(origPosInfo, value);
@@ -2548,7 +2594,7 @@ Apply.prototype.reallyEval = function(state) {
2548
2594
  return succeeded;
2549
2595
  };
2550
2596
 
2551
- Apply.prototype.evalOnce = function(expr, state) {
2597
+ Apply.prototype.evalOnce = function (expr, state) {
2552
2598
  const {inputStream} = state;
2553
2599
  const origPos = inputStream.pos;
2554
2600
 
@@ -2563,7 +2609,7 @@ Apply.prototype.evalOnce = function(expr, state) {
2563
2609
  }
2564
2610
  };
2565
2611
 
2566
- Apply.prototype.growSeedResult = function(body, state, origPos, lrMemoRec, newValue) {
2612
+ Apply.prototype.growSeedResult = function (body, state, origPos, lrMemoRec, newValue) {
2567
2613
  if (!newValue) {
2568
2614
  return false;
2569
2615
  }
@@ -2581,13 +2627,13 @@ Apply.prototype.growSeedResult = function(body, state, origPos, lrMemoRec, newVa
2581
2627
  // element in `state.trace`.
2582
2628
  const seedTrace = state.trace[state.trace.length - 1];
2583
2629
  lrMemoRec.traceEntry = new Trace(
2584
- state.input,
2585
- origPos,
2586
- inputStream.pos,
2587
- this,
2588
- true,
2589
- [newValue],
2590
- [seedTrace.clone()],
2630
+ state.input,
2631
+ origPos,
2632
+ inputStream.pos,
2633
+ this,
2634
+ true,
2635
+ [newValue],
2636
+ [seedTrace.clone()]
2591
2637
  );
2592
2638
  }
2593
2639
  inputStream.pos = origPos;
@@ -2607,17 +2653,19 @@ Apply.prototype.growSeedResult = function(body, state, origPos, lrMemoRec, newVa
2607
2653
  return lrMemoRec.value;
2608
2654
  };
2609
2655
 
2610
- UnicodeChar.prototype.eval = function(state) {
2656
+ UnicodeChar.prototype.eval = function (state) {
2611
2657
  const {inputStream} = state;
2612
2658
  const origPos = inputStream.pos;
2613
- const ch = inputStream.next();
2614
- if (ch && this.pattern.test(ch)) {
2615
- state.pushBinding(new TerminalNode(ch.length), origPos);
2616
- return true;
2617
- } else {
2618
- state.processFailure(origPos, this);
2619
- return false;
2659
+ const cp = inputStream.nextCodePoint();
2660
+ if (cp !== undefined && cp <= MAX_CODE_POINT) {
2661
+ const ch = String.fromCodePoint(cp);
2662
+ if (this.pattern.test(ch)) {
2663
+ state.pushBinding(new TerminalNode(ch.length), origPos);
2664
+ return true;
2665
+ }
2620
2666
  }
2667
+ state.processFailure(origPos, this);
2668
+ return false;
2621
2669
  };
2622
2670
 
2623
2671
  // --------------------------------------------------------------------
@@ -2633,17 +2681,17 @@ any.getArity =
2633
2681
  Param.prototype.getArity =
2634
2682
  Apply.prototype.getArity =
2635
2683
  UnicodeChar.prototype.getArity =
2636
- function() {
2684
+ function () {
2637
2685
  return 1;
2638
2686
  };
2639
2687
 
2640
- Alt.prototype.getArity = function() {
2688
+ Alt.prototype.getArity = function () {
2641
2689
  // This is ok b/c all terms must have the same arity -- this property is
2642
2690
  // checked by the Grammar constructor.
2643
2691
  return this.terms.length === 0 ? 0 : this.terms[0].getArity();
2644
2692
  };
2645
2693
 
2646
- Seq.prototype.getArity = function() {
2694
+ Seq.prototype.getArity = function () {
2647
2695
  let arity = 0;
2648
2696
  for (let idx = 0; idx < this.factors.length; idx++) {
2649
2697
  arity += this.factors[idx].getArity();
@@ -2651,15 +2699,15 @@ Seq.prototype.getArity = function() {
2651
2699
  return arity;
2652
2700
  };
2653
2701
 
2654
- Iter.prototype.getArity = function() {
2702
+ Iter.prototype.getArity = function () {
2655
2703
  return this.expr.getArity();
2656
2704
  };
2657
2705
 
2658
- Not.prototype.getArity = function() {
2706
+ Not.prototype.getArity = function () {
2659
2707
  return 0;
2660
2708
  };
2661
2709
 
2662
- Lookahead.prototype.getArity = Lex.prototype.getArity = function() {
2710
+ Lookahead.prototype.getArity = Lex.prototype.getArity = function () {
2663
2711
  return this.expr.getArity();
2664
2712
  };
2665
2713
 
@@ -2682,38 +2730,38 @@ function getMetaInfo(expr, grammarInterval) {
2682
2730
 
2683
2731
  PExpr.prototype.outputRecipe = abstract('outputRecipe');
2684
2732
 
2685
- any.outputRecipe = function(formals, grammarInterval) {
2733
+ any.outputRecipe = function (formals, grammarInterval) {
2686
2734
  return ['any', getMetaInfo(this, grammarInterval)];
2687
2735
  };
2688
2736
 
2689
- end.outputRecipe = function(formals, grammarInterval) {
2737
+ end.outputRecipe = function (formals, grammarInterval) {
2690
2738
  return ['end', getMetaInfo(this, grammarInterval)];
2691
2739
  };
2692
2740
 
2693
- Terminal.prototype.outputRecipe = function(formals, grammarInterval) {
2741
+ Terminal.prototype.outputRecipe = function (formals, grammarInterval) {
2694
2742
  return ['terminal', getMetaInfo(this, grammarInterval), this.obj];
2695
2743
  };
2696
2744
 
2697
- Range.prototype.outputRecipe = function(formals, grammarInterval) {
2745
+ Range.prototype.outputRecipe = function (formals, grammarInterval) {
2698
2746
  return ['range', getMetaInfo(this, grammarInterval), this.from, this.to];
2699
2747
  };
2700
2748
 
2701
- Param.prototype.outputRecipe = function(formals, grammarInterval) {
2749
+ Param.prototype.outputRecipe = function (formals, grammarInterval) {
2702
2750
  return ['param', getMetaInfo(this, grammarInterval), this.index];
2703
2751
  };
2704
2752
 
2705
- Alt.prototype.outputRecipe = function(formals, grammarInterval) {
2753
+ Alt.prototype.outputRecipe = function (formals, grammarInterval) {
2706
2754
  return ['alt', getMetaInfo(this, grammarInterval)].concat(
2707
- this.terms.map(term => term.outputRecipe(formals, grammarInterval)),
2755
+ this.terms.map(term => term.outputRecipe(formals, grammarInterval))
2708
2756
  );
2709
2757
  };
2710
2758
 
2711
- Extend.prototype.outputRecipe = function(formals, grammarInterval) {
2759
+ Extend.prototype.outputRecipe = function (formals, grammarInterval) {
2712
2760
  const extension = this.terms[0]; // [extension, original]
2713
2761
  return extension.outputRecipe(formals, grammarInterval);
2714
2762
  };
2715
2763
 
2716
- Splice.prototype.outputRecipe = function(formals, grammarInterval) {
2764
+ Splice.prototype.outputRecipe = function (formals, grammarInterval) {
2717
2765
  const beforeTerms = this.terms.slice(0, this.expansionPos);
2718
2766
  const afterTerms = this.terms.slice(this.expansionPos + 1);
2719
2767
  return [
@@ -2724,9 +2772,9 @@ Splice.prototype.outputRecipe = function(formals, grammarInterval) {
2724
2772
  ];
2725
2773
  };
2726
2774
 
2727
- Seq.prototype.outputRecipe = function(formals, grammarInterval) {
2775
+ Seq.prototype.outputRecipe = function (formals, grammarInterval) {
2728
2776
  return ['seq', getMetaInfo(this, grammarInterval)].concat(
2729
- this.factors.map(factor => factor.outputRecipe(formals, grammarInterval)),
2777
+ this.factors.map(factor => factor.outputRecipe(formals, grammarInterval))
2730
2778
  );
2731
2779
  };
2732
2780
 
@@ -2736,7 +2784,7 @@ Star.prototype.outputRecipe =
2736
2784
  Not.prototype.outputRecipe =
2737
2785
  Lookahead.prototype.outputRecipe =
2738
2786
  Lex.prototype.outputRecipe =
2739
- function(formals, grammarInterval) {
2787
+ function (formals, grammarInterval) {
2740
2788
  return [
2741
2789
  this.constructor.name.toLowerCase(),
2742
2790
  getMetaInfo(this, grammarInterval),
@@ -2744,7 +2792,7 @@ Star.prototype.outputRecipe =
2744
2792
  ];
2745
2793
  };
2746
2794
 
2747
- Apply.prototype.outputRecipe = function(formals, grammarInterval) {
2795
+ Apply.prototype.outputRecipe = function (formals, grammarInterval) {
2748
2796
  return [
2749
2797
  'app',
2750
2798
  getMetaInfo(this, grammarInterval),
@@ -2753,8 +2801,8 @@ Apply.prototype.outputRecipe = function(formals, grammarInterval) {
2753
2801
  ];
2754
2802
  };
2755
2803
 
2756
- UnicodeChar.prototype.outputRecipe = function(formals, grammarInterval) {
2757
- return ['unicodeChar', getMetaInfo(this, grammarInterval), this.category];
2804
+ UnicodeChar.prototype.outputRecipe = function (formals, grammarInterval) {
2805
+ return ['unicodeChar', getMetaInfo(this, grammarInterval), this.categoryOrProp];
2758
2806
  };
2759
2807
 
2760
2808
  // --------------------------------------------------------------------
@@ -2774,18 +2822,18 @@ any.introduceParams =
2774
2822
  Range.prototype.introduceParams =
2775
2823
  Param.prototype.introduceParams =
2776
2824
  UnicodeChar.prototype.introduceParams =
2777
- function(formals) {
2825
+ function (formals) {
2778
2826
  return this;
2779
2827
  };
2780
2828
 
2781
- Alt.prototype.introduceParams = function(formals) {
2829
+ Alt.prototype.introduceParams = function (formals) {
2782
2830
  this.terms.forEach((term, idx, terms) => {
2783
2831
  terms[idx] = term.introduceParams(formals);
2784
2832
  });
2785
2833
  return this;
2786
2834
  };
2787
2835
 
2788
- Seq.prototype.introduceParams = function(formals) {
2836
+ Seq.prototype.introduceParams = function (formals) {
2789
2837
  this.factors.forEach((factor, idx, factors) => {
2790
2838
  factors[idx] = factor.introduceParams(formals);
2791
2839
  });
@@ -2796,12 +2844,12 @@ Iter.prototype.introduceParams =
2796
2844
  Not.prototype.introduceParams =
2797
2845
  Lookahead.prototype.introduceParams =
2798
2846
  Lex.prototype.introduceParams =
2799
- function(formals) {
2847
+ function (formals) {
2800
2848
  this.expr = this.expr.introduceParams(formals);
2801
2849
  return this;
2802
2850
  };
2803
2851
 
2804
- Apply.prototype.introduceParams = function(formals) {
2852
+ Apply.prototype.introduceParams = function (formals) {
2805
2853
  const index = formals.indexOf(this.ruleName);
2806
2854
  if (index >= 0) {
2807
2855
  if (this.args.length > 0) {
@@ -2822,7 +2870,7 @@ Apply.prototype.introduceParams = function(formals) {
2822
2870
  // --------------------------------------------------------------------
2823
2871
 
2824
2872
  // Returns `true` if this parsing expression may accept without consuming any input.
2825
- PExpr.prototype.isNullable = function(grammar) {
2873
+ PExpr.prototype.isNullable = function (grammar) {
2826
2874
  return this._isNullable(grammar, Object.create(null));
2827
2875
  };
2828
2876
 
@@ -2833,15 +2881,15 @@ any._isNullable =
2833
2881
  Param.prototype._isNullable =
2834
2882
  Plus.prototype._isNullable =
2835
2883
  UnicodeChar.prototype._isNullable =
2836
- function(grammar, memo) {
2884
+ function (grammar, memo) {
2837
2885
  return false;
2838
2886
  };
2839
2887
 
2840
- end._isNullable = function(grammar, memo) {
2888
+ end._isNullable = function (grammar, memo) {
2841
2889
  return true;
2842
2890
  };
2843
2891
 
2844
- Terminal.prototype._isNullable = function(grammar, memo) {
2892
+ Terminal.prototype._isNullable = function (grammar, memo) {
2845
2893
  if (typeof this.obj === 'string') {
2846
2894
  // This is an over-simplification: it's only correct if the input is a string. If it's an array
2847
2895
  // or an object, then the empty string parsing expression is not nullable.
@@ -2851,11 +2899,11 @@ Terminal.prototype._isNullable = function(grammar, memo) {
2851
2899
  }
2852
2900
  };
2853
2901
 
2854
- Alt.prototype._isNullable = function(grammar, memo) {
2902
+ Alt.prototype._isNullable = function (grammar, memo) {
2855
2903
  return this.terms.length === 0 || this.terms.some(term => term._isNullable(grammar, memo));
2856
2904
  };
2857
2905
 
2858
- Seq.prototype._isNullable = function(grammar, memo) {
2906
+ Seq.prototype._isNullable = function (grammar, memo) {
2859
2907
  return this.factors.every(factor => factor._isNullable(grammar, memo));
2860
2908
  };
2861
2909
 
@@ -2863,15 +2911,15 @@ Star.prototype._isNullable =
2863
2911
  Opt.prototype._isNullable =
2864
2912
  Not.prototype._isNullable =
2865
2913
  Lookahead.prototype._isNullable =
2866
- function(grammar, memo) {
2914
+ function (grammar, memo) {
2867
2915
  return true;
2868
2916
  };
2869
2917
 
2870
- Lex.prototype._isNullable = function(grammar, memo) {
2918
+ Lex.prototype._isNullable = function (grammar, memo) {
2871
2919
  return this.expr._isNullable(grammar, memo);
2872
2920
  };
2873
2921
 
2874
- Apply.prototype._isNullable = function(grammar, memo) {
2922
+ Apply.prototype._isNullable = function (grammar, memo) {
2875
2923
  const key = this.toMemoKey();
2876
2924
  if (!Object.prototype.hasOwnProperty.call(memo, key)) {
2877
2925
  const {body} = grammar.rules[this.ruleName];
@@ -2900,19 +2948,19 @@ any.substituteParams =
2900
2948
  Terminal.prototype.substituteParams =
2901
2949
  Range.prototype.substituteParams =
2902
2950
  UnicodeChar.prototype.substituteParams =
2903
- function(actuals) {
2951
+ function (actuals) {
2904
2952
  return this;
2905
2953
  };
2906
2954
 
2907
- Param.prototype.substituteParams = function(actuals) {
2955
+ Param.prototype.substituteParams = function (actuals) {
2908
2956
  return checkNotNull(actuals[this.index]);
2909
2957
  };
2910
2958
 
2911
- Alt.prototype.substituteParams = function(actuals) {
2959
+ Alt.prototype.substituteParams = function (actuals) {
2912
2960
  return new Alt(this.terms.map(term => term.substituteParams(actuals)));
2913
2961
  };
2914
2962
 
2915
- Seq.prototype.substituteParams = function(actuals) {
2963
+ Seq.prototype.substituteParams = function (actuals) {
2916
2964
  return new Seq(this.factors.map(factor => factor.substituteParams(actuals)));
2917
2965
  };
2918
2966
 
@@ -2920,11 +2968,11 @@ Iter.prototype.substituteParams =
2920
2968
  Not.prototype.substituteParams =
2921
2969
  Lookahead.prototype.substituteParams =
2922
2970
  Lex.prototype.substituteParams =
2923
- function(actuals) {
2971
+ function (actuals) {
2924
2972
  return new this.constructor(this.expr.substituteParams(actuals));
2925
2973
  };
2926
2974
 
2927
- Apply.prototype.substituteParams = function(actuals) {
2975
+ Apply.prototype.substituteParams = function (actuals) {
2928
2976
  if (this.args.length === 0) {
2929
2977
  // Avoid making a copy of this application, as an optimization
2930
2978
  return this;
@@ -2998,15 +3046,15 @@ function resolveDuplicatedNames(argumentNameList) {
2998
3046
  // function(firstArgIndex, noDupCheck) { ... }
2999
3047
  PExpr.prototype.toArgumentNameList = abstract('toArgumentNameList');
3000
3048
 
3001
- any.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3049
+ any.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3002
3050
  return ['any'];
3003
3051
  };
3004
3052
 
3005
- end.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3053
+ end.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3006
3054
  return ['end'];
3007
3055
  };
3008
3056
 
3009
- Terminal.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3057
+ Terminal.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3010
3058
  if (typeof this.obj === 'string' && /^[_a-zA-Z0-9]+$/.test(this.obj)) {
3011
3059
  // If this terminal is a valid suffix for a JS identifier, just prepend it with '_'
3012
3060
  return ['_' + this.obj];
@@ -3016,7 +3064,7 @@ Terminal.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3016
3064
  }
3017
3065
  };
3018
3066
 
3019
- Range.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3067
+ Range.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3020
3068
  let argName = this.from + '_to_' + this.to;
3021
3069
  // If the `argName` is not valid then try to prepend a `_`.
3022
3070
  if (!isRestrictedJSIdentifier(argName)) {
@@ -3029,11 +3077,11 @@ Range.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3029
3077
  return [argName];
3030
3078
  };
3031
3079
 
3032
- Alt.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3080
+ Alt.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3033
3081
  // `termArgNameLists` is an array of arrays where each row is the
3034
3082
  // argument name list that corresponds to a term in this alternation.
3035
3083
  const termArgNameLists = this.terms.map(term =>
3036
- term.toArgumentNameList(firstArgIndex, true),
3084
+ term.toArgumentNameList(firstArgIndex, true)
3037
3085
  );
3038
3086
 
3039
3087
  const argumentNameList = [];
@@ -3053,7 +3101,7 @@ Alt.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3053
3101
  return argumentNameList;
3054
3102
  };
3055
3103
 
3056
- Seq.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3104
+ Seq.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3057
3105
  // Generate the argument name list, without worrying about duplicates.
3058
3106
  let argumentNameList = [];
3059
3107
  this.factors.forEach(factor => {
@@ -3069,44 +3117,44 @@ Seq.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3069
3117
  return argumentNameList;
3070
3118
  };
3071
3119
 
3072
- Iter.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3120
+ Iter.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3073
3121
  const argumentNameList = this.expr
3074
- .toArgumentNameList(firstArgIndex, noDupCheck)
3075
- .map(exprArgumentString =>
3076
- exprArgumentString[exprArgumentString.length - 1] === 's' ?
3077
- exprArgumentString + 'es' :
3078
- exprArgumentString + 's',
3079
- );
3122
+ .toArgumentNameList(firstArgIndex, noDupCheck)
3123
+ .map(exprArgumentString =>
3124
+ exprArgumentString[exprArgumentString.length - 1] === 's'
3125
+ ? exprArgumentString + 'es'
3126
+ : exprArgumentString + 's'
3127
+ );
3080
3128
  if (!noDupCheck) {
3081
3129
  resolveDuplicatedNames(argumentNameList);
3082
3130
  }
3083
3131
  return argumentNameList;
3084
3132
  };
3085
3133
 
3086
- Opt.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3134
+ Opt.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3087
3135
  return this.expr.toArgumentNameList(firstArgIndex, noDupCheck).map(argName => {
3088
3136
  return 'opt' + argName[0].toUpperCase() + argName.slice(1);
3089
3137
  });
3090
3138
  };
3091
3139
 
3092
- Not.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3140
+ Not.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3093
3141
  return [];
3094
3142
  };
3095
3143
 
3096
3144
  Lookahead.prototype.toArgumentNameList = Lex.prototype.toArgumentNameList =
3097
- function(firstArgIndex, noDupCheck) {
3145
+ function (firstArgIndex, noDupCheck) {
3098
3146
  return this.expr.toArgumentNameList(firstArgIndex, noDupCheck);
3099
3147
  };
3100
3148
 
3101
- Apply.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3149
+ Apply.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3102
3150
  return [this.ruleName];
3103
3151
  };
3104
3152
 
3105
- UnicodeChar.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3153
+ UnicodeChar.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3106
3154
  return ['$' + firstArgIndex];
3107
3155
  };
3108
3156
 
3109
- Param.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3157
+ Param.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
3110
3158
  return ['param' + this.index];
3111
3159
  };
3112
3160
 
@@ -3119,7 +3167,7 @@ Param.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
3119
3167
  // Returns a string representing the PExpr, for use as a UI label, etc.
3120
3168
  PExpr.prototype.toDisplayString = abstract('toDisplayString');
3121
3169
 
3122
- Alt.prototype.toDisplayString = Seq.prototype.toDisplayString = function() {
3170
+ Alt.prototype.toDisplayString = Seq.prototype.toDisplayString = function () {
3123
3171
  if (this.source) {
3124
3172
  return this.source.trimmed().contents;
3125
3173
  }
@@ -3135,11 +3183,11 @@ any.toDisplayString =
3135
3183
  Terminal.prototype.toDisplayString =
3136
3184
  Range.prototype.toDisplayString =
3137
3185
  Param.prototype.toDisplayString =
3138
- function() {
3186
+ function () {
3139
3187
  return this.toString();
3140
3188
  };
3141
3189
 
3142
- Apply.prototype.toDisplayString = function() {
3190
+ Apply.prototype.toDisplayString = function () {
3143
3191
  if (this.args.length > 0) {
3144
3192
  const ps = this.args.map(arg => arg.toDisplayString());
3145
3193
  return this.ruleName + '<' + ps.join(',') + '>';
@@ -3148,8 +3196,8 @@ Apply.prototype.toDisplayString = function() {
3148
3196
  }
3149
3197
  };
3150
3198
 
3151
- UnicodeChar.prototype.toDisplayString = function() {
3152
- return 'Unicode [' + this.category + '] character';
3199
+ UnicodeChar.prototype.toDisplayString = function () {
3200
+ return 'Unicode [' + this.categoryOrProp + '] character';
3153
3201
  };
3154
3202
 
3155
3203
  // --------------------------------------------------------------------
@@ -3252,34 +3300,34 @@ class Failure {
3252
3300
 
3253
3301
  PExpr.prototype.toFailure = abstract('toFailure');
3254
3302
 
3255
- any.toFailure = function(grammar) {
3303
+ any.toFailure = function (grammar) {
3256
3304
  return new Failure(this, 'any object', 'description');
3257
3305
  };
3258
3306
 
3259
- end.toFailure = function(grammar) {
3307
+ end.toFailure = function (grammar) {
3260
3308
  return new Failure(this, 'end of input', 'description');
3261
3309
  };
3262
3310
 
3263
- Terminal.prototype.toFailure = function(grammar) {
3311
+ Terminal.prototype.toFailure = function (grammar) {
3264
3312
  return new Failure(this, this.obj, 'string');
3265
3313
  };
3266
3314
 
3267
- Range.prototype.toFailure = function(grammar) {
3315
+ Range.prototype.toFailure = function (grammar) {
3268
3316
  // TODO: come up with something better
3269
3317
  return new Failure(this, JSON.stringify(this.from) + '..' + JSON.stringify(this.to), 'code');
3270
3318
  };
3271
3319
 
3272
- Not.prototype.toFailure = function(grammar) {
3320
+ Not.prototype.toFailure = function (grammar) {
3273
3321
  const description =
3274
3322
  this.expr === any ? 'nothing' : 'not ' + this.expr.toFailure(grammar);
3275
3323
  return new Failure(this, description, 'description');
3276
3324
  };
3277
3325
 
3278
- Lookahead.prototype.toFailure = function(grammar) {
3326
+ Lookahead.prototype.toFailure = function (grammar) {
3279
3327
  return this.expr.toFailure(grammar);
3280
3328
  };
3281
3329
 
3282
- Apply.prototype.toFailure = function(grammar) {
3330
+ Apply.prototype.toFailure = function (grammar) {
3283
3331
  let {description} = grammar.rules[this.ruleName];
3284
3332
  if (!description) {
3285
3333
  const article = /^[aeiouAEIOU]/.test(this.ruleName) ? 'an' : 'a';
@@ -3288,23 +3336,23 @@ Apply.prototype.toFailure = function(grammar) {
3288
3336
  return new Failure(this, description, 'description');
3289
3337
  };
3290
3338
 
3291
- UnicodeChar.prototype.toFailure = function(grammar) {
3292
- return new Failure(this, 'a Unicode [' + this.category + '] character', 'description');
3339
+ UnicodeChar.prototype.toFailure = function (grammar) {
3340
+ return new Failure(this, 'a Unicode [' + this.categoryOrProp + '] character', 'description');
3293
3341
  };
3294
3342
 
3295
- Alt.prototype.toFailure = function(grammar) {
3343
+ Alt.prototype.toFailure = function (grammar) {
3296
3344
  const fs = this.terms.map(t => t.toFailure(grammar));
3297
3345
  const description = '(' + fs.join(' or ') + ')';
3298
3346
  return new Failure(this, description, 'description');
3299
3347
  };
3300
3348
 
3301
- Seq.prototype.toFailure = function(grammar) {
3349
+ Seq.prototype.toFailure = function (grammar) {
3302
3350
  const fs = this.factors.map(f => f.toFailure(grammar));
3303
3351
  const description = '(' + fs.join(' ') + ')';
3304
3352
  return new Failure(this, description, 'description');
3305
3353
  };
3306
3354
 
3307
- Iter.prototype.toFailure = function(grammar) {
3355
+ Iter.prototype.toFailure = function (grammar) {
3308
3356
  const description = '(' + this.expr.toFailure(grammar) + this.operator + ')';
3309
3357
  return new Failure(this, description, 'description');
3310
3358
  };
@@ -3322,55 +3370,55 @@ Iter.prototype.toFailure = function(grammar) {
3322
3370
  */
3323
3371
  PExpr.prototype.toString = abstract('toString');
3324
3372
 
3325
- any.toString = function() {
3373
+ any.toString = function () {
3326
3374
  return 'any';
3327
3375
  };
3328
3376
 
3329
- end.toString = function() {
3377
+ end.toString = function () {
3330
3378
  return 'end';
3331
3379
  };
3332
3380
 
3333
- Terminal.prototype.toString = function() {
3381
+ Terminal.prototype.toString = function () {
3334
3382
  return JSON.stringify(this.obj);
3335
3383
  };
3336
3384
 
3337
- Range.prototype.toString = function() {
3385
+ Range.prototype.toString = function () {
3338
3386
  return JSON.stringify(this.from) + '..' + JSON.stringify(this.to);
3339
3387
  };
3340
3388
 
3341
- Param.prototype.toString = function() {
3389
+ Param.prototype.toString = function () {
3342
3390
  return '$' + this.index;
3343
3391
  };
3344
3392
 
3345
- Lex.prototype.toString = function() {
3393
+ Lex.prototype.toString = function () {
3346
3394
  return '#(' + this.expr.toString() + ')';
3347
3395
  };
3348
3396
 
3349
- Alt.prototype.toString = function() {
3350
- return this.terms.length === 1 ?
3351
- this.terms[0].toString() :
3352
- '(' + this.terms.map(term => term.toString()).join(' | ') + ')';
3397
+ Alt.prototype.toString = function () {
3398
+ return this.terms.length === 1
3399
+ ? this.terms[0].toString()
3400
+ : '(' + this.terms.map(term => term.toString()).join(' | ') + ')';
3353
3401
  };
3354
3402
 
3355
- Seq.prototype.toString = function() {
3356
- return this.factors.length === 1 ?
3357
- this.factors[0].toString() :
3358
- '(' + this.factors.map(factor => factor.toString()).join(' ') + ')';
3403
+ Seq.prototype.toString = function () {
3404
+ return this.factors.length === 1
3405
+ ? this.factors[0].toString()
3406
+ : '(' + this.factors.map(factor => factor.toString()).join(' ') + ')';
3359
3407
  };
3360
3408
 
3361
- Iter.prototype.toString = function() {
3409
+ Iter.prototype.toString = function () {
3362
3410
  return this.expr + this.operator;
3363
3411
  };
3364
3412
 
3365
- Not.prototype.toString = function() {
3413
+ Not.prototype.toString = function () {
3366
3414
  return '~' + this.expr;
3367
3415
  };
3368
3416
 
3369
- Lookahead.prototype.toString = function() {
3417
+ Lookahead.prototype.toString = function () {
3370
3418
  return '&' + this.expr;
3371
3419
  };
3372
3420
 
3373
- Apply.prototype.toString = function() {
3421
+ Apply.prototype.toString = function () {
3374
3422
  if (this.args.length > 0) {
3375
3423
  const ps = this.args.map(arg => arg.toString());
3376
3424
  return this.ruleName + '<' + ps.join(',') + '>';
@@ -3379,8 +3427,8 @@ Apply.prototype.toString = function() {
3379
3427
  }
3380
3428
  };
3381
3429
 
3382
- UnicodeChar.prototype.toString = function() {
3383
- return '\\p{' + this.category + '}';
3430
+ UnicodeChar.prototype.toString = function () {
3431
+ return '\\p{' + this.categoryOrProp + '}';
3384
3432
  };
3385
3433
 
3386
3434
  class CaseInsensitiveTerminal extends PExpr {
@@ -3428,9 +3476,9 @@ class CaseInsensitiveTerminal extends PExpr {
3428
3476
 
3429
3477
  toFailure(grammar) {
3430
3478
  return new Failure(
3431
- this,
3432
- this.obj.toFailure(grammar) + ' (case-insensitive)',
3433
- 'description',
3479
+ this,
3480
+ this.obj.toFailure(grammar) + ' (case-insensitive)',
3481
+ 'description'
3434
3482
  );
3435
3483
  }
3436
3484
 
@@ -3500,8 +3548,8 @@ class MatchState {
3500
3548
  posInfo.exit();
3501
3549
 
3502
3550
  this.rightmostFailurePosition = Math.max(
3503
- this.rightmostFailurePosition,
3504
- this._rightmostFailurePositionStack.pop(),
3551
+ this.rightmostFailurePosition,
3552
+ this._rightmostFailurePositionStack.pop()
3505
3553
  );
3506
3554
 
3507
3555
  if (optNode) {
@@ -3637,9 +3685,9 @@ class MatchState {
3637
3685
  }
3638
3686
 
3639
3687
  _getRightmostFailureOffset() {
3640
- return this.rightmostFailurePosition >= 0 ?
3641
- this.posToOffset(this.rightmostFailurePosition) :
3642
- -1;
3688
+ return this.rightmostFailurePosition >= 0
3689
+ ? this.posToOffset(this.rightmostFailurePosition)
3690
+ : -1;
3643
3691
  }
3644
3692
 
3645
3693
  // Returns the memoized trace entry for `expr` at `pos`, if one exists, `null` otherwise.
@@ -3696,8 +3744,8 @@ class MatchState {
3696
3744
  const memoRecRightmostFailurePosition =
3697
3745
  this.inputStream.pos + memoRec.rightmostFailureOffset;
3698
3746
  this.rightmostFailurePosition = Math.max(
3699
- this.rightmostFailurePosition,
3700
- memoRecRightmostFailurePosition,
3747
+ this.rightmostFailurePosition,
3748
+ memoRecRightmostFailurePosition
3701
3749
  );
3702
3750
  if (
3703
3751
  this.recordedFailures &&
@@ -3708,8 +3756,8 @@ class MatchState {
3708
3756
  }
3709
3757
 
3710
3758
  this.inputStream.examinedLength = Math.max(
3711
- this.inputStream.examinedLength,
3712
- memoRec.examinedLength + origPos,
3759
+ this.inputStream.examinedLength,
3760
+ memoRec.examinedLength + origPos
3713
3761
  );
3714
3762
 
3715
3763
  if (memoRec.value) {
@@ -3787,7 +3835,7 @@ class MatchState {
3787
3835
  let rightmostFailures;
3788
3836
  if (this.recordedFailures) {
3789
3837
  rightmostFailures = Object.keys(this.recordedFailures).map(
3790
- key => this.recordedFailures[key],
3838
+ key => this.recordedFailures[key]
3791
3839
  );
3792
3840
  }
3793
3841
  const cst = this._bindings[0];
@@ -3795,13 +3843,13 @@ class MatchState {
3795
3843
  cst.grammar = this.grammar;
3796
3844
  }
3797
3845
  return new MatchResult(
3798
- this.matcher,
3799
- this.input,
3800
- this.startExpr,
3801
- cst,
3802
- this._bindingOffsets[0],
3803
- this.rightmostFailurePosition,
3804
- rightmostFailures,
3846
+ this.matcher,
3847
+ this.input,
3848
+ this.startExpr,
3849
+ cst,
3850
+ this._bindingOffsets[0],
3851
+ this.rightmostFailurePosition,
3852
+ rightmostFailures
3805
3853
  );
3806
3854
  }
3807
3855
 
@@ -4114,11 +4162,11 @@ class Semantics {
4114
4162
  if (superSemantics) {
4115
4163
  if (!(grammar.equals(this.super.grammar) || grammar._inheritsFrom(this.super.grammar))) {
4116
4164
  throw new Error(
4117
- "Cannot extend a semantics for grammar '" +
4165
+ "Cannot extend a semantics for grammar '" +
4118
4166
  this.super.grammar.name +
4119
4167
  "' for use with grammar '" +
4120
4168
  grammar.name +
4121
- "' (not a sub-grammar)",
4169
+ "' (not a sub-grammar)"
4122
4170
  );
4123
4171
  }
4124
4172
  this.operations = Object.create(this.super.operations);
@@ -4127,7 +4175,7 @@ class Semantics {
4127
4175
 
4128
4176
  // Assign unique symbols for each of the attributes inherited from the super-semantics so that
4129
4177
  // they are memoized independently.
4130
- // eslint-disable-next-line guard-for-in
4178
+
4131
4179
  for (const attributeName in this.attributes) {
4132
4180
  Object.defineProperty(this.attributeKeys, attributeName, {
4133
4181
  value: uniqueId(attributeName),
@@ -4156,11 +4204,11 @@ class Semantics {
4156
4204
  // Throws an exception if one or more of them doesn't.
4157
4205
  checkActionDicts() {
4158
4206
  let name;
4159
- // eslint-disable-next-line guard-for-in
4207
+
4160
4208
  for (name in this.operations) {
4161
4209
  this.operations[name].checkActionDict(this.grammar);
4162
4210
  }
4163
- // eslint-disable-next-line guard-for-in
4211
+
4164
4212
  for (name in this.attributes) {
4165
4213
  this.attributes[name].checkActionDict(this.grammar);
4166
4214
  }
@@ -4260,9 +4308,9 @@ class Semantics {
4260
4308
  });
4261
4309
 
4262
4310
  const entry =
4263
- type === 'operation' ?
4264
- new Operation(name, formals, realActionDict, builtInDefault) :
4265
- new Attribute(name, realActionDict, builtInDefault);
4311
+ type === 'operation'
4312
+ ? new Operation(name, formals, realActionDict, builtInDefault)
4313
+ : new Attribute(name, realActionDict, builtInDefault);
4266
4314
 
4267
4315
  // The following check is not strictly necessary (it will happen later anyway) but it's better
4268
4316
  // to catch errors early.
@@ -4278,7 +4326,7 @@ class Semantics {
4278
4326
  // Check that the caller passed the correct number of arguments.
4279
4327
  if (arguments.length !== thisThing.formals.length) {
4280
4328
  throw new Error(
4281
- 'Invalid number of arguments passed to ' +
4329
+ 'Invalid number of arguments passed to ' +
4282
4330
  name +
4283
4331
  ' ' +
4284
4332
  type +
@@ -4286,7 +4334,7 @@ class Semantics {
4286
4334
  thisThing.formals.length +
4287
4335
  ', got ' +
4288
4336
  arguments.length +
4289
- ')',
4337
+ ')'
4290
4338
  );
4291
4339
  }
4292
4340
 
@@ -4307,7 +4355,7 @@ class Semantics {
4307
4355
 
4308
4356
  if (type === 'operation') {
4309
4357
  this.Wrapper.prototype[name] = doIt;
4310
- this.Wrapper.prototype[name].toString = function() {
4358
+ this.Wrapper.prototype[name].toString = function () {
4311
4359
  return '[' + name + ' operation]';
4312
4360
  };
4313
4361
  } else {
@@ -4329,13 +4377,13 @@ class Semantics {
4329
4377
 
4330
4378
  if (!(this.super && name in this.super[typePlural])) {
4331
4379
  throw new Error(
4332
- 'Cannot extend ' +
4380
+ 'Cannot extend ' +
4333
4381
  type +
4334
4382
  " '" +
4335
4383
  name +
4336
4384
  "': did not inherit an " +
4337
4385
  type +
4338
- ' with that name',
4386
+ ' with that name'
4339
4387
  );
4340
4388
  }
4341
4389
  if (hasOwnProperty(this[typePlural], name)) {
@@ -4352,9 +4400,9 @@ class Semantics {
4352
4400
  });
4353
4401
 
4354
4402
  this[typePlural][name] =
4355
- type === 'operation' ?
4356
- new Operation(name, inheritedFormals, newActionDict) :
4357
- new Attribute(name, newActionDict);
4403
+ type === 'operation'
4404
+ ? new Operation(name, inheritedFormals, newActionDict)
4405
+ : new Attribute(name, newActionDict);
4358
4406
 
4359
4407
  // The following check is not strictly necessary (it will happen later anyway) but it's better
4360
4408
  // to catch errors early.
@@ -4367,12 +4415,12 @@ class Semantics {
4367
4415
  }
4368
4416
  if (name in this.operations) {
4369
4417
  throw new Error(
4370
- 'Cannot add ' + type + " '" + name + "': an operation with that name already exists",
4418
+ 'Cannot add ' + type + " '" + name + "': an operation with that name already exists"
4371
4419
  );
4372
4420
  }
4373
4421
  if (name in this.attributes) {
4374
4422
  throw new Error(
4375
- 'Cannot add ' + type + " '" + name + "': an attribute with that name already exists",
4423
+ 'Cannot add ' + type + " '" + name + "': an attribute with that name already exists"
4376
4424
  );
4377
4425
  }
4378
4426
  }
@@ -4398,8 +4446,8 @@ function parseSignature(signature, type) {
4398
4446
  }
4399
4447
 
4400
4448
  const r = Semantics.prototypeGrammar.match(
4401
- signature,
4402
- type === 'operation' ? 'OperationSignature' : 'AttributeSignature',
4449
+ signature,
4450
+ type === 'operation' ? 'OperationSignature' : 'AttributeSignature'
4403
4451
  );
4404
4452
  if (r.failed()) {
4405
4453
  throw new Error(r.message);
@@ -4409,7 +4457,7 @@ function parseSignature(signature, type) {
4409
4457
  }
4410
4458
 
4411
4459
  function newDefaultAction(type, name, doIt) {
4412
- return function(...children) {
4460
+ return function (...children) {
4413
4461
  const thisThing = this._semantics.operations[name] || this._semantics.attributes[name];
4414
4462
  const args = thisThing.formals.map(formal => this.args[formal]);
4415
4463
 
@@ -4433,12 +4481,12 @@ function newDefaultAction(type, name, doIt) {
4433
4481
  // Semantics instance. When that function is invoked with a CST node as an argument, it returns
4434
4482
  // a wrapper for that node which gives access to the operations and attributes provided by this
4435
4483
  // semantics.
4436
- Semantics.createSemantics = function(grammar, optSuperSemantics) {
4484
+ Semantics.createSemantics = function (grammar, optSuperSemantics) {
4437
4485
  const s = new Semantics(
4438
- grammar,
4439
- optSuperSemantics !== undefined ?
4440
- optSuperSemantics :
4441
- Semantics.BuiltInSemantics._getSemantics(),
4486
+ grammar,
4487
+ optSuperSemantics !== undefined
4488
+ ? optSuperSemantics
4489
+ : Semantics.BuiltInSemantics._getSemantics()
4442
4490
  );
4443
4491
 
4444
4492
  // To enable clients to invoke a semantics like a function, return a function that acts as a proxy
@@ -4446,8 +4494,8 @@ Semantics.createSemantics = function(grammar, optSuperSemantics) {
4446
4494
  const proxy = function ASemantics(matchResult) {
4447
4495
  if (!(matchResult instanceof MatchResult)) {
4448
4496
  throw new TypeError(
4449
- 'Semantics expected a MatchResult, but got ' +
4450
- unexpectedObjToString(matchResult),
4497
+ 'Semantics expected a MatchResult, but got ' +
4498
+ unexpectedObjToString(matchResult)
4451
4499
  );
4452
4500
  }
4453
4501
  if (matchResult.failed()) {
@@ -4457,11 +4505,11 @@ Semantics.createSemantics = function(grammar, optSuperSemantics) {
4457
4505
  const cst = matchResult._cst;
4458
4506
  if (cst.grammar !== grammar) {
4459
4507
  throw new Error(
4460
- "Cannot use a MatchResult from grammar '" +
4508
+ "Cannot use a MatchResult from grammar '" +
4461
4509
  cst.grammar.name +
4462
4510
  "' with a semantics for '" +
4463
4511
  grammar.name +
4464
- "'",
4512
+ "'"
4465
4513
  );
4466
4514
  }
4467
4515
  const inputStream = new InputStream(matchResult.input);
@@ -4469,38 +4517,38 @@ Semantics.createSemantics = function(grammar, optSuperSemantics) {
4469
4517
  };
4470
4518
 
4471
4519
  // Forward public methods from the proxy to the semantics instance.
4472
- proxy.addOperation = function(signature, actionDict) {
4520
+ proxy.addOperation = function (signature, actionDict) {
4473
4521
  s.addOperationOrAttribute('operation', signature, actionDict);
4474
4522
  return proxy;
4475
4523
  };
4476
- proxy.extendOperation = function(name, actionDict) {
4524
+ proxy.extendOperation = function (name, actionDict) {
4477
4525
  s.extendOperationOrAttribute('operation', name, actionDict);
4478
4526
  return proxy;
4479
4527
  };
4480
- proxy.addAttribute = function(name, actionDict) {
4528
+ proxy.addAttribute = function (name, actionDict) {
4481
4529
  s.addOperationOrAttribute('attribute', name, actionDict);
4482
4530
  return proxy;
4483
4531
  };
4484
- proxy.extendAttribute = function(name, actionDict) {
4532
+ proxy.extendAttribute = function (name, actionDict) {
4485
4533
  s.extendOperationOrAttribute('attribute', name, actionDict);
4486
4534
  return proxy;
4487
4535
  };
4488
- proxy._getActionDict = function(operationOrAttributeName) {
4536
+ proxy._getActionDict = function (operationOrAttributeName) {
4489
4537
  const action =
4490
4538
  s.operations[operationOrAttributeName] || s.attributes[operationOrAttributeName];
4491
4539
  if (!action) {
4492
4540
  throw new Error(
4493
- '"' +
4541
+ '"' +
4494
4542
  operationOrAttributeName +
4495
4543
  '" is not a valid operation or attribute ' +
4496
4544
  'name in this semantics for "' +
4497
4545
  grammar.name +
4498
- '"',
4546
+ '"'
4499
4547
  );
4500
4548
  }
4501
4549
  return action.actionDict;
4502
4550
  };
4503
- proxy._remove = function(operationOrAttributeName) {
4551
+ proxy._remove = function (operationOrAttributeName) {
4504
4552
  let semantic;
4505
4553
  if (operationOrAttributeName in s.operations) {
4506
4554
  semantic = s.operations[operationOrAttributeName];
@@ -4512,16 +4560,16 @@ Semantics.createSemantics = function(grammar, optSuperSemantics) {
4512
4560
  delete s.Wrapper.prototype[operationOrAttributeName];
4513
4561
  return semantic;
4514
4562
  };
4515
- proxy.getOperationNames = function() {
4563
+ proxy.getOperationNames = function () {
4516
4564
  return Object.keys(s.operations);
4517
4565
  };
4518
- proxy.getAttributeNames = function() {
4566
+ proxy.getAttributeNames = function () {
4519
4567
  return Object.keys(s.attributes);
4520
4568
  };
4521
- proxy.getGrammar = function() {
4569
+ proxy.getGrammar = function () {
4522
4570
  return s.grammar;
4523
4571
  };
4524
- proxy.toRecipe = function(semanticsOnly) {
4572
+ proxy.toRecipe = function (semanticsOnly) {
4525
4573
  return s.toRecipe(semanticsOnly);
4526
4574
  };
4527
4575
 
@@ -4529,7 +4577,7 @@ Semantics.createSemantics = function(grammar, optSuperSemantics) {
4529
4577
  proxy.toString = s.toString.bind(s);
4530
4578
 
4531
4579
  // Returns the semantics for the proxy.
4532
- proxy._getSemantics = function() {
4580
+ proxy._getSemantics = function () {
4533
4581
  return s;
4534
4582
  };
4535
4583
 
@@ -4621,8 +4669,8 @@ const SPECIAL_ACTION_NAMES = ['_iter', '_terminal', '_nonterminal', '_default'];
4621
4669
 
4622
4670
  function getSortedRuleValues(grammar) {
4623
4671
  return Object.keys(grammar.rules)
4624
- .sort()
4625
- .map(name => grammar.rules[name]);
4672
+ .sort()
4673
+ .map(name => grammar.rules[name]);
4626
4674
  }
4627
4675
 
4628
4676
  // Until ES2019, JSON was not a valid subset of JavaScript because U+2028 (line separator)
@@ -4643,11 +4691,11 @@ class Grammar {
4643
4691
  if (optDefaultStartRule) {
4644
4692
  if (!(optDefaultStartRule in rules)) {
4645
4693
  throw new Error(
4646
- "Invalid start rule: '" +
4694
+ "Invalid start rule: '" +
4647
4695
  optDefaultStartRule +
4648
4696
  "' is not a rule in grammar '" +
4649
4697
  name +
4650
- "'",
4698
+ "'"
4651
4699
  );
4652
4700
  }
4653
4701
  this.defaultStartRule = optDefaultStartRule;
@@ -4718,7 +4766,6 @@ class Grammar {
4718
4766
  _checkTopDownActionDict(what, name, actionDict) {
4719
4767
  const problems = [];
4720
4768
 
4721
- // eslint-disable-next-line guard-for-in
4722
4769
  for (const k in actionDict) {
4723
4770
  const v = actionDict[k];
4724
4771
  const isSpecialAction = SPECIAL_ACTION_NAMES.includes(k);
@@ -4748,10 +4795,10 @@ class Grammar {
4748
4795
  if (problems.length > 0) {
4749
4796
  const prettyProblems = problems.map(problem => '- ' + problem);
4750
4797
  const error = new Error(
4751
- [
4752
- `Found errors in the action dictionary of the '${name}' ${what}:`,
4753
- ...prettyProblems,
4754
- ].join('\n'),
4798
+ [
4799
+ `Found errors in the action dictionary of the '${name}' ${what}:`,
4800
+ ...prettyProblems,
4801
+ ].join('\n')
4755
4802
  );
4756
4803
  error.problems = problems;
4757
4804
  throw error;
@@ -4764,9 +4811,9 @@ class Grammar {
4764
4811
  // All special actions have an expected arity of 0, though all but _terminal
4765
4812
  // are expected to use the rest parameter syntax (e.g. `_iter(...children)`).
4766
4813
  // This is considered to have arity 0, i.e. `((...args) => {}).length` is 0.
4767
- return SPECIAL_ACTION_NAMES.includes(actionName) ?
4768
- 0 :
4769
- this.rules[actionName].body.getArity();
4814
+ return SPECIAL_ACTION_NAMES.includes(actionName)
4815
+ ? 0
4816
+ : this.rules[actionName].body.getArity();
4770
4817
  }
4771
4818
 
4772
4819
  _inheritsFrom(grammar) {
@@ -4857,7 +4904,7 @@ class Grammar {
4857
4904
  sb.append('{');
4858
4905
 
4859
4906
  let first = true;
4860
- // eslint-disable-next-line guard-for-in
4907
+
4861
4908
  for (const ruleName in this.rules) {
4862
4909
  const {body} = this.rules[ruleName];
4863
4910
  if (first) {
@@ -4904,10 +4951,10 @@ class Grammar {
4904
4951
  if (formals.length !== app.args.length) {
4905
4952
  const {source} = this.rules[app.ruleName];
4906
4953
  throw wrongNumberOfParameters(
4907
- app.ruleName,
4908
- formals.length,
4909
- app.args.length,
4910
- source,
4954
+ app.ruleName,
4955
+ formals.length,
4956
+ app.args.length,
4957
+ source
4911
4958
  );
4912
4959
  }
4913
4960
  return app;
@@ -4926,63 +4973,63 @@ class Grammar {
4926
4973
  // `digit`, and is implicitly the super-grammar of any grammar whose super-grammar
4927
4974
  // isn't specified.
4928
4975
  Grammar.ProtoBuiltInRules = new Grammar(
4929
- 'ProtoBuiltInRules', // name
4930
- undefined, // supergrammar
4931
- {
4932
- any: {
4933
- body: any,
4934
- formals: [],
4935
- description: 'any character',
4936
- primitive: true,
4937
- },
4938
- end: {
4939
- body: end,
4940
- formals: [],
4941
- description: 'end of input',
4942
- primitive: true,
4943
- },
4944
-
4945
- caseInsensitive: {
4946
- body: new CaseInsensitiveTerminal(new Param(0)),
4947
- formals: ['str'],
4948
- primitive: true,
4949
- },
4950
- lower: {
4951
- body: new UnicodeChar('Ll'),
4952
- formals: [],
4953
- description: 'a lowercase letter',
4954
- primitive: true,
4955
- },
4956
- upper: {
4957
- body: new UnicodeChar('Lu'),
4958
- formals: [],
4959
- description: 'an uppercase letter',
4960
- primitive: true,
4961
- },
4962
- // Union of Lt (titlecase), Lm (modifier), and Lo (other), i.e. any letter not in Ll or Lu.
4963
- unicodeLtmo: {
4964
- body: new UnicodeChar('Ltmo'),
4965
- formals: [],
4966
- description: 'a Unicode character in Lt, Lm, or Lo',
4967
- primitive: true,
4968
- },
4969
-
4970
- // These rules are not truly primitive (they could be written in userland) but are defined
4971
- // here for bootstrapping purposes.
4972
- spaces: {
4973
- body: new Star(new Apply('space')),
4974
- formals: [],
4975
- },
4976
- space: {
4977
- body: new Range('\x00', ' '),
4978
- formals: [],
4979
- description: 'a space',
4980
- },
4976
+ 'ProtoBuiltInRules', // name
4977
+ undefined, // supergrammar
4978
+ {
4979
+ any: {
4980
+ body: any,
4981
+ formals: [],
4982
+ description: 'any character',
4983
+ primitive: true,
4984
+ },
4985
+ end: {
4986
+ body: end,
4987
+ formals: [],
4988
+ description: 'end of input',
4989
+ primitive: true,
4990
+ },
4991
+
4992
+ caseInsensitive: {
4993
+ body: new CaseInsensitiveTerminal(new Param(0)),
4994
+ formals: ['str'],
4995
+ primitive: true,
4996
+ },
4997
+ lower: {
4998
+ body: new UnicodeChar('Ll'),
4999
+ formals: [],
5000
+ description: 'a lowercase letter',
5001
+ primitive: true,
5002
+ },
5003
+ upper: {
5004
+ body: new UnicodeChar('Lu'),
5005
+ formals: [],
5006
+ description: 'an uppercase letter',
5007
+ primitive: true,
5008
+ },
5009
+ // Union of Lt (titlecase), Lm (modifier), and Lo (other), i.e. any letter not in Ll or Lu.
5010
+ unicodeLtmo: {
5011
+ body: new UnicodeChar('Ltmo'),
5012
+ formals: [],
5013
+ description: 'a Unicode character in Lt, Lm, or Lo',
5014
+ primitive: true,
4981
5015
  },
5016
+
5017
+ // These rules are not truly primitive (they could be written in userland) but are defined
5018
+ // here for bootstrapping purposes.
5019
+ spaces: {
5020
+ body: new Star(new Apply('space')),
5021
+ formals: [],
5022
+ },
5023
+ space: {
5024
+ body: new Range('\x00', ' '),
5025
+ formals: [],
5026
+ description: 'a space',
5027
+ },
5028
+ }
4982
5029
  );
4983
5030
 
4984
5031
  // This method is called from main.js once Ohm has loaded.
4985
- Grammar.initApplicationParser = function(grammar, builderFn) {
5032
+ Grammar.initApplicationParser = function (grammar, builderFn) {
4986
5033
  ohmGrammar$1 = grammar;
4987
5034
  buildGrammar$1 = builderFn;
4988
5035
  };
@@ -5010,7 +5057,7 @@ class GrammarDecl {
5010
5057
  // TODO: The conditional expression below is an ugly hack. It's kind of ok because
5011
5058
  // I doubt anyone will ever try to declare a grammar called `BuiltInRules`. Still,
5012
5059
  // we should try to find a better way to do this.
5013
- this.name === 'BuiltInRules' ? Grammar.ProtoBuiltInRules : Grammar.BuiltInRules,
5060
+ this.name === 'BuiltInRules' ? Grammar.ProtoBuiltInRules : Grammar.BuiltInRules
5014
5061
  );
5015
5062
  }
5016
5063
  return this.superGrammar;
@@ -5078,10 +5125,10 @@ class GrammarDecl {
5078
5125
  // Creates a Grammar instance, and if it passes the sanity checks, returns it.
5079
5126
  build() {
5080
5127
  const grammar = new Grammar(
5081
- this.name,
5082
- this.ensureSuperGrammar(),
5083
- this.rules,
5084
- this.defaultStartRule,
5128
+ this.name,
5129
+ this.ensureSuperGrammar(),
5130
+ this.rules,
5131
+ this.defaultStartRule
5085
5132
  );
5086
5133
  // Initialize internal props that are inherited from the super grammar.
5087
5134
  grammar._matchStateInitializer = grammar.superGrammar._matchStateInitializer;
@@ -5182,7 +5229,7 @@ class Builder {
5182
5229
  if (superGrammar) {
5183
5230
  // `superGrammar` may be a recipe (i.e. an Array), or an actual grammar instance.
5184
5231
  gDecl.withSuperGrammar(
5185
- superGrammar instanceof Grammar ? superGrammar : this.fromRecipe(superGrammar),
5232
+ superGrammar instanceof Grammar ? superGrammar : this.fromRecipe(superGrammar)
5186
5233
  );
5187
5234
  }
5188
5235
  if (defaultStartRule) {
@@ -5206,8 +5253,8 @@ class Builder {
5206
5253
  let source;
5207
5254
  if (gDecl.source && metaInfo && metaInfo.sourceInterval) {
5208
5255
  source = gDecl.source.subInterval(
5209
- metaInfo.sourceInterval[0],
5210
- metaInfo.sourceInterval[1] - metaInfo.sourceInterval[0],
5256
+ metaInfo.sourceInterval[0],
5257
+ metaInfo.sourceInterval[1] - metaInfo.sourceInterval[0]
5211
5258
  );
5212
5259
  }
5213
5260
  gDecl[action](ruleName, formals, body, description, source);
@@ -5302,7 +5349,7 @@ class Builder {
5302
5349
 
5303
5350
  app(ruleName, optParams) {
5304
5351
  if (optParams && optParams.length > 0) {
5305
- optParams = optParams.map(function(param) {
5352
+ optParams = optParams.map(function (param) {
5306
5353
  return param instanceof PExpr ? param : this.fromRecipe(param);
5307
5354
  }, this);
5308
5355
  }
@@ -5314,10 +5361,10 @@ class Builder {
5314
5361
  // `this.currentDecl` and `this.currentRuleName` being set.
5315
5362
  splice(beforeTerms, afterTerms) {
5316
5363
  return new Splice(
5317
- this.currentDecl.superGrammar,
5318
- this.currentRuleName,
5319
- beforeTerms.map(term => this.fromRecipe(term)),
5320
- afterTerms.map(term => this.fromRecipe(term)),
5364
+ this.currentDecl.superGrammar,
5365
+ this.currentRuleName,
5366
+ beforeTerms.map(term => this.fromRecipe(term)),
5367
+ afterTerms.map(term => this.fromRecipe(term))
5321
5368
  );
5322
5369
  }
5323
5370
 
@@ -5458,10 +5505,10 @@ function buildGrammar(match, namespace, optOhmGrammarForTesting) {
5458
5505
  });
5459
5506
 
5460
5507
  return new Splice(
5461
- decl.superGrammar,
5462
- currentRuleName,
5463
- beforeTerms,
5464
- afterTerms,
5508
+ decl.superGrammar,
5509
+ currentRuleName,
5510
+ beforeTerms,
5511
+ afterTerms
5465
5512
  ).withSource(this.source);
5466
5513
  } else {
5467
5514
  return builder.alt(...args).withSource(this.source);
@@ -5606,14 +5653,14 @@ function initBuiltInSemantics(builtInRules) {
5606
5653
  };
5607
5654
 
5608
5655
  Semantics.BuiltInSemantics = Semantics.createSemantics(builtInRules, null).addOperation(
5609
- 'asIteration',
5610
- {
5611
- emptyListOf: actions.empty,
5612
- nonemptyListOf: actions.nonEmpty,
5613
- EmptyListOf: actions.empty,
5614
- NonemptyListOf: actions.nonEmpty,
5615
- _iter: actions.self,
5616
- },
5656
+ 'asIteration',
5657
+ {
5658
+ emptyListOf: actions.empty,
5659
+ nonemptyListOf: actions.nonEmpty,
5660
+ EmptyListOf: actions.empty,
5661
+ NonemptyListOf: actions.nonEmpty,
5662
+ _iter: actions.self,
5663
+ }
5617
5664
  );
5618
5665
  }
5619
5666
 
@@ -5802,12 +5849,12 @@ const applyDedent = new Apply('dedent');
5802
5849
  const newAnyBody = new Splice(BuiltInRules, 'any', [applyIndent, applyDedent], []);
5803
5850
 
5804
5851
  const IndentationSensitive = new Builder()
5805
- .newGrammar('IndentationSensitive')
5806
- .withSuperGrammar(BuiltInRules)
5807
- .define('indent', [], new Indentation(true), INDENT_DESCRIPTION, undefined, true)
5808
- .define('dedent', [], new Indentation(false), DEDENT_DESCRIPTION, undefined, true)
5809
- .extend('any', [], newAnyBody, 'any character', undefined)
5810
- .build();
5852
+ .newGrammar('IndentationSensitive')
5853
+ .withSuperGrammar(BuiltInRules)
5854
+ .define('indent', [], new Indentation(true), INDENT_DESCRIPTION, undefined, true)
5855
+ .define('dedent', [], new Indentation(false), DEDENT_DESCRIPTION, undefined, true)
5856
+ .extend('any', [], newAnyBody, 'any character', undefined)
5857
+ .build();
5811
5858
 
5812
5859
  Object.assign(IndentationSensitive, {
5813
5860
  _matchStateInitializer(state) {
@@ -5840,7 +5887,7 @@ function grammars$1(source, optNamespace) {
5840
5887
  source = source.toString();
5841
5888
  } else {
5842
5889
  throw new TypeError(
5843
- 'Expected string as first argument, got ' + unexpectedObjToString(source),
5890
+ 'Expected string as first argument, got ' + unexpectedObjToString(source)
5844
5891
  );
5845
5892
  }
5846
5893
  }
@@ -5996,9 +6043,59 @@ function extractExamples(grammarsDef) {
5996
6043
  return semantics(matchResult).examples();
5997
6044
  }
5998
6045
 
6046
+ /*
6047
+ To find iter nodes that are derived from the same repetition expression, we
6048
+ look for adjacent iter nodes that have the same source interval and the same
6049
+ number of children.
6050
+
6051
+ A few things to note:
6052
+ - The children of `*` and `+` nodes can't be nullable, so the associated iter
6053
+ nodes always consume some input, and therefore consecutive nodes that have
6054
+ the same interval must come from the same repetition expression.
6055
+ - We *could* mistake `a? b?` for (a b)?`, if neither of them comsume any input.
6056
+ However, for the purposes of this module, those two cases are equivalent
6057
+ anyways, since we only care about finding the correct order of the non-iter
6058
+ nodes, and both interpretations yield the same order.
6059
+ */
6060
+ const isIterSibling = (refNode, n) => {
6061
+ return (
6062
+ n.isIteration() &&
6063
+ n.source.startIdx === refNode.source.startIdx &&
6064
+ n.source.endIdx === refNode.source.endIdx &&
6065
+ n.children.length === refNode.children.length
6066
+ );
6067
+ };
6068
+
6069
+ function recoverSourceOrder(nodes, depth = 0) {
6070
+ const ans = [];
6071
+ for (let i = 0; i < nodes.length; i++) {
6072
+ const n = nodes[i];
6073
+ if (!n.isIteration()) {
6074
+ ans.push(n);
6075
+ continue;
6076
+ }
6077
+
6078
+ // We found an iter node, now find its siblings.
6079
+ const siblings = [n];
6080
+ // Find the first node that's *not* part of the current list.
6081
+ for (let j = i + 1; j < nodes.length && isIterSibling(n, nodes[j]); j++) {
6082
+ siblings.push(nodes[j]);
6083
+ i = j;
6084
+ }
6085
+ const cousins = [];
6086
+ const numRows = siblings[0].children.length;
6087
+ for (let row = 0; row < numRows; row++) {
6088
+ cousins.push(...siblings.map(sib => sib.children[row]));
6089
+ }
6090
+ ans.push(...recoverSourceOrder(cousins, depth + 1));
6091
+ }
6092
+ return ans;
6093
+ }
6094
+
5999
6095
  exports.VisitorFamily = VisitorFamily;
6000
6096
  exports.extractExamples = extractExamples;
6001
6097
  exports.getLineAndColumn = getLineAndColumn;
6002
6098
  exports.getLineAndColumnMessage = getLineAndColumnMessage;
6099
+ exports.recoverSourceOrder = recoverSourceOrder;
6003
6100
  exports.semanticsForToAST = semanticsForToAST;
6004
6101
  exports.toAST = toAST;