parseman 0.52.0 → 0.54.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/analysis/diagnostics.js +636 -126
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +6191 -6274
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/field-trivia.d.ts +40 -0
- package/dist/combinators/field-trivia.d.ts.map +1 -0
- package/dist/combinators/map.d.ts +19 -2
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +34 -0
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/ref.d.ts +0 -13
- package/dist/combinators/ref.d.ts.map +1 -1
- package/dist/combinators/repeat.d.ts.map +1 -1
- package/dist/combinators/sequence.d.ts.map +1 -1
- package/dist/compiler/borrowed-rules.d.ts +30 -0
- package/dist/compiler/borrowed-rules.d.ts.map +1 -0
- package/dist/compiler/compile-linkable-table.d.ts +1 -1
- package/dist/compiler/fields.d.ts +2 -0
- package/dist/compiler/fields.d.ts.map +1 -1
- package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts +10 -4
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +48 -91
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/coverage.d.ts +1 -1
- package/dist/coverage.d.ts.map +1 -1
- package/dist/cst/reflection.d.ts.map +1 -1
- package/dist/cst/trivia-charscan.d.ts +11 -3
- package/dist/cst/trivia-charscan.d.ts.map +1 -1
- package/dist/cst/trivia-kinds.d.ts +11 -0
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +764 -888
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/evaluator.d.ts +38 -2
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1443 -729
- package/dist/plugin/index.js.map +3 -3
- package/dist/plugin/ir-eval.d.ts +21 -0
- package/dist/plugin/ir-eval.d.ts.map +1 -0
- package/dist/plugin/reducer-resolver.d.ts +6 -0
- package/dist/plugin/reducer-resolver.d.ts.map +1 -1
- package/dist/spec/index.js +555 -6109
- package/dist/spec/index.js.map +3 -3
- package/dist/spec/railroad-lib.d.ts +7 -2
- package/dist/spec/railroad-lib.d.ts.map +1 -1
- package/dist/spec/railroad.d.ts.map +1 -1
- package/dist/table/assemble.d.ts +9 -0
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +11 -4
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/compile.d.ts +16 -0
- package/dist/table/compile.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +1 -1
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts +6 -2
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/field-spec.d.ts +13 -0
- package/dist/table/field-spec.d.ts.map +1 -0
- package/dist/table/index.js +480 -199
- package/dist/table/index.js.map +2 -2
- package/dist/table/scalar-terminal.d.ts +11 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/analysis/duplication.ts +1 -1
- package/src/analysis/rebuild.ts +1 -1
- package/src/combinators/field-trivia.ts +44 -0
- package/src/combinators/map.ts +48 -6
- package/src/combinators/parser.ts +133 -67
- package/src/combinators/ref.ts +10 -1
- package/src/combinators/repeat.ts +6 -1
- package/src/combinators/sequence.ts +9 -1
- package/src/compiler/borrowed-rules.ts +88 -0
- package/src/compiler/compile-linkable-table.ts +1 -1
- package/src/compiler/fields.ts +5 -2
- package/src/compiler/grammar-coverage-ids.ts +35 -6
- package/src/compiler/ir-serialize.ts +19 -119
- package/src/compiler/linker.ts +190 -666
- package/src/coverage.ts +7 -5
- package/src/cst/reflection.ts +6 -1
- package/src/cst/trivia-charscan.ts +17 -56
- package/src/cst/trivia-kinds.ts +24 -8
- package/src/index.ts +1 -0
- package/src/plugin/evaluator.ts +114 -14
- package/src/plugin/index.ts +588 -110
- package/src/plugin/ir-eval.ts +165 -0
- package/src/plugin/reducer-resolver.ts +20 -3
- package/src/spec/railroad-lib.ts +18 -8
- package/src/spec/railroad.ts +3 -4
- package/src/table/assemble.ts +126 -22
- package/src/table/compile-rule-map.ts +18 -8
- package/src/table/compile.ts +61 -0
- package/src/table/emit-assembly.ts +38 -18
- package/src/table/emit.ts +15 -4
- package/src/table/encode.ts +18 -2
- package/src/table/exec.ts +15 -1
- package/src/table/field-spec.ts +17 -0
- package/src/table/scalar-terminal.ts +25 -0
- package/src/types.ts +12 -2
- package/src/version.ts +1 -1
|
@@ -1155,65 +1155,17 @@ function plainRegexSource(p) {
|
|
|
1155
1155
|
const d = p._def;
|
|
1156
1156
|
return d.tag === "regex" && d.flags === "" ? d.source : null;
|
|
1157
1157
|
}
|
|
1158
|
-
var visitSpec0;
|
|
1159
|
-
var visitSpec1;
|
|
1160
|
-
var visitSpec2;
|
|
1161
|
-
var visitSpec3;
|
|
1162
|
-
var visitValue0;
|
|
1163
|
-
var visitValue1;
|
|
1164
|
-
var visitValue2;
|
|
1165
|
-
var visitValue3;
|
|
1166
1158
|
function commonLabeledTriviaVisitor(spec) {
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
if (spec === visitSpec2) return visitValue2;
|
|
1170
|
-
if (spec === visitSpec3) return visitValue3;
|
|
1171
|
-
const sources = spec.minRepeats <= 1 ? spec.arms.map((arm) => plainRegexSource(arm.parser)) : [];
|
|
1172
|
-
const visitor = commonCssTriviaVisitor(sources);
|
|
1173
|
-
visitSpec3 = visitSpec2;
|
|
1174
|
-
visitValue3 = visitValue2;
|
|
1175
|
-
visitSpec2 = visitSpec1;
|
|
1176
|
-
visitValue2 = visitValue1;
|
|
1177
|
-
visitSpec1 = visitSpec0;
|
|
1178
|
-
visitValue1 = visitValue0;
|
|
1179
|
-
visitSpec0 = spec;
|
|
1180
|
-
visitValue0 = visitor;
|
|
1181
|
-
return visitor;
|
|
1182
|
-
}
|
|
1183
|
-
var armSpec0;
|
|
1184
|
-
var armSpec1;
|
|
1185
|
-
var armSpec2;
|
|
1186
|
-
var armSpec3;
|
|
1187
|
-
var armValue0;
|
|
1188
|
-
var armValue1;
|
|
1189
|
-
var armValue2;
|
|
1190
|
-
var armValue3;
|
|
1159
|
+
return commonCssTriviaVisitor(spec.minRepeats <= 1 ? spec.arms.map((arm) => plainRegexSource(arm.parser)) : []);
|
|
1160
|
+
}
|
|
1191
1161
|
function charArmsFor(spec) {
|
|
1192
|
-
if (spec
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
arms = null;
|
|
1199
|
-
} else {
|
|
1200
|
-
for (const arm of spec.arms) {
|
|
1201
|
-
const c = classifyParser(arm.parser);
|
|
1202
|
-
if (!c) {
|
|
1203
|
-
arms = null;
|
|
1204
|
-
break;
|
|
1205
|
-
}
|
|
1206
|
-
arms.push(c);
|
|
1207
|
-
}
|
|
1162
|
+
if (spec.minRepeats > 1) return null;
|
|
1163
|
+
const arms = [];
|
|
1164
|
+
for (const arm of spec.arms) {
|
|
1165
|
+
const c = classifyParser(arm.parser);
|
|
1166
|
+
if (!c) return null;
|
|
1167
|
+
arms.push(c);
|
|
1208
1168
|
}
|
|
1209
|
-
armSpec3 = armSpec2;
|
|
1210
|
-
armValue3 = armValue2;
|
|
1211
|
-
armSpec2 = armSpec1;
|
|
1212
|
-
armValue2 = armValue1;
|
|
1213
|
-
armSpec1 = armSpec0;
|
|
1214
|
-
armValue1 = armValue0;
|
|
1215
|
-
armSpec0 = spec;
|
|
1216
|
-
armValue0 = arms;
|
|
1217
1169
|
return arms;
|
|
1218
1170
|
}
|
|
1219
1171
|
function charTriviaEnd(input, cur, arms) {
|
|
@@ -1329,12 +1281,16 @@ function analyzeLabeledTrivia(trivia2) {
|
|
|
1329
1281
|
}
|
|
1330
1282
|
arms.push({ label: peeled.label, kindIndex: 0, parser: peeled.parser });
|
|
1331
1283
|
}
|
|
1332
|
-
|
|
1284
|
+
return cacheLabeledTrivia(trivia2, labeledTriviaSpec(arms, minRepeats));
|
|
1285
|
+
}
|
|
1286
|
+
function labeledTriviaSpec(arms, minRepeats) {
|
|
1287
|
+
return {
|
|
1333
1288
|
labels: arms.map((a) => a.label),
|
|
1334
1289
|
arms,
|
|
1335
|
-
minRepeats
|
|
1290
|
+
minRepeats,
|
|
1291
|
+
visitor: commonLabeledTriviaVisitor({ arms, minRepeats }),
|
|
1292
|
+
charArms: charArmsFor({ arms, minRepeats })
|
|
1336
1293
|
};
|
|
1337
|
-
return cacheLabeledTrivia(trivia2, spec);
|
|
1338
1294
|
}
|
|
1339
1295
|
function matchArmAt(input, pos, arm, state) {
|
|
1340
1296
|
if (!startsFirstSet(arm, input, pos)) return null;
|
|
@@ -1364,7 +1320,7 @@ function scanLabeledTriviaChunks(input, cur, spec, state) {
|
|
|
1364
1320
|
return { end: pos, chunks };
|
|
1365
1321
|
}
|
|
1366
1322
|
function scanLabeledTriviaEnd(input, cur, spec, state) {
|
|
1367
|
-
const chars =
|
|
1323
|
+
const chars = spec.charArms;
|
|
1368
1324
|
if (chars !== null) return charTriviaEnd(input, cur, chars);
|
|
1369
1325
|
let pos = cur;
|
|
1370
1326
|
let count = 0;
|
|
@@ -1382,9 +1338,9 @@ function scanLabeledTriviaEnd(input, cur, spec, state) {
|
|
|
1382
1338
|
}
|
|
1383
1339
|
function visitLabeledTrivia(input, cur, spec, state, visit) {
|
|
1384
1340
|
if (spec.minRepeats > 1) return void 0;
|
|
1385
|
-
const common =
|
|
1341
|
+
const common = spec.visitor;
|
|
1386
1342
|
if (common !== null) return common(input, cur, visit);
|
|
1387
|
-
const chars =
|
|
1343
|
+
const chars = spec.charArms;
|
|
1388
1344
|
if (chars !== null) return charTriviaVisit(input, cur, chars, visit);
|
|
1389
1345
|
let pos = cur;
|
|
1390
1346
|
let count = 0;
|
|
@@ -1451,7 +1407,7 @@ function resolveAdjacencyKindMask(trivia2, kinds) {
|
|
|
1451
1407
|
return mask;
|
|
1452
1408
|
}
|
|
1453
1409
|
function triviaKindMaskAt(input, pos, spec, state) {
|
|
1454
|
-
const chars =
|
|
1410
|
+
const chars = spec.charArms;
|
|
1455
1411
|
if (chars !== null) return charTriviaKindMask(input, pos, chars);
|
|
1456
1412
|
let cur = pos;
|
|
1457
1413
|
let mask = 0;
|
|
@@ -3252,6 +3208,53 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3252
3208
|
return false;
|
|
3253
3209
|
}
|
|
3254
3210
|
}
|
|
3211
|
+
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
3212
|
+
if (seen.has(p)) return false;
|
|
3213
|
+
seen.add(p);
|
|
3214
|
+
const d = p._def;
|
|
3215
|
+
switch (d.tag) {
|
|
3216
|
+
case "node":
|
|
3217
|
+
return d.build !== void 0 || hasDirectBuildDef(d.parser, seen);
|
|
3218
|
+
case "lazy": {
|
|
3219
|
+
try {
|
|
3220
|
+
return hasDirectBuildDef(d.thunk(), seen);
|
|
3221
|
+
} catch {
|
|
3222
|
+
return false;
|
|
3223
|
+
}
|
|
3224
|
+
}
|
|
3225
|
+
case "grammar":
|
|
3226
|
+
case "trivia":
|
|
3227
|
+
case "token":
|
|
3228
|
+
case "leaf":
|
|
3229
|
+
case "label":
|
|
3230
|
+
case "field":
|
|
3231
|
+
case "optional":
|
|
3232
|
+
case "many":
|
|
3233
|
+
case "oneOrMore":
|
|
3234
|
+
case "attempt":
|
|
3235
|
+
case "not":
|
|
3236
|
+
case "peek":
|
|
3237
|
+
case "withCtx":
|
|
3238
|
+
case "expect":
|
|
3239
|
+
case "transform":
|
|
3240
|
+
return hasDirectBuildDef(d.parser, seen);
|
|
3241
|
+
case "sequence":
|
|
3242
|
+
case "choice":
|
|
3243
|
+
return d.parsers.some((x) => hasDirectBuildDef(x, seen));
|
|
3244
|
+
case "dispatch":
|
|
3245
|
+
return hasDirectBuildDef(d.selector, seen) || d.cases.some((x) => hasDirectBuildDef(x.parser, seen)) || (d.matchers ? d.matchers.some((x) => hasDirectBuildDef(x.parser, seen)) : false) || (d.otherwise ? hasDirectBuildDef(d.otherwise, seen) : false);
|
|
3246
|
+
case "sepBy":
|
|
3247
|
+
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.separator, seen);
|
|
3248
|
+
case "scanTo":
|
|
3249
|
+
return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen)) || d.recoverAt !== void 0 && hasDirectBuildDef(d.recoverAt, seen) || d.stopAt !== void 0 && hasDirectBuildDef(d.stopAt, seen);
|
|
3250
|
+
case "recover":
|
|
3251
|
+
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.sentinel, seen);
|
|
3252
|
+
case "routed":
|
|
3253
|
+
return d.fallback ? hasDirectBuildDef(d.fallback, seen) : false;
|
|
3254
|
+
default:
|
|
3255
|
+
return false;
|
|
3256
|
+
}
|
|
3257
|
+
}
|
|
3255
3258
|
function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve) {
|
|
3256
3259
|
if (seen.has(p)) return false;
|
|
3257
3260
|
seen.add(p);
|
|
@@ -4153,7 +4156,7 @@ function buildFieldMap(captures) {
|
|
|
4153
4156
|
if (!captures?.length) return void 0;
|
|
4154
4157
|
const out = {};
|
|
4155
4158
|
for (const cap of captures) {
|
|
4156
|
-
const entry = { value: cap.value, span: cap.span };
|
|
4159
|
+
const entry = cap.leading === void 0 ? { value: cap.value, span: cap.span } : { value: cap.value, span: cap.span, leading: cap.leading, trailing: cap.trailing };
|
|
4157
4160
|
const current = out[cap.name];
|
|
4158
4161
|
if (current === void 0) out[cap.name] = entry;
|
|
4159
4162
|
else if (Array.isArray(current)) current.push(entry);
|
|
@@ -4162,6 +4165,23 @@ function buildFieldMap(captures) {
|
|
|
4162
4165
|
return out;
|
|
4163
4166
|
}
|
|
4164
4167
|
|
|
4168
|
+
// src/combinators/field-trivia.ts
|
|
4169
|
+
var LEAD = { at: -1 };
|
|
4170
|
+
var FIELD_LEADING_TRIVIA = 1;
|
|
4171
|
+
var FIELD_TRAILING_TRIVIA = 2;
|
|
4172
|
+
function triviaFieldCapture(name, value, input, start, end, leadFrom, trailEnd) {
|
|
4173
|
+
return {
|
|
4174
|
+
name,
|
|
4175
|
+
value,
|
|
4176
|
+
span: { start, end },
|
|
4177
|
+
leading: leadFrom >= 0 && leadFrom < start ? input.slice(leadFrom, start) : "",
|
|
4178
|
+
trailing: trailEnd > end ? input.slice(end, trailEnd) : ""
|
|
4179
|
+
};
|
|
4180
|
+
}
|
|
4181
|
+
function leadsTrivia(p) {
|
|
4182
|
+
return p._def.tag === "field" && p._def.leadingTrivia === true;
|
|
4183
|
+
}
|
|
4184
|
+
|
|
4165
4185
|
// src/combinators/dispatch.ts
|
|
4166
4186
|
function parserUsesRouted(parser2, seen = /* @__PURE__ */ new Set()) {
|
|
4167
4187
|
if (seen.has(parser2)) return false;
|
|
@@ -5130,6 +5150,7 @@ function unwrapSeparator(separator) {
|
|
|
5130
5150
|
}
|
|
5131
5151
|
function sepBy(combinator, separatorArg, opts = {}) {
|
|
5132
5152
|
const { sep: separator, keep: keepSeparators } = unwrapSeparator(separatorArg);
|
|
5153
|
+
const separatorLeads = leadsTrivia(separator);
|
|
5133
5154
|
const { min, max } = resolveBounds("sepBy()", opts);
|
|
5134
5155
|
const trailing = opts.trailing ?? "forbid";
|
|
5135
5156
|
const meta = {
|
|
@@ -5194,7 +5215,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
5194
5215
|
// this option surface already; parity is held by test/parity, not by hope.
|
|
5195
5216
|
...keepSeparators ? { keepSeparators: true } : {}
|
|
5196
5217
|
},
|
|
5197
|
-
_parseScalar: keepSeparators ? void 0 : parseScalar,
|
|
5218
|
+
_parseScalar: keepSeparators || separatorLeads ? void 0 : parseScalar,
|
|
5198
5219
|
parse(input, pos, ctx) {
|
|
5199
5220
|
const first = combinator.parse(input, pos, ctx);
|
|
5200
5221
|
const values = [];
|
|
@@ -5226,6 +5247,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
5226
5247
|
sepPos = advanceTrivia(input, cur, ctx);
|
|
5227
5248
|
}
|
|
5228
5249
|
}
|
|
5250
|
+
if (separatorLeads) LEAD.at = cur;
|
|
5229
5251
|
const sep = separator.parse(input, sepPos, ctx);
|
|
5230
5252
|
if (!sep.ok) {
|
|
5231
5253
|
rollbackTrivia(ctx, loopMark);
|
|
@@ -5377,16 +5399,41 @@ function label(name, combinator) {
|
|
|
5377
5399
|
}
|
|
5378
5400
|
};
|
|
5379
5401
|
}
|
|
5380
|
-
function field(name, combinator) {
|
|
5402
|
+
function field(name, combinator, opts) {
|
|
5403
|
+
const leadingTrivia = opts?.leadingTrivia === true;
|
|
5404
|
+
const trailingTrivia = opts?.trailingTrivia === true;
|
|
5405
|
+
if (!leadingTrivia && !trailingTrivia) {
|
|
5406
|
+
return {
|
|
5407
|
+
_tag: combinator._tag,
|
|
5408
|
+
_meta: combinator._meta,
|
|
5409
|
+
_def: { tag: "field", name, parser: combinator },
|
|
5410
|
+
parse(input, pos, ctx) {
|
|
5411
|
+
const result = combinator.parse(input, pos, ctx);
|
|
5412
|
+
if (!result.ok) return result;
|
|
5413
|
+
ctx._fields?.push({ name, value: result.value, span: result.span });
|
|
5414
|
+
return result;
|
|
5415
|
+
}
|
|
5416
|
+
};
|
|
5417
|
+
}
|
|
5381
5418
|
return {
|
|
5382
5419
|
_tag: combinator._tag,
|
|
5383
5420
|
_meta: combinator._meta,
|
|
5384
|
-
_def: {
|
|
5421
|
+
_def: {
|
|
5422
|
+
tag: "field",
|
|
5423
|
+
name,
|
|
5424
|
+
parser: combinator,
|
|
5425
|
+
...leadingTrivia ? { leadingTrivia: true } : {},
|
|
5426
|
+
...trailingTrivia ? { trailingTrivia: true } : {}
|
|
5427
|
+
},
|
|
5385
5428
|
parse(input, pos, ctx) {
|
|
5429
|
+
const leadFrom = LEAD.at;
|
|
5430
|
+
LEAD.at = -1;
|
|
5386
5431
|
const result = combinator.parse(input, pos, ctx);
|
|
5387
5432
|
if (!result.ok) return result;
|
|
5388
|
-
|
|
5389
|
-
|
|
5433
|
+
const end = result.span.end;
|
|
5434
|
+
const trailEnd = trailingTrivia && ctx.trivia ? consumeTrivia(input, end, ctx) : end;
|
|
5435
|
+
ctx._fields?.push(triviaFieldCapture(name, result.value, input, result.span.start, end, leadingTrivia ? leadFrom : -1, trailEnd));
|
|
5436
|
+
return trailEnd === end ? result : { ok: true, value: result.value, span: { start: result.span.start, end: trailEnd } };
|
|
5390
5437
|
}
|
|
5391
5438
|
};
|
|
5392
5439
|
}
|
|
@@ -6531,6 +6578,16 @@ var Encoder = class {
|
|
|
6531
6578
|
this.kIndex.set(key, i);
|
|
6532
6579
|
return i;
|
|
6533
6580
|
}
|
|
6581
|
+
fieldSpecIndex = /* @__PURE__ */ new Map();
|
|
6582
|
+
fieldSpecSlot(name, bits) {
|
|
6583
|
+
const key = JSON.stringify([name, bits]);
|
|
6584
|
+
const hit = this.fieldSpecIndex.get(key);
|
|
6585
|
+
if (hit !== void 0) return hit;
|
|
6586
|
+
const i = this.k.length;
|
|
6587
|
+
this.k.push([name, bits]);
|
|
6588
|
+
this.fieldSpecIndex.set(key, i);
|
|
6589
|
+
return i;
|
|
6590
|
+
}
|
|
6534
6591
|
/**
|
|
6535
6592
|
* A `notAdjacent({ kinds })` filter, pooled by its CONTENTS.
|
|
6536
6593
|
*
|
|
@@ -7151,8 +7208,10 @@ var Encoder = class {
|
|
|
7151
7208
|
for (let i = 0; i < arms.length; i++) this.code[head + 6 + i] = arms[i];
|
|
7152
7209
|
return head;
|
|
7153
7210
|
}
|
|
7154
|
-
case "field":
|
|
7155
|
-
|
|
7211
|
+
case "field": {
|
|
7212
|
+
const bits = (d.leadingTrivia === true ? FIELD_LEADING_TRIVIA : 0) | (d.trailingTrivia === true ? FIELD_TRAILING_TRIVIA : 0);
|
|
7213
|
+
return this.emit(OP_FIELD, bits === 0 ? this.constant(d.name) : this.fieldSpecSlot(d.name, bits), this.node(d.parser).ip);
|
|
7214
|
+
}
|
|
7156
7215
|
case "lazy": {
|
|
7157
7216
|
const refName = p._ruleName;
|
|
7158
7217
|
const winner = refName === void 0 ? void 0 : this.winners?.[refName];
|
|
@@ -8825,6 +8884,26 @@ function leadingLiteralFamily(code, constants, ip, minDepth = 2, limit = 4) {
|
|
|
8825
8884
|
};
|
|
8826
8885
|
return walk(ip, 0);
|
|
8827
8886
|
}
|
|
8887
|
+
function largeChoiceLiteralPretest(code, constants, armIp) {
|
|
8888
|
+
const child = leadingScalarTerminal(code, armIp, 2, true, true);
|
|
8889
|
+
if (child >= 0) {
|
|
8890
|
+
const spec = constants[code[child + 1]];
|
|
8891
|
+
if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) return [child];
|
|
8892
|
+
}
|
|
8893
|
+
const family = leadingLiteralFamily(code, constants, armIp);
|
|
8894
|
+
return family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
8895
|
+
const value = constants[code[terminal + 1]];
|
|
8896
|
+
return typeof value === "string" && value.length >= 2;
|
|
8897
|
+
}) ? family : void 0;
|
|
8898
|
+
}
|
|
8899
|
+
|
|
8900
|
+
// src/table/field-spec.ts
|
|
8901
|
+
function fieldSpec(slot) {
|
|
8902
|
+
return Array.isArray(slot) ? { name: slot[0], bits: slot[1] } : { name: slot, bits: 0 };
|
|
8903
|
+
}
|
|
8904
|
+
function leadingTriviaFieldAt(code, k, ip) {
|
|
8905
|
+
return code[ip] === OP_FIELD && (fieldSpec(k[code[ip + 1]]).bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
8906
|
+
}
|
|
8828
8907
|
|
|
8829
8908
|
// src/table/emit-assembly.ts
|
|
8830
8909
|
var Unemittable = class extends Error {
|
|
@@ -8899,7 +8978,11 @@ var EMITTED_PARAMS = [
|
|
|
8899
8978
|
// Appended for old precompiled-factory ABI: old factories ignore it.
|
|
8900
8979
|
"adjacencyHolds",
|
|
8901
8980
|
// Appended for selected composite lexical programs; old factories ignore it.
|
|
8902
|
-
"LEXPROG"
|
|
8981
|
+
"LEXPROG",
|
|
8982
|
+
// Appended for trivia-attributing fields (`field(…, { leadingTrivia })`);
|
|
8983
|
+
// old factories ignore them.
|
|
8984
|
+
"LEAD",
|
|
8985
|
+
"triviaFieldCapture"
|
|
8903
8986
|
];
|
|
8904
8987
|
var RUNTIME_PRELUDE = `
|
|
8905
8988
|
let _pfScan=null
|
|
@@ -9159,20 +9242,12 @@ function emitAssemblySource(t2, prog, cfg, extraIps = [], staticBuild = false) {
|
|
|
9159
9242
|
if (child >= 0) scalarSpecs.add(code[child + 1]);
|
|
9160
9243
|
continue;
|
|
9161
9244
|
}
|
|
9162
|
-
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
|
|
9166
|
-
continue;
|
|
9167
|
-
}
|
|
9168
|
-
}
|
|
9169
|
-
const family = leadingLiteralFamily(code, k, armIp);
|
|
9170
|
-
if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
9171
|
-
const value = k[code[terminal + 1]];
|
|
9172
|
-
return typeof value === "string" && value.length >= 2;
|
|
9173
|
-
})) {
|
|
9174
|
-
largeChoiceLiteralFamilies.set(armIp, family);
|
|
9245
|
+
const literals = largeChoiceLiteralPretest(code, k, armIp);
|
|
9246
|
+
if (literals !== void 0 && literals.length === 1 && literals[0] === child) {
|
|
9247
|
+
largeChoiceScalarSpecs.add(code[child + 1]);
|
|
9248
|
+
continue;
|
|
9175
9249
|
}
|
|
9250
|
+
if (literals !== void 0) largeChoiceLiteralFamilies.set(armIp, literals);
|
|
9176
9251
|
const sequence6 = leadingScalarSequence(code, armIp);
|
|
9177
9252
|
if (sequence6 !== void 0 && (sequence6.trivia < 0 || swapLegal && t2.triviaScan[sequence6.trivia] != null)) {
|
|
9178
9253
|
largeChoiceScalarSequences.set(armIp, sequence6);
|
|
@@ -9596,14 +9671,31 @@ return v
|
|
|
9596
9671
|
}`;
|
|
9597
9672
|
}
|
|
9598
9673
|
case OP_FIELD: {
|
|
9599
|
-
const
|
|
9674
|
+
const spec = fieldSpec(k[code[ip + 1]]);
|
|
9675
|
+
const name = q(spec.name);
|
|
9600
9676
|
const child = link(code[ip + 2]);
|
|
9601
|
-
|
|
9677
|
+
if (spec.bits === 0) {
|
|
9678
|
+
return `${head}
|
|
9602
9679
|
const v=${child}(input,pos,ctx)
|
|
9603
9680
|
if(v===FAIL)return FAIL
|
|
9604
9681
|
const f=ctx._fields
|
|
9605
9682
|
if(f!==undefined)f.push({name:${name},value:v,span:{start:pos,end:EC.e}})
|
|
9606
9683
|
return v
|
|
9684
|
+
}`;
|
|
9685
|
+
}
|
|
9686
|
+
const leading = (spec.bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
9687
|
+
const trailing = (spec.bits & FIELD_TRAILING_TRIVIA) !== 0;
|
|
9688
|
+
return `${head}
|
|
9689
|
+
const lf=${leading ? "LEAD.at" : "-1"}
|
|
9690
|
+
LEAD.at=-1
|
|
9691
|
+
const v=${child}(input,pos,ctx)
|
|
9692
|
+
if(v===FAIL)return FAIL
|
|
9693
|
+
const e=EC.e
|
|
9694
|
+
const te=${trailing ? "ctx.trivia!==undefined?consumeTrivia(input,e,ctx):e" : "e"}
|
|
9695
|
+
const f=ctx._fields
|
|
9696
|
+
if(f!==undefined)f.push(triviaFieldCapture(${name},v,input,pos,e,lf,te))
|
|
9697
|
+
EC.e=te
|
|
9698
|
+
return v
|
|
9607
9699
|
}`;
|
|
9608
9700
|
}
|
|
9609
9701
|
case OP_EXPECT: {
|
|
@@ -9899,7 +9991,10 @@ return v
|
|
|
9899
9991
|
`if(!adjacencyHolds(input,cur,ctx,${negated ? "true" : "false"},${kinds})){ctx._fe=cur;ctx._fx=${expected};return FAIL}`,
|
|
9900
9992
|
`${vn}=null`
|
|
9901
9993
|
);
|
|
9902
|
-
} else
|
|
9994
|
+
} else {
|
|
9995
|
+
const callee = leadingTriviaFieldAt(code, k, childIp) ? `(LEAD.at=cur,${kids[i]})` : kids[i];
|
|
9996
|
+
parts.push(emitTerm(callee, vn, tmp(), L, skipFor(L)));
|
|
9997
|
+
}
|
|
9903
9998
|
names.push(vn);
|
|
9904
9999
|
}
|
|
9905
10000
|
parts.push("EC.e=cur");
|
|
@@ -10299,7 +10394,7 @@ let sp=cur
|
|
|
10299
10394
|
${hasTrivia === "false" ? "" : hasTrivia === "true" ? `sp=${skip}(input,sp,ctx)
|
|
10300
10395
|
` : `if(hasTrivia)sp=${skip}(input,sp,ctx)
|
|
10301
10396
|
`}ctx._fc=false
|
|
10302
|
-
const sv=${sep}(input,sp,ctx)
|
|
10397
|
+
${sepIp >= 0 && leadingTriviaFieldAt(code, k, sepIp) ? "LEAD.at=cur\n" : ""}const sv=${sep}(input,sp,ctx)
|
|
10303
10398
|
if(sv===FAIL){
|
|
10304
10399
|
${rb}
|
|
10305
10400
|
if(ctx._fc===true)return FAIL
|
|
@@ -10681,6 +10776,10 @@ function sequence(...parsers) {
|
|
|
10681
10776
|
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
10682
10777
|
}
|
|
10683
10778
|
const hasAdjacency = adjacency !== null;
|
|
10779
|
+
let leading = null;
|
|
10780
|
+
for (let i = 1; i < parsers.length; i++) {
|
|
10781
|
+
if (leadsTrivia(parsers[i])) (leading ??= Array.from({ length: parsers.length }, () => false))[i] = true;
|
|
10782
|
+
}
|
|
10684
10783
|
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
10685
10784
|
const meta = {
|
|
10686
10785
|
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
@@ -10728,7 +10827,7 @@ function sequence(...parsers) {
|
|
|
10728
10827
|
_tag: "sequence",
|
|
10729
10828
|
_meta: meta,
|
|
10730
10829
|
_def: def,
|
|
10731
|
-
_parseScalar: hasAdjacency ? void 0 : parseScalar,
|
|
10830
|
+
_parseScalar: hasAdjacency || leading !== null ? void 0 : parseScalar,
|
|
10732
10831
|
parse(input, pos, ctx) {
|
|
10733
10832
|
const tolerant = ctx._tolerant === true;
|
|
10734
10833
|
if (tolerant) {
|
|
@@ -10762,6 +10861,7 @@ function sequence(...parsers) {
|
|
|
10762
10861
|
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
10763
10862
|
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
10764
10863
|
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
10864
|
+
if (leading?.[i] === true) LEAD.at = cur;
|
|
10765
10865
|
const result = parsers[i].parse(input, termPos, ctx);
|
|
10766
10866
|
if (!result.ok) return result;
|
|
10767
10867
|
if (values !== void 0) values.push(result.value);
|
|
@@ -10803,6 +10903,7 @@ function withRuleTrivia(trivia2, ctx, run) {
|
|
|
10803
10903
|
ctx.triviaKindLabels = savedLabels;
|
|
10804
10904
|
}
|
|
10805
10905
|
}
|
|
10906
|
+
var UNDEFINED_REF = new Error("ref<T>() used before .define() was called");
|
|
10806
10907
|
function ref() {
|
|
10807
10908
|
let resolved = null;
|
|
10808
10909
|
let resolvedScalar = null;
|
|
@@ -10818,7 +10919,7 @@ function ref() {
|
|
|
10818
10919
|
_def: {
|
|
10819
10920
|
tag: "lazy",
|
|
10820
10921
|
thunk: () => {
|
|
10821
|
-
if (!resolved) throw
|
|
10922
|
+
if (!resolved) throw UNDEFINED_REF;
|
|
10822
10923
|
return resolved;
|
|
10823
10924
|
}
|
|
10824
10925
|
},
|
|
@@ -11793,6 +11894,12 @@ function assemble(t2, prog, cfg) {
|
|
|
11793
11894
|
rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
11794
11895
|
return cur;
|
|
11795
11896
|
}
|
|
11897
|
+
function leadingFieldTerm(step, child, input, cur, ctx) {
|
|
11898
|
+
return step((i, p, c) => {
|
|
11899
|
+
LEAD.at = cur;
|
|
11900
|
+
return child(i, p, c);
|
|
11901
|
+
}, input, cur, ctx);
|
|
11902
|
+
}
|
|
11796
11903
|
function committed3(c) {
|
|
11797
11904
|
return c._fc === true;
|
|
11798
11905
|
}
|
|
@@ -12430,12 +12537,27 @@ function assemble(t2, prog, cfg) {
|
|
|
12430
12537
|
};
|
|
12431
12538
|
}
|
|
12432
12539
|
case OP_FIELD: {
|
|
12433
|
-
const name = k[code[ip + 1]];
|
|
12540
|
+
const { name, bits } = fieldSpec(k[code[ip + 1]]);
|
|
12434
12541
|
const child = link(code[ip + 2]);
|
|
12542
|
+
if (bits === 0) {
|
|
12543
|
+
return (input, pos, ctx) => {
|
|
12544
|
+
const v = child(input, pos, ctx);
|
|
12545
|
+
if (v === FAIL) return FAIL;
|
|
12546
|
+
ctx._fields?.push({ name, value: v, span: { start: pos, end: EC.e } });
|
|
12547
|
+
return v;
|
|
12548
|
+
};
|
|
12549
|
+
}
|
|
12550
|
+
const leading = (bits & FIELD_LEADING_TRIVIA) !== 0;
|
|
12551
|
+
const trailing = (bits & FIELD_TRAILING_TRIVIA) !== 0;
|
|
12435
12552
|
return (input, pos, ctx) => {
|
|
12553
|
+
const leadFrom = leading ? LEAD.at : -1;
|
|
12554
|
+
LEAD.at = -1;
|
|
12436
12555
|
const v = child(input, pos, ctx);
|
|
12437
12556
|
if (v === FAIL) return FAIL;
|
|
12438
|
-
|
|
12557
|
+
const end = EC.e;
|
|
12558
|
+
const trailEnd = trailing && ctx.trivia !== void 0 ? consumeTrivia(input, end, ctx) : end;
|
|
12559
|
+
ctx._fields?.push(triviaFieldCapture(name, v, input, pos, end, leadFrom, trailEnd));
|
|
12560
|
+
EC.e = trailEnd;
|
|
12439
12561
|
return v;
|
|
12440
12562
|
};
|
|
12441
12563
|
}
|
|
@@ -12869,6 +12991,12 @@ function assemble(t2, prog, cfg) {
|
|
|
12869
12991
|
const kidIp = code[base + i];
|
|
12870
12992
|
if (code[kidIp] !== OP_ADJ) {
|
|
12871
12993
|
const kid = link(kidIp);
|
|
12994
|
+
if (leadingTriviaFieldAt(code, k, kidIp)) {
|
|
12995
|
+
return (input, cur, ctx, inherited) => {
|
|
12996
|
+
ctx._sync = sync ?? inherited;
|
|
12997
|
+
return leadingFieldTerm(step, kid, input, cur, ctx);
|
|
12998
|
+
};
|
|
12999
|
+
}
|
|
12872
13000
|
return (input, cur, ctx, inherited) => {
|
|
12873
13001
|
ctx._sync = sync ?? inherited;
|
|
12874
13002
|
return step(kid, input, cur, ctx);
|
|
@@ -12946,9 +13074,12 @@ function assemble(t2, prog, cfg) {
|
|
|
12946
13074
|
};
|
|
12947
13075
|
}
|
|
12948
13076
|
let hasAdj = false;
|
|
12949
|
-
for (let i = 1; i < n; i++)
|
|
12950
|
-
|
|
12951
|
-
|
|
13077
|
+
for (let i = 1; i < n; i++) {
|
|
13078
|
+
const kidIp = code[base + i];
|
|
13079
|
+
if (code[kidIp] === OP_ADJ || leadingTriviaFieldAt(code, k, kidIp)) {
|
|
13080
|
+
hasAdj = true;
|
|
13081
|
+
break;
|
|
13082
|
+
}
|
|
12952
13083
|
}
|
|
12953
13084
|
if (hasAdj) {
|
|
12954
13085
|
const first2 = link(code[base]);
|
|
@@ -12956,6 +13087,9 @@ function assemble(t2, prog, cfg) {
|
|
|
12956
13087
|
const kidIp = code[base + i];
|
|
12957
13088
|
if (code[kidIp] !== OP_ADJ) {
|
|
12958
13089
|
const kid = link(kidIp);
|
|
13090
|
+
if (leadingTriviaFieldAt(code, k, kidIp)) {
|
|
13091
|
+
return (input, cur, ctx) => leadingFieldTerm(step, kid, input, cur, ctx);
|
|
13092
|
+
}
|
|
12959
13093
|
return (input, cur, ctx) => step(kid, input, cur, ctx);
|
|
12960
13094
|
}
|
|
12961
13095
|
const negated = code[kidIp + 1] === 1;
|
|
@@ -13318,7 +13452,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13318
13452
|
if (n === 2 || n === 3) {
|
|
13319
13453
|
const a0 = link(code[base]), a1 = link(code[base + 1]);
|
|
13320
13454
|
const a2 = n === 3 ? link(code[base + 2]) : void 0;
|
|
13321
|
-
const predecide = !
|
|
13455
|
+
const predecide = !REC && !cfg.probe && !cfg.coverage && !cfg.trackLines;
|
|
13322
13456
|
const p0ip = predecide ? leadingScalarTerminal(code, code[base], 2, true, true) : -1;
|
|
13323
13457
|
const p1ip = predecide ? leadingScalarTerminal(code, code[base + 1], 2, true, true) : -1;
|
|
13324
13458
|
const p2ip = predecide && n === 3 ? leadingScalarTerminal(code, code[base + 2], 2, true, true) : -1;
|
|
@@ -13541,6 +13675,75 @@ function assemble(t2, prog, cfg) {
|
|
|
13541
13675
|
);
|
|
13542
13676
|
};
|
|
13543
13677
|
const masked = bindMasked(0, EMPTY_EXPECTED_PREFIX);
|
|
13678
|
+
const pBit = [];
|
|
13679
|
+
const pRec = [];
|
|
13680
|
+
if (!REC && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
|
|
13681
|
+
for (let i = 0; i < n; i++) {
|
|
13682
|
+
for (const terminal of largeChoiceLiteralPretest(code, k, code[base + i]) ?? []) {
|
|
13683
|
+
pBit.push(1 << i);
|
|
13684
|
+
pRec.push(scalarFor(terminal));
|
|
13685
|
+
}
|
|
13686
|
+
}
|
|
13687
|
+
}
|
|
13688
|
+
const pn = pBit.length;
|
|
13689
|
+
if (pn !== 0) {
|
|
13690
|
+
return (input, pos, ctx) => {
|
|
13691
|
+
const c = lead(input, pos);
|
|
13692
|
+
const need = markCst(ctx);
|
|
13693
|
+
const mRaw = MRAW;
|
|
13694
|
+
const mTl = MTL;
|
|
13695
|
+
const mLv = MLV;
|
|
13696
|
+
const mFl = need ? ctx._fields?.length ?? 0 : 0;
|
|
13697
|
+
const mEr = need ? ctx._errors?.length ?? 0 : 0;
|
|
13698
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0;
|
|
13699
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
13700
|
+
if (c < 128) {
|
|
13701
|
+
const bits = mask[c < 0 ? 128 : c];
|
|
13702
|
+
let tested = 0;
|
|
13703
|
+
let hit = 0;
|
|
13704
|
+
for (let i = 0; i < pn; i++) {
|
|
13705
|
+
const b = pBit[i];
|
|
13706
|
+
if ((bits & b) === 0 || (hit & b) !== 0) continue;
|
|
13707
|
+
tested |= b;
|
|
13708
|
+
if (pRec[i](input, pos) >= 0) hit |= b;
|
|
13709
|
+
}
|
|
13710
|
+
return masked(
|
|
13711
|
+
input,
|
|
13712
|
+
pos,
|
|
13713
|
+
ctx,
|
|
13714
|
+
bits & (~tested | hit),
|
|
13715
|
+
need,
|
|
13716
|
+
mRaw,
|
|
13717
|
+
mTl,
|
|
13718
|
+
mLv,
|
|
13719
|
+
mFl,
|
|
13720
|
+
mEr,
|
|
13721
|
+
mLog,
|
|
13722
|
+
mRoot,
|
|
13723
|
+
void 0,
|
|
13724
|
+
0,
|
|
13725
|
+
pos
|
|
13726
|
+
);
|
|
13727
|
+
}
|
|
13728
|
+
return general(
|
|
13729
|
+
input,
|
|
13730
|
+
pos,
|
|
13731
|
+
ctx,
|
|
13732
|
+
c,
|
|
13733
|
+
need,
|
|
13734
|
+
mRaw,
|
|
13735
|
+
mTl,
|
|
13736
|
+
mLv,
|
|
13737
|
+
mFl,
|
|
13738
|
+
mEr,
|
|
13739
|
+
mLog,
|
|
13740
|
+
mRoot,
|
|
13741
|
+
void 0,
|
|
13742
|
+
0,
|
|
13743
|
+
pos
|
|
13744
|
+
);
|
|
13745
|
+
};
|
|
13746
|
+
}
|
|
13544
13747
|
return (input, pos, ctx) => {
|
|
13545
13748
|
const c = lead(input, pos);
|
|
13546
13749
|
const need = markCst(ctx);
|
|
@@ -13702,6 +13905,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13702
13905
|
const max = code[ip + 3];
|
|
13703
13906
|
const sepIp = code[ip + 4];
|
|
13704
13907
|
const sep = sepIp >= 0 ? link(sepIp) : void 0;
|
|
13908
|
+
const sepLeads = sepIp >= 0 && leadingTriviaFieldAt(code, k, sepIp);
|
|
13705
13909
|
const flags = code[ip + 5];
|
|
13706
13910
|
const keepSeparators = (flags & 2) !== 0;
|
|
13707
13911
|
const trailingAllowed = (flags & 1) !== 0;
|
|
@@ -13741,6 +13945,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13741
13945
|
let sp = cur;
|
|
13742
13946
|
if (hasTrivia) sp = skipTrivia(input, sp, ctx);
|
|
13743
13947
|
ctx._fc = false;
|
|
13948
|
+
if (sepLeads) LEAD.at = cur;
|
|
13744
13949
|
const sv = sep(input, sp, ctx);
|
|
13745
13950
|
if (sv === FAIL) {
|
|
13746
13951
|
if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
@@ -13830,6 +14035,7 @@ function assemble(t2, prog, cfg) {
|
|
|
13830
14035
|
let sp = cur;
|
|
13831
14036
|
if (hasTrivia) sp = skipTrivia(input, sp, ctx);
|
|
13832
14037
|
ctx._fc = false;
|
|
14038
|
+
if (sepLeads) LEAD.at = cur;
|
|
13833
14039
|
const sv = sep(input, sp, ctx);
|
|
13834
14040
|
if (sv === FAIL) {
|
|
13835
14041
|
if (needMark) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
@@ -14152,20 +14358,9 @@ function assemble(t2, prog, cfg) {
|
|
|
14152
14358
|
if (child >= 0) scalarFor(child);
|
|
14153
14359
|
continue;
|
|
14154
14360
|
}
|
|
14155
|
-
|
|
14156
|
-
|
|
14157
|
-
|
|
14158
|
-
scalarFor(child);
|
|
14159
|
-
continue;
|
|
14160
|
-
}
|
|
14161
|
-
}
|
|
14162
|
-
const family = leadingLiteralFamily(code, k, armIp);
|
|
14163
|
-
if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
14164
|
-
const value = k[code[terminal + 1]];
|
|
14165
|
-
return typeof value === "string" && value.length >= 2;
|
|
14166
|
-
})) {
|
|
14167
|
-
for (const terminal of family) scalarFor(terminal);
|
|
14168
|
-
}
|
|
14361
|
+
const literals = largeChoiceLiteralPretest(code, k, armIp);
|
|
14362
|
+
if (literals !== void 0) for (const terminal of literals) scalarFor(terminal);
|
|
14363
|
+
if (literals !== void 0 && literals.length === 1 && literals[0] === child) continue;
|
|
14169
14364
|
const sequence6 = leadingScalarSequence(code, armIp);
|
|
14170
14365
|
if (sequence6 !== void 0 && (sequence6.trivia < 0 || triviaScan[sequence6.trivia] != null)) {
|
|
14171
14366
|
for (const terminal of sequence6.terminals) scalarFor(terminal);
|
|
@@ -14231,7 +14426,9 @@ function assemble(t2, prog, cfg) {
|
|
|
14231
14426
|
scanTriviaCompact,
|
|
14232
14427
|
t2.lex,
|
|
14233
14428
|
adjacencyHolds,
|
|
14234
|
-
t2.lexPrograms
|
|
14429
|
+
t2.lexPrograms,
|
|
14430
|
+
LEAD,
|
|
14431
|
+
triviaFieldCapture
|
|
14235
14432
|
);
|
|
14236
14433
|
emitReached = new Set(pre.reached);
|
|
14237
14434
|
}
|
|
@@ -14313,7 +14510,9 @@ function assemble(t2, prog, cfg) {
|
|
|
14313
14510
|
scanTriviaCompact,
|
|
14314
14511
|
t2.lex,
|
|
14315
14512
|
adjacencyHolds,
|
|
14316
|
-
t2.lexPrograms
|
|
14513
|
+
t2.lexPrograms,
|
|
14514
|
+
LEAD,
|
|
14515
|
+
triviaFieldCapture
|
|
14317
14516
|
);
|
|
14318
14517
|
emitReached = em.reached;
|
|
14319
14518
|
} catch (e) {
|
|
@@ -14489,7 +14688,9 @@ var AssemblyCache = class {
|
|
|
14489
14688
|
return made;
|
|
14490
14689
|
}
|
|
14491
14690
|
};
|
|
14492
|
-
function tableRules(source,
|
|
14691
|
+
function tableRules(source, metadataOrEntry = {}) {
|
|
14692
|
+
const entry = typeof metadataOrEntry === "string" ? metadataOrEntry : void 0;
|
|
14693
|
+
const artifactMetadata = typeof metadataOrEntry === "string" ? {} : metadataOrEntry;
|
|
14493
14694
|
const prog = expandCompact(source);
|
|
14494
14695
|
const resolved = resolveTable(prog);
|
|
14495
14696
|
const cache = new AssemblyCache(prog, resolved);
|
|
@@ -14497,7 +14698,7 @@ function tableRules(source, artifactMetadata = {}) {
|
|
|
14497
14698
|
const skipOf = prog.scanSkipOf;
|
|
14498
14699
|
let last;
|
|
14499
14700
|
let selected;
|
|
14500
|
-
|
|
14701
|
+
const map = stampRuleMap(prog, {
|
|
14501
14702
|
runRule: (ri, input, pos, ctx) => {
|
|
14502
14703
|
const a = selected ?? cache.forCtx(ctx);
|
|
14503
14704
|
selected = void 0;
|
|
@@ -14518,6 +14719,9 @@ function tableRules(source, artifactMetadata = {}) {
|
|
|
14518
14719
|
return a.scanSkip[skipOf?.[ri] ?? -1];
|
|
14519
14720
|
}
|
|
14520
14721
|
}, artifactMetadata, resolved);
|
|
14722
|
+
if (entry === void 0) return map;
|
|
14723
|
+
if (!Object.hasOwn(map, entry)) throw new Error(`tableRules: the program has no rule ${JSON.stringify(entry)}`);
|
|
14724
|
+
return map[entry];
|
|
14521
14725
|
}
|
|
14522
14726
|
|
|
14523
14727
|
// src/table/emit.ts
|
|
@@ -14672,11 +14876,15 @@ function emitTableExpression(prog, opts = {}) {
|
|
|
14672
14876
|
const entry = opts.entry === void 0 ? "grammar" : opts.entry;
|
|
14673
14877
|
const ref2 = opts.runtimeRef ?? "tableRules";
|
|
14674
14878
|
const fns = opts.fnSources ?? prog.fns.map(() => "() => {}");
|
|
14675
|
-
const
|
|
14879
|
+
const meta = opts.metadataSource;
|
|
14880
|
+
if (entry !== null && meta !== void 0) {
|
|
14881
|
+
throw new Error("emitTableExpression: metadataSource is for the rule-map form (entry: null); a single entry carries none");
|
|
14882
|
+
}
|
|
14883
|
+
const tail = entry !== null ? `,${jsString(entry)}` : meta === void 0 ? "" : `,${meta}`;
|
|
14676
14884
|
return [
|
|
14677
14885
|
`/* @__PURE__ */ ${ref2}({`,
|
|
14678
14886
|
...programFields(prog, fns, opts),
|
|
14679
|
-
|
|
14887
|
+
`}${tail})`
|
|
14680
14888
|
].join("\n");
|
|
14681
14889
|
}
|
|
14682
14890
|
|
|
@@ -14745,7 +14953,8 @@ function children(def, winners) {
|
|
|
14745
14953
|
return [];
|
|
14746
14954
|
}
|
|
14747
14955
|
const name = resolved._ruleName;
|
|
14748
|
-
|
|
14956
|
+
const winner = name ? winners?.[name] : void 0;
|
|
14957
|
+
return winner !== void 0 && winner._def !== def ? [winner] : [resolved];
|
|
14749
14958
|
}
|
|
14750
14959
|
default:
|
|
14751
14960
|
return [];
|
|
@@ -14770,16 +14979,39 @@ function buildGrammarPlan(entry, winners) {
|
|
|
14770
14979
|
}
|
|
14771
14980
|
}
|
|
14772
14981
|
}
|
|
14982
|
+
const selfWinnerBody = (parser2) => {
|
|
14983
|
+
if (parser2._def.tag !== "lazy" || winners === void 0) return void 0;
|
|
14984
|
+
const name = winnerNames.get(parser2);
|
|
14985
|
+
if (name === void 0 || winners[name] !== parser2) return void 0;
|
|
14986
|
+
try {
|
|
14987
|
+
return parser2._def.thunk();
|
|
14988
|
+
} catch {
|
|
14989
|
+
return void 0;
|
|
14990
|
+
}
|
|
14991
|
+
};
|
|
14992
|
+
const slotsPerBody = /* @__PURE__ */ new Map();
|
|
14993
|
+
if (winners) {
|
|
14994
|
+
for (const winner of Object.values(winners)) {
|
|
14995
|
+
const body = selfWinnerBody(winner);
|
|
14996
|
+
if (body !== void 0) slotsPerBody.set(body, (slotsPerBody.get(body) ?? 0) + 1);
|
|
14997
|
+
}
|
|
14998
|
+
}
|
|
14999
|
+
const sharedBody = (parser2) => (slotsPerBody.get(parser2) ?? 0) > 1;
|
|
15000
|
+
const ownRule = (parser2, rule2) => {
|
|
15001
|
+
const id = `rule:${rule2}`;
|
|
15002
|
+
definitions.set(id, { id, kind: "rule" });
|
|
15003
|
+
rules.set(parser2, id);
|
|
15004
|
+
};
|
|
14773
15005
|
const seen = /* @__PURE__ */ new Set();
|
|
14774
15006
|
const visit = (parser2, path) => {
|
|
14775
15007
|
if (seen.has(parser2)) return;
|
|
14776
15008
|
seen.add(parser2);
|
|
14777
15009
|
const rule2 = winnerNames.get(parser2) ?? parser2._ruleName;
|
|
14778
|
-
|
|
14779
|
-
|
|
14780
|
-
|
|
14781
|
-
rules.set(parser2, id);
|
|
15010
|
+
const body = selfWinnerBody(parser2);
|
|
15011
|
+
if (rule2 && body === void 0 && !sharedBody(parser2) && (winnerNames.has(parser2) || parser2._def.tag !== "lazy")) {
|
|
15012
|
+
ownRule(parser2, rule2);
|
|
14782
15013
|
}
|
|
15014
|
+
if (rule2 && body !== void 0 && sharedBody(body)) ownRule(parser2, rule2);
|
|
14783
15015
|
if (parser2._def.tag === "choice") {
|
|
14784
15016
|
const ids = parser2._def.parsers.map((_, index) => `choice:${path}/arm:${index}`);
|
|
14785
15017
|
choices.set(parser2, ids);
|
|
@@ -14800,7 +15032,13 @@ function buildGrammarPlan(entry, winners) {
|
|
|
14800
15032
|
};
|
|
14801
15033
|
const roots = Array.isArray(entry) ? entry : [entry];
|
|
14802
15034
|
for (const root of roots) {
|
|
14803
|
-
|
|
15035
|
+
const name = winnerNames.get(root) ?? root._ruleName ?? "entry";
|
|
15036
|
+
const body = selfWinnerBody(root);
|
|
15037
|
+
if (body !== void 0 && sharedBody(body) && !seen.has(root)) {
|
|
15038
|
+
seen.add(root);
|
|
15039
|
+
ownRule(root, name);
|
|
15040
|
+
}
|
|
15041
|
+
visit(body ?? root, name);
|
|
14804
15042
|
}
|
|
14805
15043
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules };
|
|
14806
15044
|
}
|
|
@@ -14824,7 +15062,7 @@ function payloadKey(p, d) {
|
|
|
14824
15062
|
case "label":
|
|
14825
15063
|
return `label\0${d.label}`;
|
|
14826
15064
|
case "field":
|
|
14827
|
-
return `field\0${d.name}`;
|
|
15065
|
+
return `field\0${d.name}\0${d.leadingTrivia === true}\0${d.trailingTrivia === true}`;
|
|
14828
15066
|
case "node":
|
|
14829
15067
|
return `node\0${d.type ?? ""}\0${d.unwrap === true}\0${d.collapse === true}\0${fnKey(d.buildSrc, d.build)}`;
|
|
14830
15068
|
case "transform":
|
|
@@ -16102,6 +16340,238 @@ ${lines.join("\n")}`);
|
|
|
16102
16340
|
function runDuplicationDiagnostic(combinator, opt) {
|
|
16103
16341
|
return reportDuplication(opt, (o) => analyzeDuplication(combinator, o));
|
|
16104
16342
|
}
|
|
16343
|
+
function runDuplicationDiagnosticRules(ruleMap, opt) {
|
|
16344
|
+
return reportDuplication(opt, (o) => analyzeDuplicationRules(ruleMap, o));
|
|
16345
|
+
}
|
|
16346
|
+
|
|
16347
|
+
// src/cst/reflection-symbols.ts
|
|
16348
|
+
var GRAMMAR_REFLECTION = /* @__PURE__ */ Symbol.for("parseman.grammarReflection");
|
|
16349
|
+
|
|
16350
|
+
// src/cst/reflection.ts
|
|
16351
|
+
function childrenOf2(def) {
|
|
16352
|
+
switch (def.tag) {
|
|
16353
|
+
case "sequence":
|
|
16354
|
+
case "choice":
|
|
16355
|
+
return def.parsers;
|
|
16356
|
+
case "dispatch":
|
|
16357
|
+
return [
|
|
16358
|
+
def.selector,
|
|
16359
|
+
...def.cases.map((c) => c.parser),
|
|
16360
|
+
...def.matchers ? def.matchers.map((c) => c.parser) : [],
|
|
16361
|
+
...def.otherwise ? [def.otherwise] : []
|
|
16362
|
+
];
|
|
16363
|
+
case "many":
|
|
16364
|
+
case "oneOrMore":
|
|
16365
|
+
case "optional":
|
|
16366
|
+
case "attempt":
|
|
16367
|
+
case "transform":
|
|
16368
|
+
case "trivia":
|
|
16369
|
+
case "token":
|
|
16370
|
+
case "leaf":
|
|
16371
|
+
case "label":
|
|
16372
|
+
case "field":
|
|
16373
|
+
case "not":
|
|
16374
|
+
case "peek":
|
|
16375
|
+
case "node":
|
|
16376
|
+
case "withCtx":
|
|
16377
|
+
case "expect":
|
|
16378
|
+
return [def.parser];
|
|
16379
|
+
case "recover":
|
|
16380
|
+
return [def.parser, def.sentinel];
|
|
16381
|
+
case "grammar":
|
|
16382
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
16383
|
+
case "sepBy":
|
|
16384
|
+
return [def.parser, def.separator];
|
|
16385
|
+
case "scanTo":
|
|
16386
|
+
return [
|
|
16387
|
+
def.sentinel,
|
|
16388
|
+
...def.skip,
|
|
16389
|
+
...def.recoverAt === void 0 ? [] : [def.recoverAt],
|
|
16390
|
+
...def.stopAt === void 0 ? [] : [def.stopAt]
|
|
16391
|
+
];
|
|
16392
|
+
case "routed":
|
|
16393
|
+
return def.fallback ? [def.fallback] : [];
|
|
16394
|
+
case "literal":
|
|
16395
|
+
case "regex":
|
|
16396
|
+
case "keywords":
|
|
16397
|
+
case "guard":
|
|
16398
|
+
case "adjacency":
|
|
16399
|
+
case "lazy":
|
|
16400
|
+
case "unknown":
|
|
16401
|
+
return [];
|
|
16402
|
+
}
|
|
16403
|
+
}
|
|
16404
|
+
function addNode(out, def) {
|
|
16405
|
+
if (def.type === void 0) return;
|
|
16406
|
+
const existing = out.get(def.type);
|
|
16407
|
+
if (existing === void 0) {
|
|
16408
|
+
out.set(def.type, def.tags === void 0 ? [] : [...def.tags]);
|
|
16409
|
+
return;
|
|
16410
|
+
}
|
|
16411
|
+
if (def.tags === void 0) return;
|
|
16412
|
+
for (const tag of def.tags) {
|
|
16413
|
+
if (!existing.includes(tag)) existing.push(tag);
|
|
16414
|
+
}
|
|
16415
|
+
}
|
|
16416
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
16417
|
+
if (seen.has(parser2)) return;
|
|
16418
|
+
seen.add(parser2);
|
|
16419
|
+
const def = parser2._def;
|
|
16420
|
+
if (def.tag === "lazy") {
|
|
16421
|
+
if (followLazy) {
|
|
16422
|
+
try {
|
|
16423
|
+
collectFromCombinator(def.thunk(), out, seen, followLazy);
|
|
16424
|
+
} catch {
|
|
16425
|
+
}
|
|
16426
|
+
}
|
|
16427
|
+
return;
|
|
16428
|
+
}
|
|
16429
|
+
if (def.tag === "node") addNode(out, def);
|
|
16430
|
+
for (const child of childrenOf2(def)) collectFromCombinator(child, out, seen, followLazy);
|
|
16431
|
+
}
|
|
16432
|
+
function collectGrammarReflection(ruleMap, opts) {
|
|
16433
|
+
const byType = /* @__PURE__ */ new Map();
|
|
16434
|
+
const followLazy = opts?.followLazy !== false;
|
|
16435
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16436
|
+
for (const [, rule2] of ruleMap) {
|
|
16437
|
+
if (!followLazy && rule2._def.tag === "lazy") {
|
|
16438
|
+
try {
|
|
16439
|
+
const resolved = rule2._def.thunk();
|
|
16440
|
+
if (resolved._def.tag !== "lazy") collectFromCombinator(resolved, byType, /* @__PURE__ */ new Set(), false);
|
|
16441
|
+
} catch {
|
|
16442
|
+
}
|
|
16443
|
+
continue;
|
|
16444
|
+
}
|
|
16445
|
+
collectFromCombinator(rule2, byType, seen, followLazy);
|
|
16446
|
+
}
|
|
16447
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
16448
|
+
}
|
|
16449
|
+
|
|
16450
|
+
// src/table/compile-rule-map.ts
|
|
16451
|
+
function resolveHostMode(ruleMap, explicit) {
|
|
16452
|
+
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
16453
|
+
}
|
|
16454
|
+
function resolveTrackLines(ruleMap, explicit) {
|
|
16455
|
+
return explicit === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
16456
|
+
}
|
|
16457
|
+
function withAmbient(ruleMap, opts) {
|
|
16458
|
+
if (opts.trivia === void 0 && opts.scanSkip === void 0) return ruleMap;
|
|
16459
|
+
const wrappers = /* @__PURE__ */ new Map();
|
|
16460
|
+
return ruleMap.map(([name, rule2]) => {
|
|
16461
|
+
if (rule2._meta.isTrivia) return [name, rule2];
|
|
16462
|
+
const addTrivia = opts.trivia !== void 0 && rule2._meta.grammarTrivia === void 0;
|
|
16463
|
+
const addScanSkip = opts.scanSkip !== void 0 && rule2._meta.grammarScanSkip === void 0;
|
|
16464
|
+
if (!addTrivia && !addScanSkip) return [name, rule2];
|
|
16465
|
+
let wrapped = wrappers.get(rule2);
|
|
16466
|
+
if (wrapped === void 0) {
|
|
16467
|
+
wrapped = {
|
|
16468
|
+
...rule2,
|
|
16469
|
+
_meta: {
|
|
16470
|
+
...rule2._meta,
|
|
16471
|
+
...addTrivia ? { grammarTrivia: opts.trivia } : {},
|
|
16472
|
+
...addScanSkip ? { grammarScanSkip: opts.scanSkip } : {}
|
|
16473
|
+
}
|
|
16474
|
+
};
|
|
16475
|
+
wrappers.set(rule2, wrapped);
|
|
16476
|
+
}
|
|
16477
|
+
return [name, wrapped];
|
|
16478
|
+
});
|
|
16479
|
+
}
|
|
16480
|
+
function compileRuleMapRunnable(ruleMap, opts = {}) {
|
|
16481
|
+
const encoded = encodeForRun(ruleMap, opts);
|
|
16482
|
+
if (encoded === null) return null;
|
|
16483
|
+
const { prog, hostMode, plan } = encoded;
|
|
16484
|
+
const artifact = closureArtifact(prog);
|
|
16485
|
+
const reflection = collectGrammarReflection(ruleMap);
|
|
16486
|
+
return {
|
|
16487
|
+
keys: ruleMap.map(([key]) => key),
|
|
16488
|
+
hostMode,
|
|
16489
|
+
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule2]) => hasDirectBuildDef(rule2)),
|
|
16490
|
+
reflection,
|
|
16491
|
+
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
16492
|
+
// Reflection rides on the map's metadata prototype from birth. Only `compile()`
|
|
16493
|
+
// asks to specialise; every other caller runs the closure artifact.
|
|
16494
|
+
rules: tableRules(opts.specialise === true ? prog : artifact, { [GRAMMAR_REFLECTION]: reflection }),
|
|
16495
|
+
prog: artifact
|
|
16496
|
+
};
|
|
16497
|
+
}
|
|
16498
|
+
function encodeForRun(ruleMap, opts) {
|
|
16499
|
+
runDuplicationDiagnosticRules(ruleMap, opts.duplication);
|
|
16500
|
+
const encodeMap = withAmbient(ruleMap, opts);
|
|
16501
|
+
const plan = opts.coverage === true ? buildGrammarPlan(
|
|
16502
|
+
encodeMap.map(([, rule2]) => rule2),
|
|
16503
|
+
Object.fromEntries(encodeMap.filter(([, rule2]) => rule2._def.tag !== "lazy"))
|
|
16504
|
+
) : void 0;
|
|
16505
|
+
const hostMode = resolveHostMode(ruleMap, opts.hostMode);
|
|
16506
|
+
const settings = {
|
|
16507
|
+
hostMode,
|
|
16508
|
+
...resolveTrackLines(ruleMap, opts.trackLines) ? { trackLines: true } : {},
|
|
16509
|
+
...opts.recovery === true ? { recovery: true } : {},
|
|
16510
|
+
...plan === void 0 ? {} : { coverage: plan }
|
|
16511
|
+
};
|
|
16512
|
+
try {
|
|
16513
|
+
const { prog, fnSrcs } = encodeTableProgram(Object.fromEntries(encodeMap), settings);
|
|
16514
|
+
return { prog, fnSrcs, hostMode, plan };
|
|
16515
|
+
} catch (e) {
|
|
16516
|
+
opts.refusals?.push(e instanceof Error ? e.message : String(e));
|
|
16517
|
+
return null;
|
|
16518
|
+
}
|
|
16519
|
+
}
|
|
16520
|
+
|
|
16521
|
+
// src/compiler/borrowed-rules.ts
|
|
16522
|
+
var nameOf = (c) => c._ruleName;
|
|
16523
|
+
function deref(c) {
|
|
16524
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16525
|
+
let current = c;
|
|
16526
|
+
while (current._def.tag === "lazy" && !seen.has(current)) {
|
|
16527
|
+
seen.add(current);
|
|
16528
|
+
try {
|
|
16529
|
+
current = current._def.thunk();
|
|
16530
|
+
} catch {
|
|
16531
|
+
return void 0;
|
|
16532
|
+
}
|
|
16533
|
+
}
|
|
16534
|
+
return current;
|
|
16535
|
+
}
|
|
16536
|
+
function borrowedRuleReference(map) {
|
|
16537
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16538
|
+
for (const [rule2, self] of Object.entries(map)) {
|
|
16539
|
+
let found;
|
|
16540
|
+
const visit = (c) => {
|
|
16541
|
+
if (found !== void 0) return;
|
|
16542
|
+
if (c._def.tag === "lazy") {
|
|
16543
|
+
if (!winnerWrapsReference(self, c)) {
|
|
16544
|
+
const name = nameOf(c);
|
|
16545
|
+
const winner = name !== void 0 && Object.hasOwn(map, name) ? map[name] : void 0;
|
|
16546
|
+
if (winner !== void 0) {
|
|
16547
|
+
if (winnerWrapsReference(winner, c) || deref(c) === deref(winner)) return;
|
|
16548
|
+
found = name;
|
|
16549
|
+
return;
|
|
16550
|
+
}
|
|
16551
|
+
}
|
|
16552
|
+
if (seen.has(c)) return;
|
|
16553
|
+
seen.add(c);
|
|
16554
|
+
let body;
|
|
16555
|
+
try {
|
|
16556
|
+
body = c._def.thunk();
|
|
16557
|
+
} catch {
|
|
16558
|
+
return;
|
|
16559
|
+
}
|
|
16560
|
+
visit(body);
|
|
16561
|
+
return;
|
|
16562
|
+
}
|
|
16563
|
+
if (seen.has(c)) return;
|
|
16564
|
+
seen.add(c);
|
|
16565
|
+
for (const child of childrenOf(c._def)) visit(child);
|
|
16566
|
+
};
|
|
16567
|
+
visit(self);
|
|
16568
|
+
if (found !== void 0) return { rule: rule2, reference: found };
|
|
16569
|
+
}
|
|
16570
|
+
return void 0;
|
|
16571
|
+
}
|
|
16572
|
+
function borrowedRuleMessage(api, hit) {
|
|
16573
|
+
return `${api}: rule "${hit.rule}" is a rule object borrowed from another grammar, and its graph references "${hit.reference}", which this grammar also defines. The interpreter would keep the other grammar's "${hit.reference}" while a compiled table binds this grammar's, so the two would accept different input. Compose the grammar that defines "${hit.rule}" instead of borrowing its rule object, so its references resolve to this grammar's rules.`;
|
|
16574
|
+
}
|
|
16105
16575
|
|
|
16106
16576
|
// src/table/compile.ts
|
|
16107
16577
|
var ENTRY = "Entry";
|
|
@@ -16112,7 +16582,47 @@ function ownSource(fn) {
|
|
|
16112
16582
|
const name = fn.name;
|
|
16113
16583
|
return typeof name === "string" && name.length > 0 && globalThis[name] === fn ? name : null;
|
|
16114
16584
|
}
|
|
16115
|
-
function compile(
|
|
16585
|
+
function compile(target, second, third) {
|
|
16586
|
+
if (!isCombinator(target)) return compileMap(target, second);
|
|
16587
|
+
return compileRoot(target, second, third);
|
|
16588
|
+
}
|
|
16589
|
+
function isCombinator(x) {
|
|
16590
|
+
return typeof x === "object" && x !== null && typeof x.parse === "function" && "_def" in x;
|
|
16591
|
+
}
|
|
16592
|
+
function compileMap(grammar, opts = {}) {
|
|
16593
|
+
const entries = [];
|
|
16594
|
+
for (const [key, value] of Object.entries(grammar)) {
|
|
16595
|
+
if (!isCombinator(value)) throw new TypeError(`compile: grammar entry "${key}" is not a parser`);
|
|
16596
|
+
if (value._def.tag === "lazy") {
|
|
16597
|
+
try {
|
|
16598
|
+
value._def.thunk();
|
|
16599
|
+
} catch {
|
|
16600
|
+
continue;
|
|
16601
|
+
}
|
|
16602
|
+
}
|
|
16603
|
+
entries.push([key, value]);
|
|
16604
|
+
}
|
|
16605
|
+
const borrowed = borrowedRuleReference(Object.fromEntries(entries));
|
|
16606
|
+
if (borrowed !== void 0) throw new Error(borrowedRuleMessage("compile", borrowed));
|
|
16607
|
+
const drain = beginCompileDegradationDrain();
|
|
16608
|
+
let done = false;
|
|
16609
|
+
try {
|
|
16610
|
+
const refusals = [];
|
|
16611
|
+
const compiled = compileRuleMapRunnable(entries, {
|
|
16612
|
+
...opts.hostMode ? { hostMode: opts.hostMode } : {},
|
|
16613
|
+
refusals,
|
|
16614
|
+
specialise: true
|
|
16615
|
+
});
|
|
16616
|
+
if (compiled === null) {
|
|
16617
|
+
throw new Error(`compile: this grammar could not be encoded to a table${refusals.length ? ` \u2014 ${refusals.join("; ")}` : ""}`);
|
|
16618
|
+
}
|
|
16619
|
+
done = true;
|
|
16620
|
+
return compiled.rules;
|
|
16621
|
+
} finally {
|
|
16622
|
+
drain(done);
|
|
16623
|
+
}
|
|
16624
|
+
}
|
|
16625
|
+
function compileRoot(combinator, mapFnSources, opts = {}) {
|
|
16116
16626
|
runDuplicationDiagnostic(combinator, opts.duplication);
|
|
16117
16627
|
const drain = beginCompileDegradationDrain();
|
|
16118
16628
|
let compiled = false;
|
|
@@ -16626,7 +17136,7 @@ function rebuildCombinator(root, replacements) {
|
|
|
16626
17136
|
out = label(d.label, one(d.parser));
|
|
16627
17137
|
break;
|
|
16628
17138
|
case "field":
|
|
16629
|
-
out = field(d.name, one(d.parser));
|
|
17139
|
+
out = field(d.name, one(d.parser), { leadingTrivia: d.leadingTrivia === true, trailingTrivia: d.trailingTrivia === true });
|
|
16630
17140
|
break;
|
|
16631
17141
|
case "token":
|
|
16632
17142
|
out = token(one(d.parser));
|