parseman 0.60.4 → 0.60.6
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/commitment.d.ts.map +1 -1
- package/dist/analysis/diagnostics.js +31 -5
- package/dist/analysis/diagnostics.js.map +1 -1
- package/dist/cli/index.js +639 -613
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/parser.d.ts +34 -3
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/trivia-boundary.d.ts +5 -3
- package/dist/combinators/trivia-boundary.d.ts.map +1 -1
- package/dist/compiler/compile-linkable-table.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +11 -3
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +6 -0
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +93 -25
- package/dist/index.js.map +1 -1
- package/dist/plugin/evaluator.d.ts +3 -1
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +116 -75
- package/dist/plugin/index.js.map +1 -1
- package/dist/spec/index.js +3 -1
- package/dist/spec/index.js.map +1 -1
- package/dist/spec/model.d.ts.map +1 -1
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/emit-assembly.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/index.js +31 -5
- package/dist/table/index.js.map +1 -1
- package/dist/table/ops.d.ts +6 -0
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/analysis/commitment.ts +3 -1
- package/src/combinators/grammar.ts +1 -1
- package/src/combinators/parser.ts +82 -9
- package/src/combinators/trivia-boundary.ts +11 -3
- package/src/compiler/compile-linkable-table.ts +4 -1
- package/src/compiler/ir-serialize.ts +10 -4
- package/src/compiler/linker.ts +22 -12
- package/src/index.ts +2 -1
- package/src/plugin/evaluator.ts +16 -5
- package/src/plugin/index.ts +27 -104
- package/src/spec/model.ts +3 -1
- package/src/table/assemble.ts +11 -1
- package/src/table/emit-assembly.ts +10 -1
- package/src/table/encode.ts +16 -9
- package/src/table/exec.ts +11 -9
- package/src/table/ops.ts +6 -0
- package/src/table/site-labels.ts +3 -3
- package/src/version.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -40,6 +40,12 @@ function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
|
40
40
|
case "oneOrMore":
|
|
41
41
|
case "sepBy":
|
|
42
42
|
return true;
|
|
43
|
+
// A scope that names or clears trivia keeps an outer install out of its body.
|
|
44
|
+
// Any other inherits, so it falls through at no cost in depth: line tracking
|
|
45
|
+
// wraps every rule in one, and must not change what this walk sees.
|
|
46
|
+
case "grammar":
|
|
47
|
+
if (d.triviaParser || d.clearTrivia) return false;
|
|
48
|
+
depth++;
|
|
43
49
|
// Transparent wrappers — they add no position, so ask what they wrap.
|
|
44
50
|
case "node":
|
|
45
51
|
case "transform":
|
|
@@ -4537,7 +4543,7 @@ function parser(opts, root) {
|
|
|
4537
4543
|
ctx.triviaKindLabels = void 0;
|
|
4538
4544
|
} else if (scopeTrivia !== void 0) {
|
|
4539
4545
|
ctx.trivia = scopeTrivia;
|
|
4540
|
-
|
|
4546
|
+
ctx.triviaKindLabels = scopeLabels;
|
|
4541
4547
|
}
|
|
4542
4548
|
if (forceCaptureTrivia || _ctx?.captureTrivia) ctx.captureTrivia = true;
|
|
4543
4549
|
if (ownCaptureMask !== void 0) ctx._triviaCaptureMask = ownCaptureMask;
|
|
@@ -4713,11 +4719,16 @@ function tagRule(r, key) {
|
|
|
4713
4719
|
function isDefinableRef(v) {
|
|
4714
4720
|
return !!v && typeof v === "object" && "_def" in v && v._def.tag === "lazy" && typeof v.define === "function";
|
|
4715
4721
|
}
|
|
4722
|
+
function priorNameOf(r) {
|
|
4723
|
+
return r._priorOf;
|
|
4724
|
+
}
|
|
4716
4725
|
function ruleNameOf(r) {
|
|
4717
4726
|
return r._ruleName;
|
|
4718
4727
|
}
|
|
4719
4728
|
function isNamedRuleRefForAnotherRule(r, key) {
|
|
4720
|
-
|
|
4729
|
+
if (r._def.tag !== "lazy") return false;
|
|
4730
|
+
if (priorNameOf(r) !== void 0) return true;
|
|
4731
|
+
const name = ruleNameOf(r);
|
|
4721
4732
|
return name !== void 0 && name !== key;
|
|
4722
4733
|
}
|
|
4723
4734
|
var claimedRules = /* @__PURE__ */ new WeakSet();
|
|
@@ -4730,6 +4741,20 @@ function ownRule(p, copies) {
|
|
|
4730
4741
|
}
|
|
4731
4742
|
return own;
|
|
4732
4743
|
}
|
|
4744
|
+
var priorUnfilled = (key) => new Error(`compose: prior.${key} is read, but no grammar composed before it defines "${key}"`);
|
|
4745
|
+
function priorHole(key) {
|
|
4746
|
+
const unfilled = priorUnfilled(key);
|
|
4747
|
+
const fail = () => {
|
|
4748
|
+
throw unfilled;
|
|
4749
|
+
};
|
|
4750
|
+
return {
|
|
4751
|
+
_tag: "lazy",
|
|
4752
|
+
_meta: { firstSet: any(), canMatchNewline: true, isTrivia: false },
|
|
4753
|
+
_def: { tag: "lazy", thunk: fail },
|
|
4754
|
+
parse: fail,
|
|
4755
|
+
_priorOf: key
|
|
4756
|
+
};
|
|
4757
|
+
}
|
|
4733
4758
|
function rules(a, b) {
|
|
4734
4759
|
const factory = typeof a === "function" ? a : b;
|
|
4735
4760
|
const options = typeof a === "function" ? b : a;
|
|
@@ -4754,8 +4779,20 @@ function linkRules(recipes, link) {
|
|
|
4754
4779
|
}
|
|
4755
4780
|
});
|
|
4756
4781
|
const winners = /* @__PURE__ */ new Map();
|
|
4782
|
+
const priorHoles = /* @__PURE__ */ new Map();
|
|
4783
|
+
const prior = new Proxy({}, {
|
|
4784
|
+
get(_target, key) {
|
|
4785
|
+
if (typeof key !== "string") return void 0;
|
|
4786
|
+
const earlier = winners.get(key)?.parser;
|
|
4787
|
+
if (earlier !== void 0) return earlier._def.tag === "node" ? earlier._def.parser : earlier;
|
|
4788
|
+
if (link !== void 0) throw priorUnfilled(key);
|
|
4789
|
+
let hole = priorHoles.get(key);
|
|
4790
|
+
if (hole === void 0) priorHoles.set(key, hole = priorHole(key));
|
|
4791
|
+
return hole;
|
|
4792
|
+
}
|
|
4793
|
+
});
|
|
4757
4794
|
for (const recipe of recipes) {
|
|
4758
|
-
const definitions = recipe.factory(proxy);
|
|
4795
|
+
const definitions = recipe.factory(proxy, prior);
|
|
4759
4796
|
for (const key of Object.keys(definitions)) {
|
|
4760
4797
|
winners.set(key, { parser: definitions[key], options: recipe.options });
|
|
4761
4798
|
}
|
|
@@ -7304,7 +7341,8 @@ function classifyRuleMap(ruleMap) {
|
|
|
7304
7341
|
resolved = void 0;
|
|
7305
7342
|
}
|
|
7306
7343
|
if (resolved === void 0) {
|
|
7307
|
-
|
|
7344
|
+
const hole = p;
|
|
7345
|
+
if (hole._ruleName !== void 0 || hole._priorOf !== void 0) externalRefs.add(p);
|
|
7308
7346
|
return;
|
|
7309
7347
|
}
|
|
7310
7348
|
scanExternal(resolved);
|
|
@@ -7486,6 +7524,7 @@ var OP_LIT_CI = 27;
|
|
|
7486
7524
|
var OP_LIT_CI_TRACK = 28;
|
|
7487
7525
|
var OP_TOKEN = 29;
|
|
7488
7526
|
var OP_SCOPE_CAP = 30;
|
|
7527
|
+
var SCOPE_INHERIT = -2;
|
|
7489
7528
|
var OP_WITHCTX = 31;
|
|
7490
7529
|
var OP_GUARD = 32;
|
|
7491
7530
|
var OP_ADJ = 33;
|
|
@@ -9518,7 +9557,7 @@ var Encoder = class {
|
|
|
9518
9557
|
this.triviaKnown = savedKnown;
|
|
9519
9558
|
if (d.clearTrivia === true) return this.emit(op, -1, bodyIp, flags);
|
|
9520
9559
|
if (d.triviaParser === void 0) {
|
|
9521
|
-
return cap
|
|
9560
|
+
return cap ? this.emit(op, SCOPE_INHERIT, bodyIp, flags) : bodyIp;
|
|
9522
9561
|
}
|
|
9523
9562
|
return this.emit(op, this.triviaSlot(d.triviaParser), bodyIp, flags);
|
|
9524
9563
|
}
|
|
@@ -10913,7 +10952,7 @@ function transfer(code, ip, at, hostCst) {
|
|
|
10913
10952
|
const op = code[ip];
|
|
10914
10953
|
if (op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN) {
|
|
10915
10954
|
const ki = code[ip + 1];
|
|
10916
|
-
const tri = ki < 0 ? TRI_NONE : ki;
|
|
10955
|
+
const tri = ki === SCOPE_INHERIT ? at.tri : ki < 0 ? TRI_NONE : ki;
|
|
10917
10956
|
const cap = op === OP_SCOPE_CAP ? CAP_ON : at.cap;
|
|
10918
10957
|
if (tri === at.tri && cap === at.cap) return at;
|
|
10919
10958
|
return { tri, buf: at.buf, raw: at.raw, cap };
|
|
@@ -10987,7 +11026,7 @@ function scanHandoffNeeded(code, ip, labels) {
|
|
|
10987
11026
|
if (l.tri === TRI_UNKNOWN) return true;
|
|
10988
11027
|
const op = code[at];
|
|
10989
11028
|
if (op === OP_SCAN) return true;
|
|
10990
|
-
if (op === OP_TOKEN || op === OP_SCOPE_CAP) continue;
|
|
11029
|
+
if (op === OP_TOKEN || op === OP_SCOPE_CAP && code[at + 1] !== SCOPE_INHERIT) continue;
|
|
10991
11030
|
if ((op === OP_SCOPE_PLAIN || op === OP_SCOPE) && !(code[at + 1] >= 0 && l.tri === code[at + 1] && (op === OP_SCOPE_PLAIN || code[at + 3] === 0))) continue;
|
|
10992
11031
|
kids.length = 0;
|
|
10993
11032
|
if (!childSlots(code, at, kids)) return true;
|
|
@@ -12282,6 +12321,15 @@ return r.value
|
|
|
12282
12321
|
const cap = op === OP_SCOPE_CAP;
|
|
12283
12322
|
const flags = op === OP_SCOPE_PLAIN ? 0 : code[ip + 3];
|
|
12284
12323
|
const child = link(code[ip + 2]);
|
|
12324
|
+
if (ki === SCOPE_INHERIT) {
|
|
12325
|
+
return `${head}
|
|
12326
|
+
const sC=ctx.captureTrivia
|
|
12327
|
+
ctx.captureTrivia=true
|
|
12328
|
+
const v=${child}(input,pos,ctx)
|
|
12329
|
+
ctx.captureTrivia=sC
|
|
12330
|
+
return v
|
|
12331
|
+
}`;
|
|
12332
|
+
}
|
|
12285
12333
|
const scanFor = swapLegal && ki >= 0 && !triviaLabelled[ki] ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
12286
12334
|
const tri = ki < 0 ? "undefined" : hoist("tv", `TRIVIA[${ki}]`);
|
|
12287
12335
|
const lab = ki < 0 ? "undefined" : hoist("tl", `TRIVIA[${ki}]._meta.triviaKindLabels`);
|
|
@@ -13871,7 +13919,7 @@ function clearOf(ranges, input, from, to) {
|
|
|
13871
13919
|
}
|
|
13872
13920
|
|
|
13873
13921
|
// src/version.ts
|
|
13874
|
-
var PARSEMAN_VERSION = "0.60.
|
|
13922
|
+
var PARSEMAN_VERSION = "0.60.6";
|
|
13875
13923
|
|
|
13876
13924
|
// src/table/assemble.ts
|
|
13877
13925
|
import { PlainBuf as PlainBuf2, PlainField, PlainLeaf as PlainLeaf9, PlainNode as PlainNode2, PlainSpan as PlainSpan10 } from "./cst/plain.js";
|
|
@@ -15401,6 +15449,16 @@ function assemble(t, prog, cfg) {
|
|
|
15401
15449
|
case OP_SCOPE_CAP:
|
|
15402
15450
|
case OP_SCOPE_PLAIN: {
|
|
15403
15451
|
const ki = code[ip + 1];
|
|
15452
|
+
if (ki === SCOPE_INHERIT) {
|
|
15453
|
+
const body = link(code[ip + 2]);
|
|
15454
|
+
return (input, pos, ctx) => {
|
|
15455
|
+
const savedCap = ctx.captureTrivia;
|
|
15456
|
+
ctx.captureTrivia = true;
|
|
15457
|
+
const v = body(input, pos, ctx);
|
|
15458
|
+
ctx.captureTrivia = savedCap;
|
|
15459
|
+
return v;
|
|
15460
|
+
};
|
|
15461
|
+
}
|
|
15404
15462
|
const scopeTrivia = ki < 0 ? void 0 : trivia2[ki];
|
|
15405
15463
|
const scopeLabels = scopeTrivia?._meta.triviaKindLabels;
|
|
15406
15464
|
const scanFor = swapLegal && ki >= 0 && !triviaLabelled[ki] ? triviaScan[ki] : null;
|
|
@@ -18024,7 +18082,7 @@ function buildGrammarPlan(entry, winners) {
|
|
|
18024
18082
|
const dispatches = /* @__PURE__ */ new Map();
|
|
18025
18083
|
const attempts = /* @__PURE__ */ new Map();
|
|
18026
18084
|
const labels = /* @__PURE__ */ new Map();
|
|
18027
|
-
const
|
|
18085
|
+
const rules3 = /* @__PURE__ */ new Map();
|
|
18028
18086
|
const winnerNames = /* @__PURE__ */ new Map();
|
|
18029
18087
|
if (winners) {
|
|
18030
18088
|
for (const [name, winner] of Object.entries(winners)) {
|
|
@@ -18058,7 +18116,7 @@ function buildGrammarPlan(entry, winners) {
|
|
|
18058
18116
|
const ownRule2 = (parser2, rule) => {
|
|
18059
18117
|
const id = `rule:${rule}`;
|
|
18060
18118
|
definitions.set(id, { id, kind: "rule" });
|
|
18061
|
-
|
|
18119
|
+
rules3.set(parser2, id);
|
|
18062
18120
|
};
|
|
18063
18121
|
const seen = /* @__PURE__ */ new Set();
|
|
18064
18122
|
const visit = (parser2, path) => {
|
|
@@ -18098,7 +18156,7 @@ function buildGrammarPlan(entry, winners) {
|
|
|
18098
18156
|
}
|
|
18099
18157
|
visit(body ?? root, name);
|
|
18100
18158
|
}
|
|
18101
|
-
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules:
|
|
18159
|
+
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules3 };
|
|
18102
18160
|
}
|
|
18103
18161
|
|
|
18104
18162
|
// src/analysis/duplication.ts
|
|
@@ -19891,6 +19949,8 @@ var Serializer = class {
|
|
|
19891
19949
|
localRuleNames = /* @__PURE__ */ new Map();
|
|
19892
19950
|
ruleMap;
|
|
19893
19951
|
scanSkip;
|
|
19952
|
+
/** Whether any rule reads a `prior.X` hole, so the factory takes `(g, prior)`. */
|
|
19953
|
+
usesPrior = false;
|
|
19894
19954
|
accessed;
|
|
19895
19955
|
referenced = /* @__PURE__ */ new Set();
|
|
19896
19956
|
constructor(ruleMap, scanSkip = [], accessed = []) {
|
|
@@ -19911,7 +19971,7 @@ var Serializer = class {
|
|
|
19911
19971
|
if (seen.has(c)) return;
|
|
19912
19972
|
seen.add(c);
|
|
19913
19973
|
if (c._def.tag === "lazy") {
|
|
19914
|
-
if (ruleNameOf4(c) !== void 0) throw new Unserializable("scanSkip unit references a grammar rule");
|
|
19974
|
+
if (ruleNameOf4(c) !== void 0 || priorNameOf(c) !== void 0) throw new Unserializable("scanSkip unit references a grammar rule");
|
|
19915
19975
|
const target = lazyTarget(c);
|
|
19916
19976
|
if (target) this.assertNoRuleRef(target, seen);
|
|
19917
19977
|
return;
|
|
@@ -19975,9 +20035,10 @@ var Serializer = class {
|
|
|
19975
20035
|
for (const name of this.accessed) {
|
|
19976
20036
|
if (!this.referenced.has(name)) innerDecls.push(`void g[${JSON.stringify(name)}]`);
|
|
19977
20037
|
}
|
|
19978
|
-
const
|
|
20038
|
+
const params = this.usesPrior ? "(g, prior)" : "(g)";
|
|
20039
|
+
const factory = innerDecls.length === 0 ? `${params} => ({
|
|
19979
20040
|
${body}
|
|
19980
|
-
})` :
|
|
20041
|
+
})` : `${params} => {
|
|
19981
20042
|
${innerDecls.map((d) => " " + d).join("\n")}
|
|
19982
20043
|
return ({
|
|
19983
20044
|
${body}
|
|
@@ -19994,6 +20055,10 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
19994
20055
|
analyze(c, active) {
|
|
19995
20056
|
const def = c._def;
|
|
19996
20057
|
if (def.tag === "lazy") {
|
|
20058
|
+
if (priorNameOf(c) !== void 0) {
|
|
20059
|
+
this.usesPrior = true;
|
|
20060
|
+
return;
|
|
20061
|
+
}
|
|
19997
20062
|
if (ruleNameOf4(c) !== void 0) return;
|
|
19998
20063
|
const target = lazyTarget(c);
|
|
19999
20064
|
if (!target) throw new Unserializable("unresolved unnamed ref");
|
|
@@ -20072,6 +20137,8 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
20072
20137
|
}
|
|
20073
20138
|
switch (def.tag) {
|
|
20074
20139
|
case "lazy": {
|
|
20140
|
+
const prior = priorNameOf(c);
|
|
20141
|
+
if (prior !== void 0) return `prior[${JSON.stringify(prior)}]`;
|
|
20075
20142
|
const name = this.localRuleNames.get(c) ?? ruleNameOf4(c);
|
|
20076
20143
|
if (name !== void 0) {
|
|
20077
20144
|
this.referenced.add(name);
|
|
@@ -20252,7 +20319,8 @@ function externalNames(ruleMap) {
|
|
|
20252
20319
|
resolved = void 0;
|
|
20253
20320
|
}
|
|
20254
20321
|
if (resolved === void 0) {
|
|
20255
|
-
const
|
|
20322
|
+
const prior = priorNameOf(p);
|
|
20323
|
+
const name = prior === void 0 ? p._ruleName : `prior.${prior}`;
|
|
20256
20324
|
if (name !== void 0 && !out.includes(name)) out.push(name);
|
|
20257
20325
|
return;
|
|
20258
20326
|
}
|
|
@@ -20345,9 +20413,9 @@ function carriedRuleMapsDetailed(carried) {
|
|
|
20345
20413
|
const maps = [];
|
|
20346
20414
|
const opaque = [];
|
|
20347
20415
|
for (const p of carried) {
|
|
20348
|
-
const
|
|
20349
|
-
if (
|
|
20350
|
-
maps.push(
|
|
20416
|
+
const rules3 = ruleMapOfCarried(p);
|
|
20417
|
+
if (rules3 !== void 0) {
|
|
20418
|
+
maps.push(rules3);
|
|
20351
20419
|
continue;
|
|
20352
20420
|
}
|
|
20353
20421
|
opaque.push({ ns: p.ns, ruleNames: isIRPiece(p) ? [] : [...p.keys] });
|
|
@@ -20358,7 +20426,7 @@ function recoverComposedRules(grammar) {
|
|
|
20358
20426
|
const carried = composedPiecesOf(grammar);
|
|
20359
20427
|
if (carried === void 0) return void 0;
|
|
20360
20428
|
const { maps, opaque } = carriedRuleMapsDetailed(carried);
|
|
20361
|
-
const
|
|
20429
|
+
const rules3 = /* @__PURE__ */ new Map();
|
|
20362
20430
|
for (const map of maps) for (const [name, rule] of map) {
|
|
20363
20431
|
if (rule._def.tag === "lazy") {
|
|
20364
20432
|
try {
|
|
@@ -20367,9 +20435,9 @@ function recoverComposedRules(grammar) {
|
|
|
20367
20435
|
continue;
|
|
20368
20436
|
}
|
|
20369
20437
|
}
|
|
20370
|
-
|
|
20438
|
+
rules3.set(name, rule);
|
|
20371
20439
|
}
|
|
20372
|
-
return { rules:
|
|
20440
|
+
return { rules: rules3, opaque };
|
|
20373
20441
|
}
|
|
20374
20442
|
function composedCoverageRules(grammar) {
|
|
20375
20443
|
const link = grammar[LINKED];
|
|
@@ -21282,12 +21350,12 @@ function inSet(code, fs) {
|
|
|
21282
21350
|
var TERMINAL_TAGS = /* @__PURE__ */ new Set(["literal", "regex", "keywords", "scanTo"]);
|
|
21283
21351
|
var INSTRUMENTABLE = /* @__PURE__ */ new Set(["firstMatch", "sharedPrefix"]);
|
|
21284
21352
|
function profileWastedWork(opts) {
|
|
21285
|
-
const { rules:
|
|
21286
|
-
const { walked, unresolvedRoots } = walkRules(
|
|
21287
|
-
const entryParser = typeof opts.entry === "string" ?
|
|
21353
|
+
const { rules: rules3, corpus } = opts;
|
|
21354
|
+
const { walked, unresolvedRoots } = walkRules(rules3);
|
|
21355
|
+
const entryParser = typeof opts.entry === "string" ? rules3.find(([n]) => n === opts.entry)?.[1] : opts.entry;
|
|
21288
21356
|
if (entryParser === void 0) {
|
|
21289
21357
|
throw new TypeError(
|
|
21290
|
-
`choice-cost: entry rule '${String(opts.entry)}' is not in the rule map (have: ${
|
|
21358
|
+
`choice-cost: entry rule '${String(opts.entry)}' is not in the rule map (have: ${rules3.map(([n]) => n).slice(0, 12).join(", ")}${rules3.length > 12 ? ", \u2026" : ""}).`
|
|
21291
21359
|
);
|
|
21292
21360
|
}
|
|
21293
21361
|
if (corpus.length === 0) {
|