parseman 0.28.1 → 0.29.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/compiler/codegen.d.ts +23 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +10 -0
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/index.cjs +109 -2
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +109 -2
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.cjs.map +2 -2
- package/dist/language-service/index.js.map +2 -2
- package/dist/plugin/index.cjs +110 -3
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +110 -3
- package/dist/plugin/index.js.map +3 -3
- package/package.json +1 -1
package/dist/plugin/index.cjs
CHANGED
|
@@ -4151,6 +4151,61 @@ function tryInlineDestructureTransform(src, valueVars) {
|
|
|
4151
4151
|
}
|
|
4152
4152
|
|
|
4153
4153
|
// src/compiler/codegen.ts
|
|
4154
|
+
function leadingFirstSetRecipe(p, seen = /* @__PURE__ */ new Set()) {
|
|
4155
|
+
if (seen.has(p)) return { concrete: empty(), refs: [] };
|
|
4156
|
+
seen.add(p);
|
|
4157
|
+
const d = p._def;
|
|
4158
|
+
const rec = (c) => leadingFirstSetRecipe(c, seen);
|
|
4159
|
+
const merge = (a, b) => ({ concrete: union(a.concrete, b.concrete), refs: [...a.refs, ...b.refs] });
|
|
4160
|
+
switch (d.tag) {
|
|
4161
|
+
case "lazy": {
|
|
4162
|
+
const name = p._ruleName;
|
|
4163
|
+
if (name !== void 0) return { concrete: empty(), refs: [name] };
|
|
4164
|
+
try {
|
|
4165
|
+
return rec(d.thunk());
|
|
4166
|
+
} catch {
|
|
4167
|
+
return { concrete: any(), refs: [] };
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
case "literal":
|
|
4171
|
+
case "regex":
|
|
4172
|
+
case "keywords":
|
|
4173
|
+
return { concrete: p._meta.firstSet, refs: [] };
|
|
4174
|
+
case "choice": {
|
|
4175
|
+
let out = { concrete: empty(), refs: [] };
|
|
4176
|
+
for (const arm of d.parsers) out = merge(out, rec(arm));
|
|
4177
|
+
return out;
|
|
4178
|
+
}
|
|
4179
|
+
case "sequence": {
|
|
4180
|
+
let out = { concrete: empty(), refs: [] };
|
|
4181
|
+
for (const term of d.parsers) {
|
|
4182
|
+
out = merge(out, rec(term));
|
|
4183
|
+
if (!matchesEmpty(term)) return out;
|
|
4184
|
+
}
|
|
4185
|
+
return out;
|
|
4186
|
+
}
|
|
4187
|
+
case "oneOrMore":
|
|
4188
|
+
case "many":
|
|
4189
|
+
case "optional":
|
|
4190
|
+
case "transform":
|
|
4191
|
+
case "label":
|
|
4192
|
+
case "field":
|
|
4193
|
+
case "trivia":
|
|
4194
|
+
case "token":
|
|
4195
|
+
case "leaf":
|
|
4196
|
+
case "node":
|
|
4197
|
+
case "grammar":
|
|
4198
|
+
case "expect":
|
|
4199
|
+
return rec(d.parser);
|
|
4200
|
+
case "sepBy":
|
|
4201
|
+
return rec(d.parser);
|
|
4202
|
+
case "skip":
|
|
4203
|
+
return rec(d.main);
|
|
4204
|
+
// not / scanTo / guard / withCtx / recover / unknown → shallow set (safe).
|
|
4205
|
+
default:
|
|
4206
|
+
return { concrete: p._meta.firstSet, refs: [] };
|
|
4207
|
+
}
|
|
4208
|
+
}
|
|
4154
4209
|
var HOST_READS_DECL = "const _hostReads = (b, n) => { if (b === undefined) return false; let s; try { s = Function.prototype.toString.call(b) } catch (e) { return true } if (/\\barguments\\b/.test(s)) return true; const m = /^[^(]*\\(([\\s\\S]*?)\\)/.exec(s); if (m && /\\.\\.\\.|=/.test(m[1])) return true; return b.length > n }";
|
|
4155
4210
|
var _loweringSink = null;
|
|
4156
4211
|
function beginLoweringCapture() {
|
|
@@ -5205,6 +5260,13 @@ function emitMany(def, ctx, pos) {
|
|
|
5205
5260
|
itemPos = npV;
|
|
5206
5261
|
}
|
|
5207
5262
|
}
|
|
5263
|
+
if (!ctx.recovery && !ctx.coverage && !failsAtStart(def.parser) && needsFirstSetGuard(def.parser)) {
|
|
5264
|
+
const lcV = v(ctx, "_lc");
|
|
5265
|
+
stmts.push(
|
|
5266
|
+
`${ind(ctx)}const ${lcV} = ${itemPos} < input.length ? (input.codePointAt(${itemPos}) ?? -1) : -1`,
|
|
5267
|
+
`${ind(ctx)}if (!(${firstSetCond(lcV, def.parser._meta.firstSet)})) { ${rollback}break }`
|
|
5268
|
+
);
|
|
5269
|
+
}
|
|
5208
5270
|
const { stmts: iterStmts, okVar: iterOk, valVar: iterVal, endVar: iterEnd } = emitFallible(def.parser, ctx, itemPos, true);
|
|
5209
5271
|
stmts.push(...iterStmts);
|
|
5210
5272
|
if (ctx.recovery) {
|
|
@@ -5255,8 +5317,19 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
5255
5317
|
const rollback = `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${leaves}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${raw}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${trivia2}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${log}; if (_ctx._fields) _ctx._fields.length = ${fields}; if (_ctx._errors) _ctx._errors.length = ${errors}`;
|
|
5256
5318
|
const traceId = ctx.coverage?.plan.attempts.get(p);
|
|
5257
5319
|
const traceRollback = traceId === void 0 ? "" : ` _ctx._grammarTrace?.write({ id: ${JSON.stringify(traceId)}, phase: 'rollback', offset: ${pos} });`;
|
|
5320
|
+
const preGuard = [];
|
|
5321
|
+
if (!ctx.recovery && !ctx.coverage && needsFirstSetGuard(def.parser)) {
|
|
5322
|
+
const gcV = v(ctx, "_agc");
|
|
5323
|
+
const gExp = armStaticExpected(ctx, def.parser);
|
|
5324
|
+
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(gExp, pos)} }`;
|
|
5325
|
+
preGuard.push(
|
|
5326
|
+
`${ind(ctx)}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
5327
|
+
`${ind(ctx)}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
5328
|
+
);
|
|
5329
|
+
}
|
|
5258
5330
|
return {
|
|
5259
5331
|
stmts: [
|
|
5332
|
+
...preGuard,
|
|
5260
5333
|
`${ind(ctx)}const ${leaves} = _ctx._cstLeaves?.length ?? 0, ${raw} = _ctx._cstRawChildren?.length ?? 0, ${trivia2} = _ctx._cstTriviaLog?.length ?? 0, ${log} = _ctx._triviaLog?.length ?? 0, ${fields} = _ctx._fields?.length ?? 0, ${errors} = _ctx._errors?.length ?? 0`,
|
|
5261
5334
|
...inner.stmts,
|
|
5262
5335
|
...emitIfFail(ctx, `!${inner.okVar}`, `{ ${rollback};${traceRollback} _ctx._fe = ${pos}; ${propagateFailBody(ctx)} }`)
|
|
@@ -5636,7 +5709,18 @@ ${i}const ${chV} = ${profileRecognizer} ? undefined : [], ${rawV} = ${profileRec
|
|
|
5636
5709
|
const saveTrivia = needsTriviaFrame ? `, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog${smk ? `, ${smk} = _ctx._triviaCaptureMask` : ""}` : "";
|
|
5637
5710
|
const installTrivia = needsTriviaFrame ? `; _ctx.captureTrivia = ${capTLv ?? "false"}; _ctx._cstTriviaLog = ${innerTl}${smk ? `; _ctx._triviaCaptureMask = ${capTLv} && _ctx.build !== undefined && _ctx.build._parsemanTriviaKinds !== undefined ? _ctx.build._parsemanTriviaKinds(${JSON.stringify(def.type)}) : ${smk}` : ""}` : "";
|
|
5638
5711
|
const restoreTrivia = needsTriviaFrame ? `; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}${smk ? `; _ctx._triviaCaptureMask = ${smk}` : ""}` : "";
|
|
5712
|
+
const preGuard = [];
|
|
5713
|
+
if (!ctx.recovery && !ctx.coverage && (capturesChildren || structural) && needsFirstSetGuard(def.parser)) {
|
|
5714
|
+
const gcV = v(ctx, "_ngc");
|
|
5715
|
+
const gExp = armStaticExpected(ctx, def.parser);
|
|
5716
|
+
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(gExp, pos);
|
|
5717
|
+
preGuard.push(
|
|
5718
|
+
`${i}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
5719
|
+
`${i}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
5720
|
+
);
|
|
5721
|
+
}
|
|
5639
5722
|
const stmts = [
|
|
5723
|
+
...preGuard,
|
|
5640
5724
|
profHoist,
|
|
5641
5725
|
allocStmt,
|
|
5642
5726
|
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren${saveTrivia}${sf ? `, ${sf} = _ctx._fields` : ""}`,
|
|
@@ -6663,6 +6747,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
6663
6747
|
].join("\n")));
|
|
6664
6748
|
}
|
|
6665
6749
|
const firstSets = /* @__PURE__ */ new Map();
|
|
6750
|
+
const firstSetRecipes = /* @__PURE__ */ new Map();
|
|
6666
6751
|
for (const [key, rule] of ruleMap) {
|
|
6667
6752
|
let resolved = rule;
|
|
6668
6753
|
const d = rule._def;
|
|
@@ -6674,6 +6759,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
6674
6759
|
}
|
|
6675
6760
|
}
|
|
6676
6761
|
firstSets.set(key, canMatchEmptyAtStart(resolved) ? { kind: "any" } : resolved._meta.firstSet);
|
|
6762
|
+
firstSetRecipes.set(key, canMatchEmptyAtStart(resolved) ? { concrete: any(), refs: [] } : leadingFirstSetRecipe(resolved));
|
|
6677
6763
|
}
|
|
6678
6764
|
return {
|
|
6679
6765
|
ns,
|
|
@@ -6682,6 +6768,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
6682
6768
|
ruleFns,
|
|
6683
6769
|
wrappers,
|
|
6684
6770
|
firstSets,
|
|
6771
|
+
firstSetRecipes,
|
|
6685
6772
|
deps: ruleDependencies(ruleMap),
|
|
6686
6773
|
needsEmptyTl: !!ctx.needsEmptyTl,
|
|
6687
6774
|
needsHostReads: !!ctx.needsHostReads,
|
|
@@ -7328,10 +7415,30 @@ function fusedBody(pieces) {
|
|
|
7328
7415
|
];
|
|
7329
7416
|
const wrapperEntries = [...winner].map(([k, p]) => `${JSON.stringify(k)}: ${p.wrappers.get(k)}`);
|
|
7330
7417
|
const rawBody = [...lines, "return {", wrapperEntries.join(",\n"), "}"].join("\n");
|
|
7331
|
-
const
|
|
7418
|
+
const ANY2 = { kind: "any" };
|
|
7419
|
+
const recipes = /* @__PURE__ */ new Map();
|
|
7420
|
+
const shallow = /* @__PURE__ */ new Map();
|
|
7332
7421
|
for (const [k, p] of winner) {
|
|
7422
|
+
const r = p.firstSetRecipes?.get(k);
|
|
7423
|
+
if (r) recipes.set(k, r);
|
|
7333
7424
|
const fs2 = p.firstSets?.get(k);
|
|
7334
|
-
if (fs2)
|
|
7425
|
+
if (fs2) shallow.set(k, fs2);
|
|
7426
|
+
}
|
|
7427
|
+
const finalFS = /* @__PURE__ */ new Map();
|
|
7428
|
+
for (const [k] of winner) finalFS.set(k, recipes.get(k)?.concrete ?? shallow.get(k) ?? ANY2);
|
|
7429
|
+
for (let iter = 0; iter <= recipes.size; iter++) {
|
|
7430
|
+
let changed = false;
|
|
7431
|
+
for (const [k, r] of recipes) {
|
|
7432
|
+
let fs2 = r.concrete;
|
|
7433
|
+
for (const ref2 of r.refs) {
|
|
7434
|
+
fs2 = union(fs2, recipes.has(ref2) || shallow.has(ref2) ? finalFS.get(ref2) ?? ANY2 : ANY2);
|
|
7435
|
+
}
|
|
7436
|
+
if (JSON.stringify(finalFS.get(k)) !== JSON.stringify(fs2)) {
|
|
7437
|
+
finalFS.set(k, fs2);
|
|
7438
|
+
changed = true;
|
|
7439
|
+
}
|
|
7440
|
+
}
|
|
7441
|
+
if (!changed) break;
|
|
7335
7442
|
}
|
|
7336
7443
|
const body = rawBody.replace(
|
|
7337
7444
|
// Rule name + code-point var are both JS identifiers (rule names are validated
|
|
@@ -8502,7 +8609,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
8502
8609
|
const mapLit = (m, stripVals = false) => `new Map([${[...m].map(
|
|
8503
8610
|
([k, v2]) => `[${JSON.stringify(k)}, ${JSON.stringify(stripVals && typeof v2 === "string" ? stripIndent(v2) : v2)}]`
|
|
8504
8611
|
).join(", ")}])`;
|
|
8505
|
-
return `{ ns: ${JSON.stringify(p.ns)}, keys: ${JSON.stringify(p.keys)}, prelude: ${JSON.stringify(p.prelude.map(stripIndent))}, ruleFns: ${mapLit(p.ruleFns, true)}, wrappers: ${mapLit(p.wrappers, true)}, firstSets: ${mapLit(p.firstSets)}, deps: ${mapLit(p.deps)}, needsEmptyTl: ${p.needsEmptyTl}, needsHostReads: ${p.needsHostReads}, hasDirectBuilders: ${p.hasDirectBuilders === true}, isRecognitionOnly: ${p.isRecognitionOnly === true}, mfFns: [], buildFns: [] }`;
|
|
8612
|
+
return `{ ns: ${JSON.stringify(p.ns)}, keys: ${JSON.stringify(p.keys)}, prelude: ${JSON.stringify(p.prelude.map(stripIndent))}, ruleFns: ${mapLit(p.ruleFns, true)}, wrappers: ${mapLit(p.wrappers, true)}, firstSets: ${mapLit(p.firstSets)}, firstSetRecipes: ${p.firstSetRecipes ? mapLit(p.firstSetRecipes) : "new Map()"}, deps: ${mapLit(p.deps)}, needsEmptyTl: ${p.needsEmptyTl}, needsHostReads: ${p.needsHostReads}, hasDirectBuilders: ${p.hasDirectBuilders === true}, isRecognitionOnly: ${p.isRecognitionOnly === true}, mfFns: [], buildFns: [] }`;
|
|
8506
8613
|
};
|
|
8507
8614
|
const isSpread = (it) => "__spreadLocal" in it;
|
|
8508
8615
|
const isIR = (it) => "ir" in it && !("ruleFns" in it);
|