parseman 0.60.5 → 0.61.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 +77 -40
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +77 -40
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/link-scope.d.ts +7 -0
- package/dist/combinators/link-scope.d.ts.map +1 -0
- package/dist/combinators/node.d.ts.map +1 -1
- 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/token-capability.js +7 -0
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/compiler/value-usage.d.ts.map +1 -1
- package/dist/functional/run.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +121 -70
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +1 -1
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/index.js +284 -233
- package/dist/plugin/index.js.map +3 -3
- package/dist/run/index.js +1 -1
- package/dist/run/index.js.map +1 -1
- package/dist/spec/index.js.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/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/index.js +41 -10
- package/dist/table/index.js.map +3 -3
- package/dist/table/ops.d.ts +6 -0
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +3 -1
- package/dist/table/program.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/combinators/choice.ts +3 -1
- package/src/combinators/expect.ts +1 -0
- package/src/combinators/grammar.ts +1 -1
- package/src/combinators/link-scope.ts +19 -0
- package/src/combinators/node.ts +11 -2
- package/src/combinators/parser.ts +37 -31
- package/src/combinators/trivia-boundary.ts +11 -3
- package/src/compiler/value-usage.ts +16 -29
- package/src/functional/run.ts +3 -1
- package/src/index.ts +1 -1
- package/src/table/assemble.ts +11 -1
- package/src/table/emit-assembly.ts +10 -1
- package/src/table/emit.ts +5 -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/program.ts +8 -2
- package/src/table/site-labels.ts +3 -3
- package/src/version.ts +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -48,6 +48,12 @@ function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
|
48
48
|
case "oneOrMore":
|
|
49
49
|
case "sepBy":
|
|
50
50
|
return true;
|
|
51
|
+
// A scope that names or clears trivia keeps an outer install out of its body.
|
|
52
|
+
// Any other inherits, so it falls through at no cost in depth: line tracking
|
|
53
|
+
// wraps every rule in one, and must not change what this walk sees.
|
|
54
|
+
case "grammar":
|
|
55
|
+
if (d.triviaParser || d.clearTrivia) return false;
|
|
56
|
+
depth++;
|
|
51
57
|
// Transparent wrappers — they add no position, so ask what they wrap.
|
|
52
58
|
case "node":
|
|
53
59
|
case "transform":
|
|
@@ -2712,6 +2718,7 @@ function derive(c, seen) {
|
|
|
2712
2718
|
case "optional":
|
|
2713
2719
|
case "many":
|
|
2714
2720
|
case "oneOrMore":
|
|
2721
|
+
case "sepBy":
|
|
2715
2722
|
case "transform":
|
|
2716
2723
|
case "not":
|
|
2717
2724
|
case "peek":
|
|
@@ -2893,7 +2900,7 @@ function selectOptionalSuffixLexBody(ir) {
|
|
|
2893
2900
|
function reinstallsRuleTrivia(reference, target) {
|
|
2894
2901
|
return (reference._meta.grammarTrivia ?? target._meta.grammarTrivia) !== void 0 && hasOwnTriviaBoundary(target);
|
|
2895
2902
|
}
|
|
2896
|
-
function directTokenBodyParser(parser2, resolve2,
|
|
2903
|
+
function directTokenBodyParser(parser2, resolve2, scope2) {
|
|
2897
2904
|
const outer = parser2._def;
|
|
2898
2905
|
if (outer.tag !== "token") return void 0;
|
|
2899
2906
|
let body = outer.parser;
|
|
@@ -2903,7 +2910,7 @@ function directTokenBodyParser(parser2, resolve2, scope) {
|
|
|
2903
2910
|
const wrapper = body._def;
|
|
2904
2911
|
if (wrapper.tag === "grammar") {
|
|
2905
2912
|
if (wrapper.clearTrivia !== true || wrapper.triviaParser !== void 0 || wrapper.captureTrivia === true || wrapper.rootCapture === "opaque" || wrapper.constructionTrackLines !== "inherit" || wrapper.constructionCaptureTriviaKinds !== void 0) return void 0;
|
|
2906
|
-
if (
|
|
2913
|
+
if (scope2 !== void 0) scope2.cleared = true;
|
|
2907
2914
|
body = wrapper.parser;
|
|
2908
2915
|
continue;
|
|
2909
2916
|
}
|
|
@@ -3160,10 +3167,10 @@ function directFixedLexNode(parser2, resolve2, active, pureOnly = false, cleared
|
|
|
3160
3167
|
}
|
|
3161
3168
|
}
|
|
3162
3169
|
function directFixedTokenBody(parser2, resolve2) {
|
|
3163
|
-
const
|
|
3164
|
-
const body = directTokenBodyParser(parser2, resolve2,
|
|
3170
|
+
const scope2 = { cleared: false };
|
|
3171
|
+
const body = directTokenBodyParser(parser2, resolve2, scope2);
|
|
3165
3172
|
if (body === void 0) return void 0;
|
|
3166
|
-
const root = directFixedLexNode(body, resolve2, /* @__PURE__ */ new Set(), false,
|
|
3173
|
+
const root = directFixedLexNode(body, resolve2, /* @__PURE__ */ new Set(), false, scope2.cleared);
|
|
3167
3174
|
return root === void 0 ? void 0 : { kind: "fixed-tree", root };
|
|
3168
3175
|
}
|
|
3169
3176
|
function directBalancedTokenBody(parser2, resolve2) {
|
|
@@ -4251,15 +4258,20 @@ function markUnusedValues(root) {
|
|
|
4251
4258
|
case "many":
|
|
4252
4259
|
case "oneOrMore":
|
|
4253
4260
|
mark(def, consumed);
|
|
4254
|
-
visit(def.parser, consumed);
|
|
4255
|
-
return;
|
|
4256
4261
|
case "optional":
|
|
4262
|
+
// `optional` returns `inner | null` — no aggregate array/tuple to elide, so
|
|
4263
|
+
// it carries no valueUnused flag. Still descend so an inner many/sequence
|
|
4264
|
+
// under a node() is analyzed (it benefits even when its optional wrapper
|
|
4265
|
+
// doesn't).
|
|
4266
|
+
case "label":
|
|
4267
|
+
case "trivia":
|
|
4268
|
+
case "attempt":
|
|
4269
|
+
case "withCtx":
|
|
4270
|
+
case "expect":
|
|
4257
4271
|
visit(def.parser, consumed);
|
|
4258
4272
|
return;
|
|
4259
4273
|
case "sequence":
|
|
4260
4274
|
mark(def, consumed);
|
|
4261
|
-
for (const p of def.parsers) visit(p, consumed);
|
|
4262
|
-
return;
|
|
4263
4275
|
case "choice":
|
|
4264
4276
|
for (const p of def.parsers) visit(p, consumed);
|
|
4265
4277
|
return;
|
|
@@ -4270,22 +4282,24 @@ function markUnusedValues(root) {
|
|
|
4270
4282
|
if (def.otherwise) visit(def.otherwise, consumed);
|
|
4271
4283
|
return;
|
|
4272
4284
|
case "node":
|
|
4285
|
+
// builds from captured children, NOT the inner parser value.
|
|
4286
|
+
case "not":
|
|
4287
|
+
case "peek":
|
|
4288
|
+
// lookahead — value never observed
|
|
4289
|
+
case "token":
|
|
4273
4290
|
visit(def.parser, false);
|
|
4274
4291
|
return;
|
|
4275
4292
|
case "transform":
|
|
4276
|
-
|
|
4277
|
-
return;
|
|
4293
|
+
// the map fn reads the value → always consumed.
|
|
4278
4294
|
case "field":
|
|
4295
|
+
// the field capture records the parsed value → always consumed.
|
|
4296
|
+
case "leaf":
|
|
4279
4297
|
visit(def.parser, true);
|
|
4280
4298
|
return;
|
|
4281
4299
|
case "sepBy":
|
|
4282
4300
|
visit(def.parser, true);
|
|
4283
4301
|
visit(def.separator, false);
|
|
4284
4302
|
return;
|
|
4285
|
-
case "not":
|
|
4286
|
-
case "peek":
|
|
4287
|
-
visit(def.parser, false);
|
|
4288
|
-
return;
|
|
4289
4303
|
case "grammar":
|
|
4290
4304
|
visit(def.parser, consumed);
|
|
4291
4305
|
if (def.triviaParser) visit(def.triviaParser, false);
|
|
@@ -4294,19 +4308,6 @@ function markUnusedValues(root) {
|
|
|
4294
4308
|
visit(def.parser, consumed);
|
|
4295
4309
|
visit(def.sentinel, false);
|
|
4296
4310
|
return;
|
|
4297
|
-
case "token":
|
|
4298
|
-
visit(def.parser, false);
|
|
4299
|
-
return;
|
|
4300
|
-
case "label":
|
|
4301
|
-
case "trivia":
|
|
4302
|
-
case "attempt":
|
|
4303
|
-
case "withCtx":
|
|
4304
|
-
case "expect":
|
|
4305
|
-
visit(def.parser, consumed);
|
|
4306
|
-
return;
|
|
4307
|
-
case "leaf":
|
|
4308
|
-
visit(def.parser, true);
|
|
4309
|
-
return;
|
|
4310
4311
|
case "lazy":
|
|
4311
4312
|
return;
|
|
4312
4313
|
default:
|
|
@@ -4336,6 +4337,12 @@ function markUnusedValues(root) {
|
|
|
4336
4337
|
visit(resolveRoot(root), true);
|
|
4337
4338
|
}
|
|
4338
4339
|
|
|
4340
|
+
// src/combinators/link-scope.ts
|
|
4341
|
+
var scope;
|
|
4342
|
+
function afterLink(settle) {
|
|
4343
|
+
scope?.push(settle);
|
|
4344
|
+
}
|
|
4345
|
+
|
|
4339
4346
|
// src/cst/root-trivia-scope.ts
|
|
4340
4347
|
var ROOT_TRIVIA_SCOPE_REFUSAL = "parser(): selected root trivia requires classifiedTrivia() for every local trivia scope, or rootCapture: 'opaque'.";
|
|
4341
4348
|
function refuseUnclassifiedRootScope(strict) {
|
|
@@ -4446,7 +4453,7 @@ function parser(opts, root) {
|
|
|
4446
4453
|
ctx.triviaKindLabels = void 0;
|
|
4447
4454
|
} else if (scopeTrivia !== void 0) {
|
|
4448
4455
|
ctx.trivia = scopeTrivia;
|
|
4449
|
-
|
|
4456
|
+
ctx.triviaKindLabels = scopeLabels;
|
|
4450
4457
|
}
|
|
4451
4458
|
if (forceCaptureTrivia || _ctx?.captureTrivia) ctx.captureTrivia = true;
|
|
4452
4459
|
if (ownCaptureMask !== void 0) ctx._triviaCaptureMask = ownCaptureMask;
|
|
@@ -4592,7 +4599,7 @@ function choice(...args) {
|
|
|
4592
4599
|
const result = parsers[idx].parse(input, pos, ctx);
|
|
4593
4600
|
if (result.ok) return result;
|
|
4594
4601
|
expected.push(...result.expected);
|
|
4595
|
-
if (result.committed) return { ok: false, expected, span:
|
|
4602
|
+
if (result.committed) return { ok: false, expected, span: result.span, committed: true };
|
|
4596
4603
|
return { ok: false, expected, span: { start: pos, end: pos } };
|
|
4597
4604
|
}
|
|
4598
4605
|
if (ctx._probe !== void 0 || ctx._tolerant) for (const p of parsers) p.parse(input, pos, ctx);
|
|
@@ -5492,6 +5499,9 @@ function regex(pattern, flags = "") {
|
|
|
5492
5499
|
};
|
|
5493
5500
|
}
|
|
5494
5501
|
|
|
5502
|
+
// src/version.ts
|
|
5503
|
+
var PARSEMAN_VERSION = "0.61.0";
|
|
5504
|
+
|
|
5495
5505
|
// src/table/lex-body.ts
|
|
5496
5506
|
function buildLexBodyRecognizer(spec, constants) {
|
|
5497
5507
|
const raw = constants[spec[0]];
|
|
@@ -6107,11 +6117,12 @@ function assemblyExtraIps(prog) {
|
|
|
6107
6117
|
}
|
|
6108
6118
|
function expandCompact(p) {
|
|
6109
6119
|
if ("code" in p) return p;
|
|
6120
|
+
if (p.es === void 0) throw new Error(`parseman: this parser was printed by an earlier parseman; reprint it with parseman ${PARSEMAN_VERSION}`);
|
|
6110
6121
|
return ownTableProgram({
|
|
6111
6122
|
code: p.c,
|
|
6112
6123
|
k: p.k,
|
|
6113
6124
|
cc: p.x,
|
|
6114
|
-
fx: p.e,
|
|
6125
|
+
fx: p.e.map((set) => set.map((i) => p.es[i])),
|
|
6115
6126
|
disp: p.d,
|
|
6116
6127
|
rules: p.r,
|
|
6117
6128
|
fns: p.f,
|
|
@@ -7177,6 +7188,7 @@ var OP_LIT_CI = 27;
|
|
|
7177
7188
|
var OP_LIT_CI_TRACK = 28;
|
|
7178
7189
|
var OP_TOKEN = 29;
|
|
7179
7190
|
var OP_SCOPE_CAP = 30;
|
|
7191
|
+
var SCOPE_INHERIT = -2;
|
|
7180
7192
|
var OP_WITHCTX = 31;
|
|
7181
7193
|
var OP_GUARD = 32;
|
|
7182
7194
|
var OP_ADJ = 33;
|
|
@@ -7311,8 +7323,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
7311
7323
|
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || buildArity !== void 0 || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...buildArity !== void 0 ? { buildArity } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
|
|
7312
7324
|
const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
7313
7325
|
const readsState = build ? buildReadsState(def) : project === void 0;
|
|
7314
|
-
|
|
7315
|
-
|
|
7326
|
+
let hasOwnFields = parserHasOwnFields(combinator);
|
|
7327
|
+
let capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
|
|
7328
|
+
if (!hasOwnFields) {
|
|
7329
|
+
afterLink(() => {
|
|
7330
|
+
hasOwnFields = parserHasOwnFields(combinator);
|
|
7331
|
+
capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
|
|
7332
|
+
});
|
|
7333
|
+
}
|
|
7316
7334
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
7317
7335
|
let failExpected;
|
|
7318
7336
|
return {
|
|
@@ -8976,7 +8994,7 @@ var Encoder = class {
|
|
|
8976
8994
|
this.triviaKnown = savedKnown;
|
|
8977
8995
|
if (d.clearTrivia === true) return this.emit(op, -1, bodyIp, flags);
|
|
8978
8996
|
if (d.triviaParser === void 0) {
|
|
8979
|
-
return cap
|
|
8997
|
+
return cap ? this.emit(op, SCOPE_INHERIT, bodyIp, flags) : bodyIp;
|
|
8980
8998
|
}
|
|
8981
8999
|
return this.emit(op, this.triviaSlot(d.triviaParser), bodyIp, flags);
|
|
8982
9000
|
}
|
|
@@ -10368,7 +10386,7 @@ function transfer(code, ip, at, hostCst) {
|
|
|
10368
10386
|
const op = code[ip];
|
|
10369
10387
|
if (op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN) {
|
|
10370
10388
|
const ki = code[ip + 1];
|
|
10371
|
-
const tri = ki < 0 ? TRI_NONE : ki;
|
|
10389
|
+
const tri = ki === SCOPE_INHERIT ? at.tri : ki < 0 ? TRI_NONE : ki;
|
|
10372
10390
|
const cap = op === OP_SCOPE_CAP ? CAP_ON : at.cap;
|
|
10373
10391
|
if (tri === at.tri && cap === at.cap) return at;
|
|
10374
10392
|
return { tri, buf: at.buf, raw: at.raw, cap };
|
|
@@ -10442,7 +10460,7 @@ function scanHandoffNeeded(code, ip, labels) {
|
|
|
10442
10460
|
if (l.tri === TRI_UNKNOWN) return true;
|
|
10443
10461
|
const op = code[at];
|
|
10444
10462
|
if (op === OP_SCAN) return true;
|
|
10445
|
-
if (op === OP_TOKEN || op === OP_SCOPE_CAP) continue;
|
|
10463
|
+
if (op === OP_TOKEN || op === OP_SCOPE_CAP && code[at + 1] !== SCOPE_INHERIT) continue;
|
|
10446
10464
|
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;
|
|
10447
10465
|
kids.length = 0;
|
|
10448
10466
|
if (!childSlots(code, at, kids)) return true;
|
|
@@ -11737,6 +11755,15 @@ return r.value
|
|
|
11737
11755
|
const cap = op === OP_SCOPE_CAP;
|
|
11738
11756
|
const flags = op === OP_SCOPE_PLAIN ? 0 : code[ip + 3];
|
|
11739
11757
|
const child = link(code[ip + 2]);
|
|
11758
|
+
if (ki === SCOPE_INHERIT) {
|
|
11759
|
+
return `${head}
|
|
11760
|
+
const sC=ctx.captureTrivia
|
|
11761
|
+
ctx.captureTrivia=true
|
|
11762
|
+
const v=${child}(input,pos,ctx)
|
|
11763
|
+
ctx.captureTrivia=sC
|
|
11764
|
+
return v
|
|
11765
|
+
}`;
|
|
11766
|
+
}
|
|
11740
11767
|
const scanFor = swapLegal && ki >= 0 && !triviaLabelled[ki] ? hoist("ts", `TRIVIASCAN[${ki}]`) : "null";
|
|
11741
11768
|
const tri = ki < 0 ? "undefined" : hoist("tv", `TRIVIA[${ki}]`);
|
|
11742
11769
|
const lab = ki < 0 ? "undefined" : hoist("tl", `TRIVIA[${ki}]._meta.triviaKindLabels`);
|
|
@@ -13414,9 +13441,6 @@ function clearOf(ranges, input, from, to) {
|
|
|
13414
13441
|
return true;
|
|
13415
13442
|
}
|
|
13416
13443
|
|
|
13417
|
-
// src/version.ts
|
|
13418
|
-
var PARSEMAN_VERSION = "0.60.5";
|
|
13419
|
-
|
|
13420
13444
|
// src/table/assemble.ts
|
|
13421
13445
|
import { PlainBuf as PlainBuf2, PlainField, PlainLeaf as PlainLeaf9, PlainNode as PlainNode2, PlainSpan as PlainSpan10 } from "../cst/plain.js";
|
|
13422
13446
|
|
|
@@ -14928,6 +14952,16 @@ function assemble(t2, prog, cfg) {
|
|
|
14928
14952
|
case OP_SCOPE_CAP:
|
|
14929
14953
|
case OP_SCOPE_PLAIN: {
|
|
14930
14954
|
const ki = code[ip + 1];
|
|
14955
|
+
if (ki === SCOPE_INHERIT) {
|
|
14956
|
+
const body = link(code[ip + 2]);
|
|
14957
|
+
return (input, pos, ctx) => {
|
|
14958
|
+
const savedCap = ctx.captureTrivia;
|
|
14959
|
+
ctx.captureTrivia = true;
|
|
14960
|
+
const v = body(input, pos, ctx);
|
|
14961
|
+
ctx.captureTrivia = savedCap;
|
|
14962
|
+
return v;
|
|
14963
|
+
};
|
|
14964
|
+
}
|
|
14931
14965
|
const scopeTrivia = ki < 0 ? void 0 : trivia2[ki];
|
|
14932
14966
|
const scopeLabels = scopeTrivia?._meta.triviaKindLabels;
|
|
14933
14967
|
const scanFor = swapLegal && ki >= 0 && !triviaLabelled[ki] ? triviaScan[ki] : null;
|
|
@@ -17386,12 +17420,15 @@ function assertPrintable(prog, who) {
|
|
|
17386
17420
|
}
|
|
17387
17421
|
}
|
|
17388
17422
|
function programFields(prog, fns, opts = {}) {
|
|
17423
|
+
const tokens = [...new Set(prog.fx.flat())];
|
|
17424
|
+
const tokenAt = new Map(tokens.map((token2, i) => [token2, i]));
|
|
17389
17425
|
return [
|
|
17390
17426
|
...emitAssemblies(prog, opts.assemblies ?? []),
|
|
17391
17427
|
`c:[${prog.code.join(",")}],`,
|
|
17392
17428
|
`k:[${prog.k.map(emitConst).join(",")}],`,
|
|
17393
17429
|
`x:${emitClassPool(prog.cc)},`,
|
|
17394
|
-
`e:[${prog.fx.map((f) => `[${f.map(
|
|
17430
|
+
`e:[${prog.fx.map((f) => `[${f.map((token2) => tokenAt.get(token2)).join(",")}]`).join(",")}],`,
|
|
17431
|
+
`es:[${tokens.map(jsString).join(",")}],`,
|
|
17395
17432
|
`d:[${prog.disp.map((a) => `[${a.join(",")}]`).join(",")}],`,
|
|
17396
17433
|
`r:${JSON.stringify(prog.rules)},`,
|
|
17397
17434
|
...prog.lines === 1 ? ["l:1,"] : [],
|