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