ohm-js 17.2.0 → 17.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ohm-extras.cjs +517 -471
- package/dist/ohm-extras.js +517 -471
- package/dist/ohm.cjs +510 -464
- package/dist/ohm.cjs.map +1 -1
- package/dist/ohm.js +511 -465
- package/dist/ohm.min.js +1 -1
- package/extras/VisitorFamily.js +9 -9
- package/extras/index.d.ts +1 -1
- package/extras/semantics-toAST.js +1 -1
- package/index.d.ts +24 -4
- package/package.json +4 -4
- package/src/Builder.js +8 -8
- package/src/CaseInsensitiveTerminal.js +3 -3
- package/src/Grammar.js +69 -70
- package/src/GrammarDecl.js +5 -5
- package/src/IndentationSensitive.js +6 -6
- package/src/InputStream.js +3 -0
- package/src/Interval.js +19 -7
- package/src/MatchResult.js +14 -16
- package/src/MatchState.js +17 -17
- package/src/PosInfo.js +7 -7
- package/src/Semantics.js +43 -43
- package/src/Trace.js +19 -19
- package/src/buildGrammar.js +4 -4
- package/src/common.js +9 -9
- package/src/errors.js +36 -36
- package/src/main.js +3 -3
- package/src/nodes.js +4 -4
- package/src/ohm-cmd.js +5 -5
- package/src/pexprs-allowsSkippingPrecedingSpace.js +2 -2
- package/src/pexprs-assertAllApplicationsAreValid.js +11 -11
- package/src/pexprs-assertChoicesHaveUniformArity.js +9 -9
- package/src/pexprs-assertIteratedExprsAreNotNullable.js +7 -7
- package/src/pexprs-eval.js +39 -36
- package/src/pexprs-getArity.js +6 -6
- package/src/pexprs-introduceParams.js +5 -5
- package/src/pexprs-isNullable.js +9 -9
- package/src/pexprs-main.js +12 -4
- package/src/pexprs-outputRecipe.js +15 -15
- package/src/pexprs-substituteParams.js +6 -6
- package/src/pexprs-toArgumentNameList.js +20 -20
- package/src/pexprs-toDisplayString.js +5 -5
- package/src/pexprs-toFailure.js +12 -12
- package/src/pexprs-toString.js +20 -20
- package/src/semanticsDeferredInit.js +8 -8
- package/src/unicode.js +54 -0
- package/src/util.js +3 -3
- package/src/version.js +1 -1
- package/dist/ohm-grammar.js.new +0 -0
- package/src/UnicodeCategories.js +0 -30
package/dist/ohm-extras.cjs
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
483
|
-
|
|
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
|
-
|
|
490
|
-
|
|
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
|
-
|
|
523
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
665
|
-
//
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
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(
|
|
898
|
+
constructor(categoryOrProp) {
|
|
875
899
|
super();
|
|
876
|
-
this.
|
|
877
|
-
|
|
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
|
-
|
|
951
|
-
|
|
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
|
-
|
|
960
|
-
|
|
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
|
-
|
|
969
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1019
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1047
|
-
|
|
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
|
-
|
|
1088
|
+
`applySyntactic is for syntactic rules, but '${ruleName}' is a lexical rule. ` +
|
|
1057
1089
|
syntacticVsLexicalNote,
|
|
1058
|
-
|
|
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
|
-
|
|
1067
|
-
|
|
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
|
-
|
|
1094
|
-
|
|
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
|
-
|
|
1113
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1259
|
-
|
|
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
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
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
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1404
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1547
|
-
|
|
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
|
-
|
|
1570
|
-
|
|
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
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
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
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
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
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
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;
|
|
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
|
-
|
|
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
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2358
|
-
|
|
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
|
-
|
|
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();
|
|
@@ -2539,8 +2584,8 @@ Apply.prototype.reallyEval = function(state) {
|
|
|
2539
2584
|
// Fix the input stream's examinedLength -- it should be the maximum examined length
|
|
2540
2585
|
// across all applications, not just this one.
|
|
2541
2586
|
inputStream.examinedLength = Math.max(
|
|
2542
|
-
|
|
2543
|
-
|
|
2587
|
+
inputStream.examinedLength,
|
|
2588
|
+
origInputStreamExaminedLength
|
|
2544
2589
|
);
|
|
2545
2590
|
|
|
2546
2591
|
state.exitApplication(origPosInfo, value);
|
|
@@ -2548,7 +2593,7 @@ Apply.prototype.reallyEval = function(state) {
|
|
|
2548
2593
|
return succeeded;
|
|
2549
2594
|
};
|
|
2550
2595
|
|
|
2551
|
-
Apply.prototype.evalOnce = function(expr, state) {
|
|
2596
|
+
Apply.prototype.evalOnce = function (expr, state) {
|
|
2552
2597
|
const {inputStream} = state;
|
|
2553
2598
|
const origPos = inputStream.pos;
|
|
2554
2599
|
|
|
@@ -2563,7 +2608,7 @@ Apply.prototype.evalOnce = function(expr, state) {
|
|
|
2563
2608
|
}
|
|
2564
2609
|
};
|
|
2565
2610
|
|
|
2566
|
-
Apply.prototype.growSeedResult = function(body, state, origPos, lrMemoRec, newValue) {
|
|
2611
|
+
Apply.prototype.growSeedResult = function (body, state, origPos, lrMemoRec, newValue) {
|
|
2567
2612
|
if (!newValue) {
|
|
2568
2613
|
return false;
|
|
2569
2614
|
}
|
|
@@ -2581,13 +2626,13 @@ Apply.prototype.growSeedResult = function(body, state, origPos, lrMemoRec, newVa
|
|
|
2581
2626
|
// element in `state.trace`.
|
|
2582
2627
|
const seedTrace = state.trace[state.trace.length - 1];
|
|
2583
2628
|
lrMemoRec.traceEntry = new Trace(
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2629
|
+
state.input,
|
|
2630
|
+
origPos,
|
|
2631
|
+
inputStream.pos,
|
|
2632
|
+
this,
|
|
2633
|
+
true,
|
|
2634
|
+
[newValue],
|
|
2635
|
+
[seedTrace.clone()]
|
|
2591
2636
|
);
|
|
2592
2637
|
}
|
|
2593
2638
|
inputStream.pos = origPos;
|
|
@@ -2607,17 +2652,19 @@ Apply.prototype.growSeedResult = function(body, state, origPos, lrMemoRec, newVa
|
|
|
2607
2652
|
return lrMemoRec.value;
|
|
2608
2653
|
};
|
|
2609
2654
|
|
|
2610
|
-
UnicodeChar.prototype.eval = function(state) {
|
|
2655
|
+
UnicodeChar.prototype.eval = function (state) {
|
|
2611
2656
|
const {inputStream} = state;
|
|
2612
2657
|
const origPos = inputStream.pos;
|
|
2613
|
-
const
|
|
2614
|
-
if (
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2658
|
+
const cp = inputStream.nextCodePoint();
|
|
2659
|
+
if (cp !== undefined && cp <= MAX_CODE_POINT) {
|
|
2660
|
+
const ch = String.fromCodePoint(cp);
|
|
2661
|
+
if (this.pattern.test(ch)) {
|
|
2662
|
+
state.pushBinding(new TerminalNode(ch.length), origPos);
|
|
2663
|
+
return true;
|
|
2664
|
+
}
|
|
2620
2665
|
}
|
|
2666
|
+
state.processFailure(origPos, this);
|
|
2667
|
+
return false;
|
|
2621
2668
|
};
|
|
2622
2669
|
|
|
2623
2670
|
// --------------------------------------------------------------------
|
|
@@ -2633,17 +2680,17 @@ any.getArity =
|
|
|
2633
2680
|
Param.prototype.getArity =
|
|
2634
2681
|
Apply.prototype.getArity =
|
|
2635
2682
|
UnicodeChar.prototype.getArity =
|
|
2636
|
-
function() {
|
|
2683
|
+
function () {
|
|
2637
2684
|
return 1;
|
|
2638
2685
|
};
|
|
2639
2686
|
|
|
2640
|
-
Alt.prototype.getArity = function() {
|
|
2687
|
+
Alt.prototype.getArity = function () {
|
|
2641
2688
|
// This is ok b/c all terms must have the same arity -- this property is
|
|
2642
2689
|
// checked by the Grammar constructor.
|
|
2643
2690
|
return this.terms.length === 0 ? 0 : this.terms[0].getArity();
|
|
2644
2691
|
};
|
|
2645
2692
|
|
|
2646
|
-
Seq.prototype.getArity = function() {
|
|
2693
|
+
Seq.prototype.getArity = function () {
|
|
2647
2694
|
let arity = 0;
|
|
2648
2695
|
for (let idx = 0; idx < this.factors.length; idx++) {
|
|
2649
2696
|
arity += this.factors[idx].getArity();
|
|
@@ -2651,15 +2698,15 @@ Seq.prototype.getArity = function() {
|
|
|
2651
2698
|
return arity;
|
|
2652
2699
|
};
|
|
2653
2700
|
|
|
2654
|
-
Iter.prototype.getArity = function() {
|
|
2701
|
+
Iter.prototype.getArity = function () {
|
|
2655
2702
|
return this.expr.getArity();
|
|
2656
2703
|
};
|
|
2657
2704
|
|
|
2658
|
-
Not.prototype.getArity = function() {
|
|
2705
|
+
Not.prototype.getArity = function () {
|
|
2659
2706
|
return 0;
|
|
2660
2707
|
};
|
|
2661
2708
|
|
|
2662
|
-
Lookahead.prototype.getArity = Lex.prototype.getArity = function() {
|
|
2709
|
+
Lookahead.prototype.getArity = Lex.prototype.getArity = function () {
|
|
2663
2710
|
return this.expr.getArity();
|
|
2664
2711
|
};
|
|
2665
2712
|
|
|
@@ -2682,38 +2729,38 @@ function getMetaInfo(expr, grammarInterval) {
|
|
|
2682
2729
|
|
|
2683
2730
|
PExpr.prototype.outputRecipe = abstract('outputRecipe');
|
|
2684
2731
|
|
|
2685
|
-
any.outputRecipe = function(formals, grammarInterval) {
|
|
2732
|
+
any.outputRecipe = function (formals, grammarInterval) {
|
|
2686
2733
|
return ['any', getMetaInfo(this, grammarInterval)];
|
|
2687
2734
|
};
|
|
2688
2735
|
|
|
2689
|
-
end.outputRecipe = function(formals, grammarInterval) {
|
|
2736
|
+
end.outputRecipe = function (formals, grammarInterval) {
|
|
2690
2737
|
return ['end', getMetaInfo(this, grammarInterval)];
|
|
2691
2738
|
};
|
|
2692
2739
|
|
|
2693
|
-
Terminal.prototype.outputRecipe = function(formals, grammarInterval) {
|
|
2740
|
+
Terminal.prototype.outputRecipe = function (formals, grammarInterval) {
|
|
2694
2741
|
return ['terminal', getMetaInfo(this, grammarInterval), this.obj];
|
|
2695
2742
|
};
|
|
2696
2743
|
|
|
2697
|
-
Range.prototype.outputRecipe = function(formals, grammarInterval) {
|
|
2744
|
+
Range.prototype.outputRecipe = function (formals, grammarInterval) {
|
|
2698
2745
|
return ['range', getMetaInfo(this, grammarInterval), this.from, this.to];
|
|
2699
2746
|
};
|
|
2700
2747
|
|
|
2701
|
-
Param.prototype.outputRecipe = function(formals, grammarInterval) {
|
|
2748
|
+
Param.prototype.outputRecipe = function (formals, grammarInterval) {
|
|
2702
2749
|
return ['param', getMetaInfo(this, grammarInterval), this.index];
|
|
2703
2750
|
};
|
|
2704
2751
|
|
|
2705
|
-
Alt.prototype.outputRecipe = function(formals, grammarInterval) {
|
|
2752
|
+
Alt.prototype.outputRecipe = function (formals, grammarInterval) {
|
|
2706
2753
|
return ['alt', getMetaInfo(this, grammarInterval)].concat(
|
|
2707
|
-
|
|
2754
|
+
this.terms.map(term => term.outputRecipe(formals, grammarInterval))
|
|
2708
2755
|
);
|
|
2709
2756
|
};
|
|
2710
2757
|
|
|
2711
|
-
Extend.prototype.outputRecipe = function(formals, grammarInterval) {
|
|
2758
|
+
Extend.prototype.outputRecipe = function (formals, grammarInterval) {
|
|
2712
2759
|
const extension = this.terms[0]; // [extension, original]
|
|
2713
2760
|
return extension.outputRecipe(formals, grammarInterval);
|
|
2714
2761
|
};
|
|
2715
2762
|
|
|
2716
|
-
Splice.prototype.outputRecipe = function(formals, grammarInterval) {
|
|
2763
|
+
Splice.prototype.outputRecipe = function (formals, grammarInterval) {
|
|
2717
2764
|
const beforeTerms = this.terms.slice(0, this.expansionPos);
|
|
2718
2765
|
const afterTerms = this.terms.slice(this.expansionPos + 1);
|
|
2719
2766
|
return [
|
|
@@ -2724,9 +2771,9 @@ Splice.prototype.outputRecipe = function(formals, grammarInterval) {
|
|
|
2724
2771
|
];
|
|
2725
2772
|
};
|
|
2726
2773
|
|
|
2727
|
-
Seq.prototype.outputRecipe = function(formals, grammarInterval) {
|
|
2774
|
+
Seq.prototype.outputRecipe = function (formals, grammarInterval) {
|
|
2728
2775
|
return ['seq', getMetaInfo(this, grammarInterval)].concat(
|
|
2729
|
-
|
|
2776
|
+
this.factors.map(factor => factor.outputRecipe(formals, grammarInterval))
|
|
2730
2777
|
);
|
|
2731
2778
|
};
|
|
2732
2779
|
|
|
@@ -2736,7 +2783,7 @@ Star.prototype.outputRecipe =
|
|
|
2736
2783
|
Not.prototype.outputRecipe =
|
|
2737
2784
|
Lookahead.prototype.outputRecipe =
|
|
2738
2785
|
Lex.prototype.outputRecipe =
|
|
2739
|
-
function(formals, grammarInterval) {
|
|
2786
|
+
function (formals, grammarInterval) {
|
|
2740
2787
|
return [
|
|
2741
2788
|
this.constructor.name.toLowerCase(),
|
|
2742
2789
|
getMetaInfo(this, grammarInterval),
|
|
@@ -2744,7 +2791,7 @@ Star.prototype.outputRecipe =
|
|
|
2744
2791
|
];
|
|
2745
2792
|
};
|
|
2746
2793
|
|
|
2747
|
-
Apply.prototype.outputRecipe = function(formals, grammarInterval) {
|
|
2794
|
+
Apply.prototype.outputRecipe = function (formals, grammarInterval) {
|
|
2748
2795
|
return [
|
|
2749
2796
|
'app',
|
|
2750
2797
|
getMetaInfo(this, grammarInterval),
|
|
@@ -2753,8 +2800,8 @@ Apply.prototype.outputRecipe = function(formals, grammarInterval) {
|
|
|
2753
2800
|
];
|
|
2754
2801
|
};
|
|
2755
2802
|
|
|
2756
|
-
UnicodeChar.prototype.outputRecipe = function(formals, grammarInterval) {
|
|
2757
|
-
return ['unicodeChar', getMetaInfo(this, grammarInterval), this.
|
|
2803
|
+
UnicodeChar.prototype.outputRecipe = function (formals, grammarInterval) {
|
|
2804
|
+
return ['unicodeChar', getMetaInfo(this, grammarInterval), this.categoryOrProp];
|
|
2758
2805
|
};
|
|
2759
2806
|
|
|
2760
2807
|
// --------------------------------------------------------------------
|
|
@@ -2774,18 +2821,18 @@ any.introduceParams =
|
|
|
2774
2821
|
Range.prototype.introduceParams =
|
|
2775
2822
|
Param.prototype.introduceParams =
|
|
2776
2823
|
UnicodeChar.prototype.introduceParams =
|
|
2777
|
-
function(formals) {
|
|
2824
|
+
function (formals) {
|
|
2778
2825
|
return this;
|
|
2779
2826
|
};
|
|
2780
2827
|
|
|
2781
|
-
Alt.prototype.introduceParams = function(formals) {
|
|
2828
|
+
Alt.prototype.introduceParams = function (formals) {
|
|
2782
2829
|
this.terms.forEach((term, idx, terms) => {
|
|
2783
2830
|
terms[idx] = term.introduceParams(formals);
|
|
2784
2831
|
});
|
|
2785
2832
|
return this;
|
|
2786
2833
|
};
|
|
2787
2834
|
|
|
2788
|
-
Seq.prototype.introduceParams = function(formals) {
|
|
2835
|
+
Seq.prototype.introduceParams = function (formals) {
|
|
2789
2836
|
this.factors.forEach((factor, idx, factors) => {
|
|
2790
2837
|
factors[idx] = factor.introduceParams(formals);
|
|
2791
2838
|
});
|
|
@@ -2796,12 +2843,12 @@ Iter.prototype.introduceParams =
|
|
|
2796
2843
|
Not.prototype.introduceParams =
|
|
2797
2844
|
Lookahead.prototype.introduceParams =
|
|
2798
2845
|
Lex.prototype.introduceParams =
|
|
2799
|
-
function(formals) {
|
|
2846
|
+
function (formals) {
|
|
2800
2847
|
this.expr = this.expr.introduceParams(formals);
|
|
2801
2848
|
return this;
|
|
2802
2849
|
};
|
|
2803
2850
|
|
|
2804
|
-
Apply.prototype.introduceParams = function(formals) {
|
|
2851
|
+
Apply.prototype.introduceParams = function (formals) {
|
|
2805
2852
|
const index = formals.indexOf(this.ruleName);
|
|
2806
2853
|
if (index >= 0) {
|
|
2807
2854
|
if (this.args.length > 0) {
|
|
@@ -2822,7 +2869,7 @@ Apply.prototype.introduceParams = function(formals) {
|
|
|
2822
2869
|
// --------------------------------------------------------------------
|
|
2823
2870
|
|
|
2824
2871
|
// Returns `true` if this parsing expression may accept without consuming any input.
|
|
2825
|
-
PExpr.prototype.isNullable = function(grammar) {
|
|
2872
|
+
PExpr.prototype.isNullable = function (grammar) {
|
|
2826
2873
|
return this._isNullable(grammar, Object.create(null));
|
|
2827
2874
|
};
|
|
2828
2875
|
|
|
@@ -2833,15 +2880,15 @@ any._isNullable =
|
|
|
2833
2880
|
Param.prototype._isNullable =
|
|
2834
2881
|
Plus.prototype._isNullable =
|
|
2835
2882
|
UnicodeChar.prototype._isNullable =
|
|
2836
|
-
function(grammar, memo) {
|
|
2883
|
+
function (grammar, memo) {
|
|
2837
2884
|
return false;
|
|
2838
2885
|
};
|
|
2839
2886
|
|
|
2840
|
-
end._isNullable = function(grammar, memo) {
|
|
2887
|
+
end._isNullable = function (grammar, memo) {
|
|
2841
2888
|
return true;
|
|
2842
2889
|
};
|
|
2843
2890
|
|
|
2844
|
-
Terminal.prototype._isNullable = function(grammar, memo) {
|
|
2891
|
+
Terminal.prototype._isNullable = function (grammar, memo) {
|
|
2845
2892
|
if (typeof this.obj === 'string') {
|
|
2846
2893
|
// This is an over-simplification: it's only correct if the input is a string. If it's an array
|
|
2847
2894
|
// or an object, then the empty string parsing expression is not nullable.
|
|
@@ -2851,11 +2898,11 @@ Terminal.prototype._isNullable = function(grammar, memo) {
|
|
|
2851
2898
|
}
|
|
2852
2899
|
};
|
|
2853
2900
|
|
|
2854
|
-
Alt.prototype._isNullable = function(grammar, memo) {
|
|
2901
|
+
Alt.prototype._isNullable = function (grammar, memo) {
|
|
2855
2902
|
return this.terms.length === 0 || this.terms.some(term => term._isNullable(grammar, memo));
|
|
2856
2903
|
};
|
|
2857
2904
|
|
|
2858
|
-
Seq.prototype._isNullable = function(grammar, memo) {
|
|
2905
|
+
Seq.prototype._isNullable = function (grammar, memo) {
|
|
2859
2906
|
return this.factors.every(factor => factor._isNullable(grammar, memo));
|
|
2860
2907
|
};
|
|
2861
2908
|
|
|
@@ -2863,15 +2910,15 @@ Star.prototype._isNullable =
|
|
|
2863
2910
|
Opt.prototype._isNullable =
|
|
2864
2911
|
Not.prototype._isNullable =
|
|
2865
2912
|
Lookahead.prototype._isNullable =
|
|
2866
|
-
function(grammar, memo) {
|
|
2913
|
+
function (grammar, memo) {
|
|
2867
2914
|
return true;
|
|
2868
2915
|
};
|
|
2869
2916
|
|
|
2870
|
-
Lex.prototype._isNullable = function(grammar, memo) {
|
|
2917
|
+
Lex.prototype._isNullable = function (grammar, memo) {
|
|
2871
2918
|
return this.expr._isNullable(grammar, memo);
|
|
2872
2919
|
};
|
|
2873
2920
|
|
|
2874
|
-
Apply.prototype._isNullable = function(grammar, memo) {
|
|
2921
|
+
Apply.prototype._isNullable = function (grammar, memo) {
|
|
2875
2922
|
const key = this.toMemoKey();
|
|
2876
2923
|
if (!Object.prototype.hasOwnProperty.call(memo, key)) {
|
|
2877
2924
|
const {body} = grammar.rules[this.ruleName];
|
|
@@ -2900,19 +2947,19 @@ any.substituteParams =
|
|
|
2900
2947
|
Terminal.prototype.substituteParams =
|
|
2901
2948
|
Range.prototype.substituteParams =
|
|
2902
2949
|
UnicodeChar.prototype.substituteParams =
|
|
2903
|
-
function(actuals) {
|
|
2950
|
+
function (actuals) {
|
|
2904
2951
|
return this;
|
|
2905
2952
|
};
|
|
2906
2953
|
|
|
2907
|
-
Param.prototype.substituteParams = function(actuals) {
|
|
2954
|
+
Param.prototype.substituteParams = function (actuals) {
|
|
2908
2955
|
return checkNotNull(actuals[this.index]);
|
|
2909
2956
|
};
|
|
2910
2957
|
|
|
2911
|
-
Alt.prototype.substituteParams = function(actuals) {
|
|
2958
|
+
Alt.prototype.substituteParams = function (actuals) {
|
|
2912
2959
|
return new Alt(this.terms.map(term => term.substituteParams(actuals)));
|
|
2913
2960
|
};
|
|
2914
2961
|
|
|
2915
|
-
Seq.prototype.substituteParams = function(actuals) {
|
|
2962
|
+
Seq.prototype.substituteParams = function (actuals) {
|
|
2916
2963
|
return new Seq(this.factors.map(factor => factor.substituteParams(actuals)));
|
|
2917
2964
|
};
|
|
2918
2965
|
|
|
@@ -2920,11 +2967,11 @@ Iter.prototype.substituteParams =
|
|
|
2920
2967
|
Not.prototype.substituteParams =
|
|
2921
2968
|
Lookahead.prototype.substituteParams =
|
|
2922
2969
|
Lex.prototype.substituteParams =
|
|
2923
|
-
function(actuals) {
|
|
2970
|
+
function (actuals) {
|
|
2924
2971
|
return new this.constructor(this.expr.substituteParams(actuals));
|
|
2925
2972
|
};
|
|
2926
2973
|
|
|
2927
|
-
Apply.prototype.substituteParams = function(actuals) {
|
|
2974
|
+
Apply.prototype.substituteParams = function (actuals) {
|
|
2928
2975
|
if (this.args.length === 0) {
|
|
2929
2976
|
// Avoid making a copy of this application, as an optimization
|
|
2930
2977
|
return this;
|
|
@@ -2998,15 +3045,15 @@ function resolveDuplicatedNames(argumentNameList) {
|
|
|
2998
3045
|
// function(firstArgIndex, noDupCheck) { ... }
|
|
2999
3046
|
PExpr.prototype.toArgumentNameList = abstract('toArgumentNameList');
|
|
3000
3047
|
|
|
3001
|
-
any.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3048
|
+
any.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3002
3049
|
return ['any'];
|
|
3003
3050
|
};
|
|
3004
3051
|
|
|
3005
|
-
end.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3052
|
+
end.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3006
3053
|
return ['end'];
|
|
3007
3054
|
};
|
|
3008
3055
|
|
|
3009
|
-
Terminal.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3056
|
+
Terminal.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3010
3057
|
if (typeof this.obj === 'string' && /^[_a-zA-Z0-9]+$/.test(this.obj)) {
|
|
3011
3058
|
// If this terminal is a valid suffix for a JS identifier, just prepend it with '_'
|
|
3012
3059
|
return ['_' + this.obj];
|
|
@@ -3016,7 +3063,7 @@ Terminal.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
|
3016
3063
|
}
|
|
3017
3064
|
};
|
|
3018
3065
|
|
|
3019
|
-
Range.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3066
|
+
Range.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3020
3067
|
let argName = this.from + '_to_' + this.to;
|
|
3021
3068
|
// If the `argName` is not valid then try to prepend a `_`.
|
|
3022
3069
|
if (!isRestrictedJSIdentifier(argName)) {
|
|
@@ -3029,11 +3076,11 @@ Range.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
|
3029
3076
|
return [argName];
|
|
3030
3077
|
};
|
|
3031
3078
|
|
|
3032
|
-
Alt.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3079
|
+
Alt.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3033
3080
|
// `termArgNameLists` is an array of arrays where each row is the
|
|
3034
3081
|
// argument name list that corresponds to a term in this alternation.
|
|
3035
3082
|
const termArgNameLists = this.terms.map(term =>
|
|
3036
|
-
term.toArgumentNameList(firstArgIndex, true)
|
|
3083
|
+
term.toArgumentNameList(firstArgIndex, true)
|
|
3037
3084
|
);
|
|
3038
3085
|
|
|
3039
3086
|
const argumentNameList = [];
|
|
@@ -3053,7 +3100,7 @@ Alt.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
|
3053
3100
|
return argumentNameList;
|
|
3054
3101
|
};
|
|
3055
3102
|
|
|
3056
|
-
Seq.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3103
|
+
Seq.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3057
3104
|
// Generate the argument name list, without worrying about duplicates.
|
|
3058
3105
|
let argumentNameList = [];
|
|
3059
3106
|
this.factors.forEach(factor => {
|
|
@@ -3069,44 +3116,44 @@ Seq.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
|
3069
3116
|
return argumentNameList;
|
|
3070
3117
|
};
|
|
3071
3118
|
|
|
3072
|
-
Iter.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3119
|
+
Iter.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3073
3120
|
const argumentNameList = this.expr
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
exprArgumentString[exprArgumentString.length - 1] === 's'
|
|
3077
|
-
exprArgumentString + 'es'
|
|
3078
|
-
exprArgumentString + 's'
|
|
3079
|
-
|
|
3121
|
+
.toArgumentNameList(firstArgIndex, noDupCheck)
|
|
3122
|
+
.map(exprArgumentString =>
|
|
3123
|
+
exprArgumentString[exprArgumentString.length - 1] === 's'
|
|
3124
|
+
? exprArgumentString + 'es'
|
|
3125
|
+
: exprArgumentString + 's'
|
|
3126
|
+
);
|
|
3080
3127
|
if (!noDupCheck) {
|
|
3081
3128
|
resolveDuplicatedNames(argumentNameList);
|
|
3082
3129
|
}
|
|
3083
3130
|
return argumentNameList;
|
|
3084
3131
|
};
|
|
3085
3132
|
|
|
3086
|
-
Opt.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3133
|
+
Opt.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3087
3134
|
return this.expr.toArgumentNameList(firstArgIndex, noDupCheck).map(argName => {
|
|
3088
3135
|
return 'opt' + argName[0].toUpperCase() + argName.slice(1);
|
|
3089
3136
|
});
|
|
3090
3137
|
};
|
|
3091
3138
|
|
|
3092
|
-
Not.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3139
|
+
Not.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3093
3140
|
return [];
|
|
3094
3141
|
};
|
|
3095
3142
|
|
|
3096
3143
|
Lookahead.prototype.toArgumentNameList = Lex.prototype.toArgumentNameList =
|
|
3097
|
-
function(firstArgIndex, noDupCheck) {
|
|
3144
|
+
function (firstArgIndex, noDupCheck) {
|
|
3098
3145
|
return this.expr.toArgumentNameList(firstArgIndex, noDupCheck);
|
|
3099
3146
|
};
|
|
3100
3147
|
|
|
3101
|
-
Apply.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3148
|
+
Apply.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3102
3149
|
return [this.ruleName];
|
|
3103
3150
|
};
|
|
3104
3151
|
|
|
3105
|
-
UnicodeChar.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3152
|
+
UnicodeChar.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3106
3153
|
return ['$' + firstArgIndex];
|
|
3107
3154
|
};
|
|
3108
3155
|
|
|
3109
|
-
Param.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
3156
|
+
Param.prototype.toArgumentNameList = function (firstArgIndex, noDupCheck) {
|
|
3110
3157
|
return ['param' + this.index];
|
|
3111
3158
|
};
|
|
3112
3159
|
|
|
@@ -3119,7 +3166,7 @@ Param.prototype.toArgumentNameList = function(firstArgIndex, noDupCheck) {
|
|
|
3119
3166
|
// Returns a string representing the PExpr, for use as a UI label, etc.
|
|
3120
3167
|
PExpr.prototype.toDisplayString = abstract('toDisplayString');
|
|
3121
3168
|
|
|
3122
|
-
Alt.prototype.toDisplayString = Seq.prototype.toDisplayString = function() {
|
|
3169
|
+
Alt.prototype.toDisplayString = Seq.prototype.toDisplayString = function () {
|
|
3123
3170
|
if (this.source) {
|
|
3124
3171
|
return this.source.trimmed().contents;
|
|
3125
3172
|
}
|
|
@@ -3135,11 +3182,11 @@ any.toDisplayString =
|
|
|
3135
3182
|
Terminal.prototype.toDisplayString =
|
|
3136
3183
|
Range.prototype.toDisplayString =
|
|
3137
3184
|
Param.prototype.toDisplayString =
|
|
3138
|
-
function() {
|
|
3185
|
+
function () {
|
|
3139
3186
|
return this.toString();
|
|
3140
3187
|
};
|
|
3141
3188
|
|
|
3142
|
-
Apply.prototype.toDisplayString = function() {
|
|
3189
|
+
Apply.prototype.toDisplayString = function () {
|
|
3143
3190
|
if (this.args.length > 0) {
|
|
3144
3191
|
const ps = this.args.map(arg => arg.toDisplayString());
|
|
3145
3192
|
return this.ruleName + '<' + ps.join(',') + '>';
|
|
@@ -3148,8 +3195,8 @@ Apply.prototype.toDisplayString = function() {
|
|
|
3148
3195
|
}
|
|
3149
3196
|
};
|
|
3150
3197
|
|
|
3151
|
-
UnicodeChar.prototype.toDisplayString = function() {
|
|
3152
|
-
return 'Unicode [' + this.
|
|
3198
|
+
UnicodeChar.prototype.toDisplayString = function () {
|
|
3199
|
+
return 'Unicode [' + this.categoryOrProp + '] character';
|
|
3153
3200
|
};
|
|
3154
3201
|
|
|
3155
3202
|
// --------------------------------------------------------------------
|
|
@@ -3252,34 +3299,34 @@ class Failure {
|
|
|
3252
3299
|
|
|
3253
3300
|
PExpr.prototype.toFailure = abstract('toFailure');
|
|
3254
3301
|
|
|
3255
|
-
any.toFailure = function(grammar) {
|
|
3302
|
+
any.toFailure = function (grammar) {
|
|
3256
3303
|
return new Failure(this, 'any object', 'description');
|
|
3257
3304
|
};
|
|
3258
3305
|
|
|
3259
|
-
end.toFailure = function(grammar) {
|
|
3306
|
+
end.toFailure = function (grammar) {
|
|
3260
3307
|
return new Failure(this, 'end of input', 'description');
|
|
3261
3308
|
};
|
|
3262
3309
|
|
|
3263
|
-
Terminal.prototype.toFailure = function(grammar) {
|
|
3310
|
+
Terminal.prototype.toFailure = function (grammar) {
|
|
3264
3311
|
return new Failure(this, this.obj, 'string');
|
|
3265
3312
|
};
|
|
3266
3313
|
|
|
3267
|
-
Range.prototype.toFailure = function(grammar) {
|
|
3314
|
+
Range.prototype.toFailure = function (grammar) {
|
|
3268
3315
|
// TODO: come up with something better
|
|
3269
3316
|
return new Failure(this, JSON.stringify(this.from) + '..' + JSON.stringify(this.to), 'code');
|
|
3270
3317
|
};
|
|
3271
3318
|
|
|
3272
|
-
Not.prototype.toFailure = function(grammar) {
|
|
3319
|
+
Not.prototype.toFailure = function (grammar) {
|
|
3273
3320
|
const description =
|
|
3274
3321
|
this.expr === any ? 'nothing' : 'not ' + this.expr.toFailure(grammar);
|
|
3275
3322
|
return new Failure(this, description, 'description');
|
|
3276
3323
|
};
|
|
3277
3324
|
|
|
3278
|
-
Lookahead.prototype.toFailure = function(grammar) {
|
|
3325
|
+
Lookahead.prototype.toFailure = function (grammar) {
|
|
3279
3326
|
return this.expr.toFailure(grammar);
|
|
3280
3327
|
};
|
|
3281
3328
|
|
|
3282
|
-
Apply.prototype.toFailure = function(grammar) {
|
|
3329
|
+
Apply.prototype.toFailure = function (grammar) {
|
|
3283
3330
|
let {description} = grammar.rules[this.ruleName];
|
|
3284
3331
|
if (!description) {
|
|
3285
3332
|
const article = /^[aeiouAEIOU]/.test(this.ruleName) ? 'an' : 'a';
|
|
@@ -3288,23 +3335,23 @@ Apply.prototype.toFailure = function(grammar) {
|
|
|
3288
3335
|
return new Failure(this, description, 'description');
|
|
3289
3336
|
};
|
|
3290
3337
|
|
|
3291
|
-
UnicodeChar.prototype.toFailure = function(grammar) {
|
|
3292
|
-
return new Failure(this, 'a Unicode [' + this.
|
|
3338
|
+
UnicodeChar.prototype.toFailure = function (grammar) {
|
|
3339
|
+
return new Failure(this, 'a Unicode [' + this.categoryOrProp + '] character', 'description');
|
|
3293
3340
|
};
|
|
3294
3341
|
|
|
3295
|
-
Alt.prototype.toFailure = function(grammar) {
|
|
3342
|
+
Alt.prototype.toFailure = function (grammar) {
|
|
3296
3343
|
const fs = this.terms.map(t => t.toFailure(grammar));
|
|
3297
3344
|
const description = '(' + fs.join(' or ') + ')';
|
|
3298
3345
|
return new Failure(this, description, 'description');
|
|
3299
3346
|
};
|
|
3300
3347
|
|
|
3301
|
-
Seq.prototype.toFailure = function(grammar) {
|
|
3348
|
+
Seq.prototype.toFailure = function (grammar) {
|
|
3302
3349
|
const fs = this.factors.map(f => f.toFailure(grammar));
|
|
3303
3350
|
const description = '(' + fs.join(' ') + ')';
|
|
3304
3351
|
return new Failure(this, description, 'description');
|
|
3305
3352
|
};
|
|
3306
3353
|
|
|
3307
|
-
Iter.prototype.toFailure = function(grammar) {
|
|
3354
|
+
Iter.prototype.toFailure = function (grammar) {
|
|
3308
3355
|
const description = '(' + this.expr.toFailure(grammar) + this.operator + ')';
|
|
3309
3356
|
return new Failure(this, description, 'description');
|
|
3310
3357
|
};
|
|
@@ -3322,55 +3369,55 @@ Iter.prototype.toFailure = function(grammar) {
|
|
|
3322
3369
|
*/
|
|
3323
3370
|
PExpr.prototype.toString = abstract('toString');
|
|
3324
3371
|
|
|
3325
|
-
any.toString = function() {
|
|
3372
|
+
any.toString = function () {
|
|
3326
3373
|
return 'any';
|
|
3327
3374
|
};
|
|
3328
3375
|
|
|
3329
|
-
end.toString = function() {
|
|
3376
|
+
end.toString = function () {
|
|
3330
3377
|
return 'end';
|
|
3331
3378
|
};
|
|
3332
3379
|
|
|
3333
|
-
Terminal.prototype.toString = function() {
|
|
3380
|
+
Terminal.prototype.toString = function () {
|
|
3334
3381
|
return JSON.stringify(this.obj);
|
|
3335
3382
|
};
|
|
3336
3383
|
|
|
3337
|
-
Range.prototype.toString = function() {
|
|
3384
|
+
Range.prototype.toString = function () {
|
|
3338
3385
|
return JSON.stringify(this.from) + '..' + JSON.stringify(this.to);
|
|
3339
3386
|
};
|
|
3340
3387
|
|
|
3341
|
-
Param.prototype.toString = function() {
|
|
3388
|
+
Param.prototype.toString = function () {
|
|
3342
3389
|
return '$' + this.index;
|
|
3343
3390
|
};
|
|
3344
3391
|
|
|
3345
|
-
Lex.prototype.toString = function() {
|
|
3392
|
+
Lex.prototype.toString = function () {
|
|
3346
3393
|
return '#(' + this.expr.toString() + ')';
|
|
3347
3394
|
};
|
|
3348
3395
|
|
|
3349
|
-
Alt.prototype.toString = function() {
|
|
3350
|
-
return this.terms.length === 1
|
|
3351
|
-
this.terms[0].toString()
|
|
3352
|
-
'(' + this.terms.map(term => term.toString()).join(' | ') + ')';
|
|
3396
|
+
Alt.prototype.toString = function () {
|
|
3397
|
+
return this.terms.length === 1
|
|
3398
|
+
? this.terms[0].toString()
|
|
3399
|
+
: '(' + this.terms.map(term => term.toString()).join(' | ') + ')';
|
|
3353
3400
|
};
|
|
3354
3401
|
|
|
3355
|
-
Seq.prototype.toString = function() {
|
|
3356
|
-
return this.factors.length === 1
|
|
3357
|
-
this.factors[0].toString()
|
|
3358
|
-
'(' + this.factors.map(factor => factor.toString()).join(' ') + ')';
|
|
3402
|
+
Seq.prototype.toString = function () {
|
|
3403
|
+
return this.factors.length === 1
|
|
3404
|
+
? this.factors[0].toString()
|
|
3405
|
+
: '(' + this.factors.map(factor => factor.toString()).join(' ') + ')';
|
|
3359
3406
|
};
|
|
3360
3407
|
|
|
3361
|
-
Iter.prototype.toString = function() {
|
|
3408
|
+
Iter.prototype.toString = function () {
|
|
3362
3409
|
return this.expr + this.operator;
|
|
3363
3410
|
};
|
|
3364
3411
|
|
|
3365
|
-
Not.prototype.toString = function() {
|
|
3412
|
+
Not.prototype.toString = function () {
|
|
3366
3413
|
return '~' + this.expr;
|
|
3367
3414
|
};
|
|
3368
3415
|
|
|
3369
|
-
Lookahead.prototype.toString = function() {
|
|
3416
|
+
Lookahead.prototype.toString = function () {
|
|
3370
3417
|
return '&' + this.expr;
|
|
3371
3418
|
};
|
|
3372
3419
|
|
|
3373
|
-
Apply.prototype.toString = function() {
|
|
3420
|
+
Apply.prototype.toString = function () {
|
|
3374
3421
|
if (this.args.length > 0) {
|
|
3375
3422
|
const ps = this.args.map(arg => arg.toString());
|
|
3376
3423
|
return this.ruleName + '<' + ps.join(',') + '>';
|
|
@@ -3379,8 +3426,8 @@ Apply.prototype.toString = function() {
|
|
|
3379
3426
|
}
|
|
3380
3427
|
};
|
|
3381
3428
|
|
|
3382
|
-
UnicodeChar.prototype.toString = function() {
|
|
3383
|
-
return '\\p{' + this.
|
|
3429
|
+
UnicodeChar.prototype.toString = function () {
|
|
3430
|
+
return '\\p{' + this.categoryOrProp + '}';
|
|
3384
3431
|
};
|
|
3385
3432
|
|
|
3386
3433
|
class CaseInsensitiveTerminal extends PExpr {
|
|
@@ -3428,9 +3475,9 @@ class CaseInsensitiveTerminal extends PExpr {
|
|
|
3428
3475
|
|
|
3429
3476
|
toFailure(grammar) {
|
|
3430
3477
|
return new Failure(
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3478
|
+
this,
|
|
3479
|
+
this.obj.toFailure(grammar) + ' (case-insensitive)',
|
|
3480
|
+
'description'
|
|
3434
3481
|
);
|
|
3435
3482
|
}
|
|
3436
3483
|
|
|
@@ -3500,8 +3547,8 @@ class MatchState {
|
|
|
3500
3547
|
posInfo.exit();
|
|
3501
3548
|
|
|
3502
3549
|
this.rightmostFailurePosition = Math.max(
|
|
3503
|
-
|
|
3504
|
-
|
|
3550
|
+
this.rightmostFailurePosition,
|
|
3551
|
+
this._rightmostFailurePositionStack.pop()
|
|
3505
3552
|
);
|
|
3506
3553
|
|
|
3507
3554
|
if (optNode) {
|
|
@@ -3637,9 +3684,9 @@ class MatchState {
|
|
|
3637
3684
|
}
|
|
3638
3685
|
|
|
3639
3686
|
_getRightmostFailureOffset() {
|
|
3640
|
-
return this.rightmostFailurePosition >= 0
|
|
3641
|
-
this.posToOffset(this.rightmostFailurePosition)
|
|
3642
|
-
-1;
|
|
3687
|
+
return this.rightmostFailurePosition >= 0
|
|
3688
|
+
? this.posToOffset(this.rightmostFailurePosition)
|
|
3689
|
+
: -1;
|
|
3643
3690
|
}
|
|
3644
3691
|
|
|
3645
3692
|
// Returns the memoized trace entry for `expr` at `pos`, if one exists, `null` otherwise.
|
|
@@ -3696,8 +3743,8 @@ class MatchState {
|
|
|
3696
3743
|
const memoRecRightmostFailurePosition =
|
|
3697
3744
|
this.inputStream.pos + memoRec.rightmostFailureOffset;
|
|
3698
3745
|
this.rightmostFailurePosition = Math.max(
|
|
3699
|
-
|
|
3700
|
-
|
|
3746
|
+
this.rightmostFailurePosition,
|
|
3747
|
+
memoRecRightmostFailurePosition
|
|
3701
3748
|
);
|
|
3702
3749
|
if (
|
|
3703
3750
|
this.recordedFailures &&
|
|
@@ -3708,8 +3755,8 @@ class MatchState {
|
|
|
3708
3755
|
}
|
|
3709
3756
|
|
|
3710
3757
|
this.inputStream.examinedLength = Math.max(
|
|
3711
|
-
|
|
3712
|
-
|
|
3758
|
+
this.inputStream.examinedLength,
|
|
3759
|
+
memoRec.examinedLength + origPos
|
|
3713
3760
|
);
|
|
3714
3761
|
|
|
3715
3762
|
if (memoRec.value) {
|
|
@@ -3787,7 +3834,7 @@ class MatchState {
|
|
|
3787
3834
|
let rightmostFailures;
|
|
3788
3835
|
if (this.recordedFailures) {
|
|
3789
3836
|
rightmostFailures = Object.keys(this.recordedFailures).map(
|
|
3790
|
-
|
|
3837
|
+
key => this.recordedFailures[key]
|
|
3791
3838
|
);
|
|
3792
3839
|
}
|
|
3793
3840
|
const cst = this._bindings[0];
|
|
@@ -3795,13 +3842,13 @@ class MatchState {
|
|
|
3795
3842
|
cst.grammar = this.grammar;
|
|
3796
3843
|
}
|
|
3797
3844
|
return new MatchResult(
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3845
|
+
this.matcher,
|
|
3846
|
+
this.input,
|
|
3847
|
+
this.startExpr,
|
|
3848
|
+
cst,
|
|
3849
|
+
this._bindingOffsets[0],
|
|
3850
|
+
this.rightmostFailurePosition,
|
|
3851
|
+
rightmostFailures
|
|
3805
3852
|
);
|
|
3806
3853
|
}
|
|
3807
3854
|
|
|
@@ -4114,11 +4161,11 @@ class Semantics {
|
|
|
4114
4161
|
if (superSemantics) {
|
|
4115
4162
|
if (!(grammar.equals(this.super.grammar) || grammar._inheritsFrom(this.super.grammar))) {
|
|
4116
4163
|
throw new Error(
|
|
4117
|
-
|
|
4164
|
+
"Cannot extend a semantics for grammar '" +
|
|
4118
4165
|
this.super.grammar.name +
|
|
4119
4166
|
"' for use with grammar '" +
|
|
4120
4167
|
grammar.name +
|
|
4121
|
-
"' (not a sub-grammar)"
|
|
4168
|
+
"' (not a sub-grammar)"
|
|
4122
4169
|
);
|
|
4123
4170
|
}
|
|
4124
4171
|
this.operations = Object.create(this.super.operations);
|
|
@@ -4127,7 +4174,7 @@ class Semantics {
|
|
|
4127
4174
|
|
|
4128
4175
|
// Assign unique symbols for each of the attributes inherited from the super-semantics so that
|
|
4129
4176
|
// they are memoized independently.
|
|
4130
|
-
|
|
4177
|
+
|
|
4131
4178
|
for (const attributeName in this.attributes) {
|
|
4132
4179
|
Object.defineProperty(this.attributeKeys, attributeName, {
|
|
4133
4180
|
value: uniqueId(attributeName),
|
|
@@ -4156,11 +4203,11 @@ class Semantics {
|
|
|
4156
4203
|
// Throws an exception if one or more of them doesn't.
|
|
4157
4204
|
checkActionDicts() {
|
|
4158
4205
|
let name;
|
|
4159
|
-
|
|
4206
|
+
|
|
4160
4207
|
for (name in this.operations) {
|
|
4161
4208
|
this.operations[name].checkActionDict(this.grammar);
|
|
4162
4209
|
}
|
|
4163
|
-
|
|
4210
|
+
|
|
4164
4211
|
for (name in this.attributes) {
|
|
4165
4212
|
this.attributes[name].checkActionDict(this.grammar);
|
|
4166
4213
|
}
|
|
@@ -4260,9 +4307,9 @@ class Semantics {
|
|
|
4260
4307
|
});
|
|
4261
4308
|
|
|
4262
4309
|
const entry =
|
|
4263
|
-
type === 'operation'
|
|
4264
|
-
new Operation(name, formals, realActionDict, builtInDefault)
|
|
4265
|
-
new Attribute(name, realActionDict, builtInDefault);
|
|
4310
|
+
type === 'operation'
|
|
4311
|
+
? new Operation(name, formals, realActionDict, builtInDefault)
|
|
4312
|
+
: new Attribute(name, realActionDict, builtInDefault);
|
|
4266
4313
|
|
|
4267
4314
|
// The following check is not strictly necessary (it will happen later anyway) but it's better
|
|
4268
4315
|
// to catch errors early.
|
|
@@ -4278,7 +4325,7 @@ class Semantics {
|
|
|
4278
4325
|
// Check that the caller passed the correct number of arguments.
|
|
4279
4326
|
if (arguments.length !== thisThing.formals.length) {
|
|
4280
4327
|
throw new Error(
|
|
4281
|
-
|
|
4328
|
+
'Invalid number of arguments passed to ' +
|
|
4282
4329
|
name +
|
|
4283
4330
|
' ' +
|
|
4284
4331
|
type +
|
|
@@ -4286,7 +4333,7 @@ class Semantics {
|
|
|
4286
4333
|
thisThing.formals.length +
|
|
4287
4334
|
', got ' +
|
|
4288
4335
|
arguments.length +
|
|
4289
|
-
')'
|
|
4336
|
+
')'
|
|
4290
4337
|
);
|
|
4291
4338
|
}
|
|
4292
4339
|
|
|
@@ -4307,7 +4354,7 @@ class Semantics {
|
|
|
4307
4354
|
|
|
4308
4355
|
if (type === 'operation') {
|
|
4309
4356
|
this.Wrapper.prototype[name] = doIt;
|
|
4310
|
-
this.Wrapper.prototype[name].toString = function() {
|
|
4357
|
+
this.Wrapper.prototype[name].toString = function () {
|
|
4311
4358
|
return '[' + name + ' operation]';
|
|
4312
4359
|
};
|
|
4313
4360
|
} else {
|
|
@@ -4329,13 +4376,13 @@ class Semantics {
|
|
|
4329
4376
|
|
|
4330
4377
|
if (!(this.super && name in this.super[typePlural])) {
|
|
4331
4378
|
throw new Error(
|
|
4332
|
-
|
|
4379
|
+
'Cannot extend ' +
|
|
4333
4380
|
type +
|
|
4334
4381
|
" '" +
|
|
4335
4382
|
name +
|
|
4336
4383
|
"': did not inherit an " +
|
|
4337
4384
|
type +
|
|
4338
|
-
' with that name'
|
|
4385
|
+
' with that name'
|
|
4339
4386
|
);
|
|
4340
4387
|
}
|
|
4341
4388
|
if (hasOwnProperty(this[typePlural], name)) {
|
|
@@ -4352,9 +4399,9 @@ class Semantics {
|
|
|
4352
4399
|
});
|
|
4353
4400
|
|
|
4354
4401
|
this[typePlural][name] =
|
|
4355
|
-
type === 'operation'
|
|
4356
|
-
new Operation(name, inheritedFormals, newActionDict)
|
|
4357
|
-
new Attribute(name, newActionDict);
|
|
4402
|
+
type === 'operation'
|
|
4403
|
+
? new Operation(name, inheritedFormals, newActionDict)
|
|
4404
|
+
: new Attribute(name, newActionDict);
|
|
4358
4405
|
|
|
4359
4406
|
// The following check is not strictly necessary (it will happen later anyway) but it's better
|
|
4360
4407
|
// to catch errors early.
|
|
@@ -4367,12 +4414,12 @@ class Semantics {
|
|
|
4367
4414
|
}
|
|
4368
4415
|
if (name in this.operations) {
|
|
4369
4416
|
throw new Error(
|
|
4370
|
-
|
|
4417
|
+
'Cannot add ' + type + " '" + name + "': an operation with that name already exists"
|
|
4371
4418
|
);
|
|
4372
4419
|
}
|
|
4373
4420
|
if (name in this.attributes) {
|
|
4374
4421
|
throw new Error(
|
|
4375
|
-
|
|
4422
|
+
'Cannot add ' + type + " '" + name + "': an attribute with that name already exists"
|
|
4376
4423
|
);
|
|
4377
4424
|
}
|
|
4378
4425
|
}
|
|
@@ -4398,8 +4445,8 @@ function parseSignature(signature, type) {
|
|
|
4398
4445
|
}
|
|
4399
4446
|
|
|
4400
4447
|
const r = Semantics.prototypeGrammar.match(
|
|
4401
|
-
|
|
4402
|
-
type === 'operation' ? 'OperationSignature' : 'AttributeSignature'
|
|
4448
|
+
signature,
|
|
4449
|
+
type === 'operation' ? 'OperationSignature' : 'AttributeSignature'
|
|
4403
4450
|
);
|
|
4404
4451
|
if (r.failed()) {
|
|
4405
4452
|
throw new Error(r.message);
|
|
@@ -4409,7 +4456,7 @@ function parseSignature(signature, type) {
|
|
|
4409
4456
|
}
|
|
4410
4457
|
|
|
4411
4458
|
function newDefaultAction(type, name, doIt) {
|
|
4412
|
-
return function(...children) {
|
|
4459
|
+
return function (...children) {
|
|
4413
4460
|
const thisThing = this._semantics.operations[name] || this._semantics.attributes[name];
|
|
4414
4461
|
const args = thisThing.formals.map(formal => this.args[formal]);
|
|
4415
4462
|
|
|
@@ -4433,12 +4480,12 @@ function newDefaultAction(type, name, doIt) {
|
|
|
4433
4480
|
// Semantics instance. When that function is invoked with a CST node as an argument, it returns
|
|
4434
4481
|
// a wrapper for that node which gives access to the operations and attributes provided by this
|
|
4435
4482
|
// semantics.
|
|
4436
|
-
Semantics.createSemantics = function(grammar, optSuperSemantics) {
|
|
4483
|
+
Semantics.createSemantics = function (grammar, optSuperSemantics) {
|
|
4437
4484
|
const s = new Semantics(
|
|
4438
|
-
|
|
4439
|
-
optSuperSemantics !== undefined
|
|
4440
|
-
optSuperSemantics
|
|
4441
|
-
Semantics.BuiltInSemantics._getSemantics()
|
|
4485
|
+
grammar,
|
|
4486
|
+
optSuperSemantics !== undefined
|
|
4487
|
+
? optSuperSemantics
|
|
4488
|
+
: Semantics.BuiltInSemantics._getSemantics()
|
|
4442
4489
|
);
|
|
4443
4490
|
|
|
4444
4491
|
// To enable clients to invoke a semantics like a function, return a function that acts as a proxy
|
|
@@ -4446,8 +4493,8 @@ Semantics.createSemantics = function(grammar, optSuperSemantics) {
|
|
|
4446
4493
|
const proxy = function ASemantics(matchResult) {
|
|
4447
4494
|
if (!(matchResult instanceof MatchResult)) {
|
|
4448
4495
|
throw new TypeError(
|
|
4449
|
-
|
|
4450
|
-
unexpectedObjToString(matchResult)
|
|
4496
|
+
'Semantics expected a MatchResult, but got ' +
|
|
4497
|
+
unexpectedObjToString(matchResult)
|
|
4451
4498
|
);
|
|
4452
4499
|
}
|
|
4453
4500
|
if (matchResult.failed()) {
|
|
@@ -4457,11 +4504,11 @@ Semantics.createSemantics = function(grammar, optSuperSemantics) {
|
|
|
4457
4504
|
const cst = matchResult._cst;
|
|
4458
4505
|
if (cst.grammar !== grammar) {
|
|
4459
4506
|
throw new Error(
|
|
4460
|
-
|
|
4507
|
+
"Cannot use a MatchResult from grammar '" +
|
|
4461
4508
|
cst.grammar.name +
|
|
4462
4509
|
"' with a semantics for '" +
|
|
4463
4510
|
grammar.name +
|
|
4464
|
-
"'"
|
|
4511
|
+
"'"
|
|
4465
4512
|
);
|
|
4466
4513
|
}
|
|
4467
4514
|
const inputStream = new InputStream(matchResult.input);
|
|
@@ -4469,38 +4516,38 @@ Semantics.createSemantics = function(grammar, optSuperSemantics) {
|
|
|
4469
4516
|
};
|
|
4470
4517
|
|
|
4471
4518
|
// Forward public methods from the proxy to the semantics instance.
|
|
4472
|
-
proxy.addOperation = function(signature, actionDict) {
|
|
4519
|
+
proxy.addOperation = function (signature, actionDict) {
|
|
4473
4520
|
s.addOperationOrAttribute('operation', signature, actionDict);
|
|
4474
4521
|
return proxy;
|
|
4475
4522
|
};
|
|
4476
|
-
proxy.extendOperation = function(name, actionDict) {
|
|
4523
|
+
proxy.extendOperation = function (name, actionDict) {
|
|
4477
4524
|
s.extendOperationOrAttribute('operation', name, actionDict);
|
|
4478
4525
|
return proxy;
|
|
4479
4526
|
};
|
|
4480
|
-
proxy.addAttribute = function(name, actionDict) {
|
|
4527
|
+
proxy.addAttribute = function (name, actionDict) {
|
|
4481
4528
|
s.addOperationOrAttribute('attribute', name, actionDict);
|
|
4482
4529
|
return proxy;
|
|
4483
4530
|
};
|
|
4484
|
-
proxy.extendAttribute = function(name, actionDict) {
|
|
4531
|
+
proxy.extendAttribute = function (name, actionDict) {
|
|
4485
4532
|
s.extendOperationOrAttribute('attribute', name, actionDict);
|
|
4486
4533
|
return proxy;
|
|
4487
4534
|
};
|
|
4488
|
-
proxy._getActionDict = function(operationOrAttributeName) {
|
|
4535
|
+
proxy._getActionDict = function (operationOrAttributeName) {
|
|
4489
4536
|
const action =
|
|
4490
4537
|
s.operations[operationOrAttributeName] || s.attributes[operationOrAttributeName];
|
|
4491
4538
|
if (!action) {
|
|
4492
4539
|
throw new Error(
|
|
4493
|
-
|
|
4540
|
+
'"' +
|
|
4494
4541
|
operationOrAttributeName +
|
|
4495
4542
|
'" is not a valid operation or attribute ' +
|
|
4496
4543
|
'name in this semantics for "' +
|
|
4497
4544
|
grammar.name +
|
|
4498
|
-
'"'
|
|
4545
|
+
'"'
|
|
4499
4546
|
);
|
|
4500
4547
|
}
|
|
4501
4548
|
return action.actionDict;
|
|
4502
4549
|
};
|
|
4503
|
-
proxy._remove = function(operationOrAttributeName) {
|
|
4550
|
+
proxy._remove = function (operationOrAttributeName) {
|
|
4504
4551
|
let semantic;
|
|
4505
4552
|
if (operationOrAttributeName in s.operations) {
|
|
4506
4553
|
semantic = s.operations[operationOrAttributeName];
|
|
@@ -4512,16 +4559,16 @@ Semantics.createSemantics = function(grammar, optSuperSemantics) {
|
|
|
4512
4559
|
delete s.Wrapper.prototype[operationOrAttributeName];
|
|
4513
4560
|
return semantic;
|
|
4514
4561
|
};
|
|
4515
|
-
proxy.getOperationNames = function() {
|
|
4562
|
+
proxy.getOperationNames = function () {
|
|
4516
4563
|
return Object.keys(s.operations);
|
|
4517
4564
|
};
|
|
4518
|
-
proxy.getAttributeNames = function() {
|
|
4565
|
+
proxy.getAttributeNames = function () {
|
|
4519
4566
|
return Object.keys(s.attributes);
|
|
4520
4567
|
};
|
|
4521
|
-
proxy.getGrammar = function() {
|
|
4568
|
+
proxy.getGrammar = function () {
|
|
4522
4569
|
return s.grammar;
|
|
4523
4570
|
};
|
|
4524
|
-
proxy.toRecipe = function(semanticsOnly) {
|
|
4571
|
+
proxy.toRecipe = function (semanticsOnly) {
|
|
4525
4572
|
return s.toRecipe(semanticsOnly);
|
|
4526
4573
|
};
|
|
4527
4574
|
|
|
@@ -4529,7 +4576,7 @@ Semantics.createSemantics = function(grammar, optSuperSemantics) {
|
|
|
4529
4576
|
proxy.toString = s.toString.bind(s);
|
|
4530
4577
|
|
|
4531
4578
|
// Returns the semantics for the proxy.
|
|
4532
|
-
proxy._getSemantics = function() {
|
|
4579
|
+
proxy._getSemantics = function () {
|
|
4533
4580
|
return s;
|
|
4534
4581
|
};
|
|
4535
4582
|
|
|
@@ -4621,8 +4668,8 @@ const SPECIAL_ACTION_NAMES = ['_iter', '_terminal', '_nonterminal', '_default'];
|
|
|
4621
4668
|
|
|
4622
4669
|
function getSortedRuleValues(grammar) {
|
|
4623
4670
|
return Object.keys(grammar.rules)
|
|
4624
|
-
|
|
4625
|
-
|
|
4671
|
+
.sort()
|
|
4672
|
+
.map(name => grammar.rules[name]);
|
|
4626
4673
|
}
|
|
4627
4674
|
|
|
4628
4675
|
// Until ES2019, JSON was not a valid subset of JavaScript because U+2028 (line separator)
|
|
@@ -4643,11 +4690,11 @@ class Grammar {
|
|
|
4643
4690
|
if (optDefaultStartRule) {
|
|
4644
4691
|
if (!(optDefaultStartRule in rules)) {
|
|
4645
4692
|
throw new Error(
|
|
4646
|
-
|
|
4693
|
+
"Invalid start rule: '" +
|
|
4647
4694
|
optDefaultStartRule +
|
|
4648
4695
|
"' is not a rule in grammar '" +
|
|
4649
4696
|
name +
|
|
4650
|
-
"'"
|
|
4697
|
+
"'"
|
|
4651
4698
|
);
|
|
4652
4699
|
}
|
|
4653
4700
|
this.defaultStartRule = optDefaultStartRule;
|
|
@@ -4718,7 +4765,6 @@ class Grammar {
|
|
|
4718
4765
|
_checkTopDownActionDict(what, name, actionDict) {
|
|
4719
4766
|
const problems = [];
|
|
4720
4767
|
|
|
4721
|
-
// eslint-disable-next-line guard-for-in
|
|
4722
4768
|
for (const k in actionDict) {
|
|
4723
4769
|
const v = actionDict[k];
|
|
4724
4770
|
const isSpecialAction = SPECIAL_ACTION_NAMES.includes(k);
|
|
@@ -4748,10 +4794,10 @@ class Grammar {
|
|
|
4748
4794
|
if (problems.length > 0) {
|
|
4749
4795
|
const prettyProblems = problems.map(problem => '- ' + problem);
|
|
4750
4796
|
const error = new Error(
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4797
|
+
[
|
|
4798
|
+
`Found errors in the action dictionary of the '${name}' ${what}:`,
|
|
4799
|
+
...prettyProblems,
|
|
4800
|
+
].join('\n')
|
|
4755
4801
|
);
|
|
4756
4802
|
error.problems = problems;
|
|
4757
4803
|
throw error;
|
|
@@ -4764,9 +4810,9 @@ class Grammar {
|
|
|
4764
4810
|
// All special actions have an expected arity of 0, though all but _terminal
|
|
4765
4811
|
// are expected to use the rest parameter syntax (e.g. `_iter(...children)`).
|
|
4766
4812
|
// 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();
|
|
4813
|
+
return SPECIAL_ACTION_NAMES.includes(actionName)
|
|
4814
|
+
? 0
|
|
4815
|
+
: this.rules[actionName].body.getArity();
|
|
4770
4816
|
}
|
|
4771
4817
|
|
|
4772
4818
|
_inheritsFrom(grammar) {
|
|
@@ -4857,7 +4903,7 @@ class Grammar {
|
|
|
4857
4903
|
sb.append('{');
|
|
4858
4904
|
|
|
4859
4905
|
let first = true;
|
|
4860
|
-
|
|
4906
|
+
|
|
4861
4907
|
for (const ruleName in this.rules) {
|
|
4862
4908
|
const {body} = this.rules[ruleName];
|
|
4863
4909
|
if (first) {
|
|
@@ -4904,10 +4950,10 @@ class Grammar {
|
|
|
4904
4950
|
if (formals.length !== app.args.length) {
|
|
4905
4951
|
const {source} = this.rules[app.ruleName];
|
|
4906
4952
|
throw wrongNumberOfParameters(
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4953
|
+
app.ruleName,
|
|
4954
|
+
formals.length,
|
|
4955
|
+
app.args.length,
|
|
4956
|
+
source
|
|
4911
4957
|
);
|
|
4912
4958
|
}
|
|
4913
4959
|
return app;
|
|
@@ -4926,63 +4972,63 @@ class Grammar {
|
|
|
4926
4972
|
// `digit`, and is implicitly the super-grammar of any grammar whose super-grammar
|
|
4927
4973
|
// isn't specified.
|
|
4928
4974
|
Grammar.ProtoBuiltInRules = new Grammar(
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
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
|
-
},
|
|
4975
|
+
'ProtoBuiltInRules', // name
|
|
4976
|
+
undefined, // supergrammar
|
|
4977
|
+
{
|
|
4978
|
+
any: {
|
|
4979
|
+
body: any,
|
|
4980
|
+
formals: [],
|
|
4981
|
+
description: 'any character',
|
|
4982
|
+
primitive: true,
|
|
4981
4983
|
},
|
|
4984
|
+
end: {
|
|
4985
|
+
body: end,
|
|
4986
|
+
formals: [],
|
|
4987
|
+
description: 'end of input',
|
|
4988
|
+
primitive: true,
|
|
4989
|
+
},
|
|
4990
|
+
|
|
4991
|
+
caseInsensitive: {
|
|
4992
|
+
body: new CaseInsensitiveTerminal(new Param(0)),
|
|
4993
|
+
formals: ['str'],
|
|
4994
|
+
primitive: true,
|
|
4995
|
+
},
|
|
4996
|
+
lower: {
|
|
4997
|
+
body: new UnicodeChar('Ll'),
|
|
4998
|
+
formals: [],
|
|
4999
|
+
description: 'a lowercase letter',
|
|
5000
|
+
primitive: true,
|
|
5001
|
+
},
|
|
5002
|
+
upper: {
|
|
5003
|
+
body: new UnicodeChar('Lu'),
|
|
5004
|
+
formals: [],
|
|
5005
|
+
description: 'an uppercase letter',
|
|
5006
|
+
primitive: true,
|
|
5007
|
+
},
|
|
5008
|
+
// Union of Lt (titlecase), Lm (modifier), and Lo (other), i.e. any letter not in Ll or Lu.
|
|
5009
|
+
unicodeLtmo: {
|
|
5010
|
+
body: new UnicodeChar('Ltmo'),
|
|
5011
|
+
formals: [],
|
|
5012
|
+
description: 'a Unicode character in Lt, Lm, or Lo',
|
|
5013
|
+
primitive: true,
|
|
5014
|
+
},
|
|
5015
|
+
|
|
5016
|
+
// These rules are not truly primitive (they could be written in userland) but are defined
|
|
5017
|
+
// here for bootstrapping purposes.
|
|
5018
|
+
spaces: {
|
|
5019
|
+
body: new Star(new Apply('space')),
|
|
5020
|
+
formals: [],
|
|
5021
|
+
},
|
|
5022
|
+
space: {
|
|
5023
|
+
body: new Range('\x00', ' '),
|
|
5024
|
+
formals: [],
|
|
5025
|
+
description: 'a space',
|
|
5026
|
+
},
|
|
5027
|
+
}
|
|
4982
5028
|
);
|
|
4983
5029
|
|
|
4984
5030
|
// This method is called from main.js once Ohm has loaded.
|
|
4985
|
-
Grammar.initApplicationParser = function(grammar, builderFn) {
|
|
5031
|
+
Grammar.initApplicationParser = function (grammar, builderFn) {
|
|
4986
5032
|
ohmGrammar$1 = grammar;
|
|
4987
5033
|
buildGrammar$1 = builderFn;
|
|
4988
5034
|
};
|
|
@@ -5010,7 +5056,7 @@ class GrammarDecl {
|
|
|
5010
5056
|
// TODO: The conditional expression below is an ugly hack. It's kind of ok because
|
|
5011
5057
|
// I doubt anyone will ever try to declare a grammar called `BuiltInRules`. Still,
|
|
5012
5058
|
// we should try to find a better way to do this.
|
|
5013
|
-
this.name === 'BuiltInRules' ? Grammar.ProtoBuiltInRules : Grammar.BuiltInRules
|
|
5059
|
+
this.name === 'BuiltInRules' ? Grammar.ProtoBuiltInRules : Grammar.BuiltInRules
|
|
5014
5060
|
);
|
|
5015
5061
|
}
|
|
5016
5062
|
return this.superGrammar;
|
|
@@ -5078,10 +5124,10 @@ class GrammarDecl {
|
|
|
5078
5124
|
// Creates a Grammar instance, and if it passes the sanity checks, returns it.
|
|
5079
5125
|
build() {
|
|
5080
5126
|
const grammar = new Grammar(
|
|
5081
|
-
|
|
5082
|
-
|
|
5083
|
-
|
|
5084
|
-
|
|
5127
|
+
this.name,
|
|
5128
|
+
this.ensureSuperGrammar(),
|
|
5129
|
+
this.rules,
|
|
5130
|
+
this.defaultStartRule
|
|
5085
5131
|
);
|
|
5086
5132
|
// Initialize internal props that are inherited from the super grammar.
|
|
5087
5133
|
grammar._matchStateInitializer = grammar.superGrammar._matchStateInitializer;
|
|
@@ -5182,7 +5228,7 @@ class Builder {
|
|
|
5182
5228
|
if (superGrammar) {
|
|
5183
5229
|
// `superGrammar` may be a recipe (i.e. an Array), or an actual grammar instance.
|
|
5184
5230
|
gDecl.withSuperGrammar(
|
|
5185
|
-
superGrammar instanceof Grammar ? superGrammar : this.fromRecipe(superGrammar)
|
|
5231
|
+
superGrammar instanceof Grammar ? superGrammar : this.fromRecipe(superGrammar)
|
|
5186
5232
|
);
|
|
5187
5233
|
}
|
|
5188
5234
|
if (defaultStartRule) {
|
|
@@ -5206,8 +5252,8 @@ class Builder {
|
|
|
5206
5252
|
let source;
|
|
5207
5253
|
if (gDecl.source && metaInfo && metaInfo.sourceInterval) {
|
|
5208
5254
|
source = gDecl.source.subInterval(
|
|
5209
|
-
|
|
5210
|
-
|
|
5255
|
+
metaInfo.sourceInterval[0],
|
|
5256
|
+
metaInfo.sourceInterval[1] - metaInfo.sourceInterval[0]
|
|
5211
5257
|
);
|
|
5212
5258
|
}
|
|
5213
5259
|
gDecl[action](ruleName, formals, body, description, source);
|
|
@@ -5302,7 +5348,7 @@ class Builder {
|
|
|
5302
5348
|
|
|
5303
5349
|
app(ruleName, optParams) {
|
|
5304
5350
|
if (optParams && optParams.length > 0) {
|
|
5305
|
-
optParams = optParams.map(function(param) {
|
|
5351
|
+
optParams = optParams.map(function (param) {
|
|
5306
5352
|
return param instanceof PExpr ? param : this.fromRecipe(param);
|
|
5307
5353
|
}, this);
|
|
5308
5354
|
}
|
|
@@ -5314,10 +5360,10 @@ class Builder {
|
|
|
5314
5360
|
// `this.currentDecl` and `this.currentRuleName` being set.
|
|
5315
5361
|
splice(beforeTerms, afterTerms) {
|
|
5316
5362
|
return new Splice(
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5363
|
+
this.currentDecl.superGrammar,
|
|
5364
|
+
this.currentRuleName,
|
|
5365
|
+
beforeTerms.map(term => this.fromRecipe(term)),
|
|
5366
|
+
afterTerms.map(term => this.fromRecipe(term))
|
|
5321
5367
|
);
|
|
5322
5368
|
}
|
|
5323
5369
|
|
|
@@ -5458,10 +5504,10 @@ function buildGrammar(match, namespace, optOhmGrammarForTesting) {
|
|
|
5458
5504
|
});
|
|
5459
5505
|
|
|
5460
5506
|
return new Splice(
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5507
|
+
decl.superGrammar,
|
|
5508
|
+
currentRuleName,
|
|
5509
|
+
beforeTerms,
|
|
5510
|
+
afterTerms
|
|
5465
5511
|
).withSource(this.source);
|
|
5466
5512
|
} else {
|
|
5467
5513
|
return builder.alt(...args).withSource(this.source);
|
|
@@ -5606,14 +5652,14 @@ function initBuiltInSemantics(builtInRules) {
|
|
|
5606
5652
|
};
|
|
5607
5653
|
|
|
5608
5654
|
Semantics.BuiltInSemantics = Semantics.createSemantics(builtInRules, null).addOperation(
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5655
|
+
'asIteration',
|
|
5656
|
+
{
|
|
5657
|
+
emptyListOf: actions.empty,
|
|
5658
|
+
nonemptyListOf: actions.nonEmpty,
|
|
5659
|
+
EmptyListOf: actions.empty,
|
|
5660
|
+
NonemptyListOf: actions.nonEmpty,
|
|
5661
|
+
_iter: actions.self,
|
|
5662
|
+
}
|
|
5617
5663
|
);
|
|
5618
5664
|
}
|
|
5619
5665
|
|
|
@@ -5802,12 +5848,12 @@ const applyDedent = new Apply('dedent');
|
|
|
5802
5848
|
const newAnyBody = new Splice(BuiltInRules, 'any', [applyIndent, applyDedent], []);
|
|
5803
5849
|
|
|
5804
5850
|
const IndentationSensitive = new Builder()
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5851
|
+
.newGrammar('IndentationSensitive')
|
|
5852
|
+
.withSuperGrammar(BuiltInRules)
|
|
5853
|
+
.define('indent', [], new Indentation(true), INDENT_DESCRIPTION, undefined, true)
|
|
5854
|
+
.define('dedent', [], new Indentation(false), DEDENT_DESCRIPTION, undefined, true)
|
|
5855
|
+
.extend('any', [], newAnyBody, 'any character', undefined)
|
|
5856
|
+
.build();
|
|
5811
5857
|
|
|
5812
5858
|
Object.assign(IndentationSensitive, {
|
|
5813
5859
|
_matchStateInitializer(state) {
|
|
@@ -5840,7 +5886,7 @@ function grammars$1(source, optNamespace) {
|
|
|
5840
5886
|
source = source.toString();
|
|
5841
5887
|
} else {
|
|
5842
5888
|
throw new TypeError(
|
|
5843
|
-
|
|
5889
|
+
'Expected string as first argument, got ' + unexpectedObjToString(source)
|
|
5844
5890
|
);
|
|
5845
5891
|
}
|
|
5846
5892
|
}
|