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