parseman 0.49.0 → 0.50.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/commitment.d.ts +2 -1
- package/dist/analysis/commitment.d.ts.map +1 -1
- package/dist/analysis/diagnostics.js +1931 -861
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/analysis/rebuild.d.ts.map +1 -1
- package/dist/cli/index.js +1235 -164
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/trivia-skip.d.ts +1 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/build-arity.d.ts +16 -0
- package/dist/compiler/build-arity.d.ts.map +1 -1
- package/dist/compiler/degradation.d.ts +0 -2
- package/dist/compiler/degradation.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts +11 -0
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +185 -20
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/cst/capture-buffer.d.ts +5 -1
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.js +1348 -279
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +2 -1
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/entry-supercompiler.d.ts +48 -0
- package/dist/plugin/entry-supercompiler.d.ts.map +1 -0
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1940 -385
- package/dist/plugin/index.js.map +3 -3
- package/dist/run/index.js +2 -1
- package/dist/run/index.js.map +1 -1
- package/dist/spec/index.js +28 -7
- package/dist/spec/index.js.map +1 -1
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +6 -5
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +6 -1
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/index.js +1298 -231
- package/dist/table/index.js.map +3 -3
- package/dist/table/ops.d.ts +3 -2
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +15 -1
- package/dist/table/program.d.ts.map +1 -1
- package/dist/table/scalar-terminal.d.ts +30 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -1
- package/dist/table/site-labels.d.ts +8 -0
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/analysis/commitment.ts +19 -8
- package/src/analysis/rebuild.ts +1 -0
- package/src/combinators/trivia-skip.ts +2 -2
- package/src/compiler/build-arity.ts +50 -0
- package/src/compiler/degradation.ts +0 -6
- package/src/compiler/ir-serialize.ts +6 -4
- package/src/compiler/token-alphabet.ts +322 -28
- package/src/cst/capture-buffer.ts +34 -11
- package/src/plugin/entry-supercompiler.ts +567 -0
- package/src/plugin/evaluator.ts +10 -0
- package/src/plugin/index.ts +7 -3
- package/src/table/assemble.ts +125 -42
- package/src/table/compile-rule-map.ts +8 -7
- package/src/table/compile.ts +7 -8
- package/src/table/emit-assembly.ts +646 -126
- package/src/table/emit.ts +1 -1
- package/src/table/encode.ts +132 -7
- package/src/table/ops.ts +3 -2
- package/src/table/program.ts +44 -3
- package/src/table/scalar-terminal.ts +213 -1
- package/src/table/site-labels.ts +22 -9
- package/src/types.ts +1 -1
- package/src/version.ts +1 -1
package/src/table/assemble.ts
CHANGED
|
@@ -125,11 +125,12 @@ import {
|
|
|
125
125
|
type SubtreeRef, type TableProgram, type TableRule,
|
|
126
126
|
} from './program.ts'
|
|
127
127
|
import { stampRuleMap } from './stamp.ts'
|
|
128
|
-
import { reachableSites } from './site-labels.ts'
|
|
128
|
+
import { computeSiteLabels, reachableSites } from './site-labels.ts'
|
|
129
129
|
import { refuseUnclassifiedRootScope } from '../cst/root-trivia-scope.ts'
|
|
130
130
|
import { captureError, firstSetSentinel, matchesAt, orSentinel, recoverScan } from '../recovery/scan.ts'
|
|
131
131
|
import {
|
|
132
|
-
|
|
132
|
+
leadingLiteralFamily, leadingScalarSequence, leadingScalarTerminal, makeScalarRecognizer, scalarTerminalNodeChild,
|
|
133
|
+
scalarTerminalNotChild, type ScalarRecognizer,
|
|
133
134
|
} from './scalar-terminal.ts'
|
|
134
135
|
|
|
135
136
|
/**
|
|
@@ -482,6 +483,16 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
482
483
|
return recognize
|
|
483
484
|
}
|
|
484
485
|
|
|
486
|
+
const labelExtraIps: number[] = []
|
|
487
|
+
for (const s of prog.scans ?? []) {
|
|
488
|
+
for (const r of s.skip) labelExtraIps.push(r[0])
|
|
489
|
+
if (s.sentinel !== undefined) labelExtraIps.push(s.sentinel[0])
|
|
490
|
+
}
|
|
491
|
+
for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0])
|
|
492
|
+
const closureLabels = computeSiteLabels(
|
|
493
|
+
code, [...Object.values(prog.rules), ...labelExtraIps], hostCst,
|
|
494
|
+
)
|
|
495
|
+
|
|
485
496
|
/**
|
|
486
497
|
* The INSTALLED trivia scanner for the scope currently running.
|
|
487
498
|
*
|
|
@@ -818,7 +829,9 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
818
829
|
// has no single form. `rollbackNeeded` short-circuits true on a live buffer,
|
|
819
830
|
// so the other seven sinks are not consulted — as before.
|
|
820
831
|
const raw = b.raw
|
|
821
|
-
MRAW =
|
|
832
|
+
MRAW = b.noRaw === true
|
|
833
|
+
? b.rawLen ?? 0
|
|
834
|
+
: raw !== undefined ? raw.length : b.rawSingle !== undefined ? 1 : 0
|
|
822
835
|
const ch = b.ch
|
|
823
836
|
MLV = ch !== undefined ? ch.length : b.single !== undefined ? 1 : 0
|
|
824
837
|
const tl = b.tl
|
|
@@ -1004,6 +1017,33 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
1004
1017
|
return cur
|
|
1005
1018
|
}
|
|
1006
1019
|
|
|
1020
|
+
/** A non-first term at a site proven to run under an open node capture buffer. */
|
|
1021
|
+
function nextTermBuffered(child: Piece, input: string, cur: number, ctx: ParseContext): number {
|
|
1022
|
+
if (ctx.trivia === undefined) {
|
|
1023
|
+
const v = child(input, cur, ctx)
|
|
1024
|
+
if (v === FAIL) return -1
|
|
1025
|
+
TERMV = v
|
|
1026
|
+
return EC.e
|
|
1027
|
+
}
|
|
1028
|
+
const before = ctx._cstBuf!
|
|
1029
|
+
const beforeTl = before.tl
|
|
1030
|
+
const mTl = beforeTl === undefined ? 0 : beforeTl.length
|
|
1031
|
+
const mLog = ctx._triviaLog?.length ?? 0
|
|
1032
|
+
const mRoot = ctx._rootTriviaLog?.length ?? 0
|
|
1033
|
+
const scanEnd = skipTrivia(input, cur, ctx)
|
|
1034
|
+
const scanned = ctx._cstBuf!
|
|
1035
|
+
const scannedTl = scanned.tl
|
|
1036
|
+
const scanTl = scannedTl === undefined ? 0 : scannedTl.length
|
|
1037
|
+
const scanLog = ctx._triviaLog?.length ?? 0
|
|
1038
|
+
const scanRoot = ctx._rootTriviaLog?.length ?? 0
|
|
1039
|
+
const v = child(input, scanEnd, ctx)
|
|
1040
|
+
if (v === FAIL) return -1
|
|
1041
|
+
TERMV = v
|
|
1042
|
+
if (EC.e > scanEnd) return EC.e
|
|
1043
|
+
rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot)
|
|
1044
|
+
return cur
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1007
1047
|
function committed(c: ParseContext): boolean {
|
|
1008
1048
|
return c._fc === true
|
|
1009
1049
|
}
|
|
@@ -1288,7 +1328,16 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
1288
1328
|
const holder = { fwd, set: (p: Piece) => { target = p } }
|
|
1289
1329
|
inFlight.set(ip, holder)
|
|
1290
1330
|
|
|
1291
|
-
const
|
|
1331
|
+
const op = code[ip]
|
|
1332
|
+
// Match the emitted assembly's label-proven scope alias: rule entries in a
|
|
1333
|
+
// single ambient trivia scope otherwise reinstall and restore the exact
|
|
1334
|
+
// same trivia, labels and scanner on every call. Install the forwarding
|
|
1335
|
+
// holder first so a recursive child can still link back through this site.
|
|
1336
|
+
const piece = (op === OP_SCOPE_PLAIN || (op === OP_SCOPE && code[ip + 3]! === 0))
|
|
1337
|
+
&& code[ip + 1]! >= 0
|
|
1338
|
+
&& closureLabels.at(ip).tri === code[ip + 1]!
|
|
1339
|
+
? link(code[ip + 2]!)
|
|
1340
|
+
: lower(ip)
|
|
1292
1341
|
|
|
1293
1342
|
inFlight.delete(ip)
|
|
1294
1343
|
holder.set(piece)
|
|
@@ -2148,6 +2197,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2148
2197
|
const fn = fused && projection < 0
|
|
2149
2198
|
? fns[reducer] as (value: unknown, span: { start: number; end: number }) => unknown
|
|
2150
2199
|
: undefined
|
|
2200
|
+
const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm
|
|
2151
2201
|
|
|
2152
2202
|
const runnerBlock = (
|
|
2153
2203
|
count: number,
|
|
@@ -2255,7 +2305,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2255
2305
|
const kid = link(kidIp)
|
|
2256
2306
|
return (input, cur, ctx, inherited) => {
|
|
2257
2307
|
ctx._sync = sync ?? inherited
|
|
2258
|
-
return
|
|
2308
|
+
return step(kid, input, cur, ctx)
|
|
2259
2309
|
}
|
|
2260
2310
|
}
|
|
2261
2311
|
const negated = code[kidIp + 1] === 1
|
|
@@ -2328,7 +2378,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2328
2378
|
const kidIp = code[base + i]!
|
|
2329
2379
|
if (code[kidIp] !== OP_ADJ) {
|
|
2330
2380
|
const kid = link(kidIp)
|
|
2331
|
-
return (input, cur, ctx) =>
|
|
2381
|
+
return (input, cur, ctx) => step(kid, input, cur, ctx)
|
|
2332
2382
|
}
|
|
2333
2383
|
const negated = code[kidIp + 1] === 1
|
|
2334
2384
|
const ki = code[kidIp + 2]!
|
|
@@ -2436,7 +2486,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2436
2486
|
return (input, pos, ctx) => {
|
|
2437
2487
|
const v0 = k0(input, pos, ctx)
|
|
2438
2488
|
if (v0 === FAIL) return FAIL
|
|
2439
|
-
const cur =
|
|
2489
|
+
const cur = step(k1, input, EC.e, ctx)
|
|
2440
2490
|
if (cur < 0) return FAIL
|
|
2441
2491
|
EC.e = cur
|
|
2442
2492
|
return projection === 0 ? v0
|
|
@@ -2448,7 +2498,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2448
2498
|
return (input, pos, ctx) => {
|
|
2449
2499
|
const v0 = k0(input, pos, ctx)
|
|
2450
2500
|
if (v0 === FAIL) return FAIL
|
|
2451
|
-
const cur =
|
|
2501
|
+
const cur = step(k1, input, EC.e, ctx)
|
|
2452
2502
|
if (cur < 0) return FAIL
|
|
2453
2503
|
EC.e = cur
|
|
2454
2504
|
return [v0, TERMV]
|
|
@@ -2457,7 +2507,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2457
2507
|
return (input, pos, ctx) => {
|
|
2458
2508
|
const v0 = k0(input, pos, ctx)
|
|
2459
2509
|
if (v0 === FAIL) return FAIL
|
|
2460
|
-
const cur =
|
|
2510
|
+
const cur = step(k1, input, EC.e, ctx)
|
|
2461
2511
|
if (cur < 0) return FAIL
|
|
2462
2512
|
EC.e = cur
|
|
2463
2513
|
return undefined
|
|
@@ -2470,10 +2520,10 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2470
2520
|
return (input, pos, ctx) => {
|
|
2471
2521
|
const v0 = k0(input, pos, ctx)
|
|
2472
2522
|
if (v0 === FAIL) return FAIL
|
|
2473
|
-
let cur =
|
|
2523
|
+
let cur = step(k1, input, EC.e, ctx)
|
|
2474
2524
|
if (cur < 0) return FAIL
|
|
2475
2525
|
const v1 = TERMV
|
|
2476
|
-
cur =
|
|
2526
|
+
cur = step(k2, input, cur, ctx)
|
|
2477
2527
|
if (cur < 0) return FAIL
|
|
2478
2528
|
EC.e = cur
|
|
2479
2529
|
return projection === 0 ? v0
|
|
@@ -2486,10 +2536,10 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2486
2536
|
return (input, pos, ctx) => {
|
|
2487
2537
|
const v0 = k0(input, pos, ctx)
|
|
2488
2538
|
if (v0 === FAIL) return FAIL
|
|
2489
|
-
let cur =
|
|
2539
|
+
let cur = step(k1, input, EC.e, ctx)
|
|
2490
2540
|
if (cur < 0) return FAIL
|
|
2491
2541
|
const v1 = TERMV
|
|
2492
|
-
cur =
|
|
2542
|
+
cur = step(k2, input, cur, ctx)
|
|
2493
2543
|
if (cur < 0) return FAIL
|
|
2494
2544
|
EC.e = cur
|
|
2495
2545
|
return [v0, v1, TERMV]
|
|
@@ -2498,9 +2548,9 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2498
2548
|
return (input, pos, ctx) => {
|
|
2499
2549
|
const v0 = k0(input, pos, ctx)
|
|
2500
2550
|
if (v0 === FAIL) return FAIL
|
|
2501
|
-
let cur =
|
|
2551
|
+
let cur = step(k1, input, EC.e, ctx)
|
|
2502
2552
|
if (cur < 0) return FAIL
|
|
2503
|
-
cur =
|
|
2553
|
+
cur = step(k2, input, cur, ctx)
|
|
2504
2554
|
if (cur < 0) return FAIL
|
|
2505
2555
|
EC.e = cur
|
|
2506
2556
|
return undefined
|
|
@@ -2516,43 +2566,43 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2516
2566
|
next: SequenceTermBlock | undefined,
|
|
2517
2567
|
): SequenceTermBlock => {
|
|
2518
2568
|
if (count === 1) return (input, cur, ctx, values) => {
|
|
2519
|
-
cur =
|
|
2569
|
+
cur = step(k0, input, cur, ctx)
|
|
2520
2570
|
if (cur < 0) return -1
|
|
2521
2571
|
if (values !== undefined) values.push(TERMV)
|
|
2522
2572
|
return next === undefined ? cur : next(input, cur, ctx, values)
|
|
2523
2573
|
}
|
|
2524
2574
|
if (count === 2) return (input, cur, ctx, values) => {
|
|
2525
|
-
cur =
|
|
2575
|
+
cur = step(k0, input, cur, ctx)
|
|
2526
2576
|
if (cur < 0) return -1
|
|
2527
2577
|
if (values !== undefined) values.push(TERMV)
|
|
2528
|
-
cur =
|
|
2578
|
+
cur = step(k1, input, cur, ctx)
|
|
2529
2579
|
if (cur < 0) return -1
|
|
2530
2580
|
if (values !== undefined) values.push(TERMV)
|
|
2531
2581
|
return next === undefined ? cur : next(input, cur, ctx, values)
|
|
2532
2582
|
}
|
|
2533
2583
|
if (count === 3) return (input, cur, ctx, values) => {
|
|
2534
|
-
cur =
|
|
2584
|
+
cur = step(k0, input, cur, ctx)
|
|
2535
2585
|
if (cur < 0) return -1
|
|
2536
2586
|
if (values !== undefined) values.push(TERMV)
|
|
2537
|
-
cur =
|
|
2587
|
+
cur = step(k1, input, cur, ctx)
|
|
2538
2588
|
if (cur < 0) return -1
|
|
2539
2589
|
if (values !== undefined) values.push(TERMV)
|
|
2540
|
-
cur =
|
|
2590
|
+
cur = step(k2, input, cur, ctx)
|
|
2541
2591
|
if (cur < 0) return -1
|
|
2542
2592
|
if (values !== undefined) values.push(TERMV)
|
|
2543
2593
|
return next === undefined ? cur : next(input, cur, ctx, values)
|
|
2544
2594
|
}
|
|
2545
2595
|
return (input, cur, ctx, values) => {
|
|
2546
|
-
cur =
|
|
2596
|
+
cur = step(k0, input, cur, ctx)
|
|
2547
2597
|
if (cur < 0) return -1
|
|
2548
2598
|
if (values !== undefined) values.push(TERMV)
|
|
2549
|
-
cur =
|
|
2599
|
+
cur = step(k1, input, cur, ctx)
|
|
2550
2600
|
if (cur < 0) return -1
|
|
2551
2601
|
if (values !== undefined) values.push(TERMV)
|
|
2552
|
-
cur =
|
|
2602
|
+
cur = step(k2, input, cur, ctx)
|
|
2553
2603
|
if (cur < 0) return -1
|
|
2554
2604
|
if (values !== undefined) values.push(TERMV)
|
|
2555
|
-
cur =
|
|
2605
|
+
cur = step(k3, input, cur, ctx)
|
|
2556
2606
|
if (cur < 0) return -1
|
|
2557
2607
|
if (values !== undefined) values.push(TERMV)
|
|
2558
2608
|
return next === undefined ? cur : next(input, cur, ctx, values)
|
|
@@ -2722,6 +2772,13 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2722
2772
|
if (n === 2 || n === 3) {
|
|
2723
2773
|
const a0 = link(code[base]!), a1 = link(code[base + 1]!)
|
|
2724
2774
|
const a2 = n === 3 ? link(code[base + 2]!) : undefined
|
|
2775
|
+
const predecide = !hostCst && !REC && !cfg.probe && !cfg.coverage && !cfg.trackLines
|
|
2776
|
+
const p0ip = predecide ? leadingScalarTerminal(code, code[base]!, 2, true, true) : -1
|
|
2777
|
+
const p1ip = predecide ? leadingScalarTerminal(code, code[base + 1]!, 2, true, true) : -1
|
|
2778
|
+
const p2ip = predecide && n === 3 ? leadingScalarTerminal(code, code[base + 2]!, 2, true, true) : -1
|
|
2779
|
+
const p0 = p0ip < 0 ? undefined : scalarFor(p0ip)
|
|
2780
|
+
const p1 = p1ip < 0 ? undefined : scalarFor(p1ip)
|
|
2781
|
+
const p2 = p2ip < 0 ? undefined : scalarFor(p2ip)
|
|
2725
2782
|
const e0 = fx[code[base + n]!] as string[]
|
|
2726
2783
|
const e1 = fx[code[base + n + 1]!] as string[]
|
|
2727
2784
|
const e2 = n === 3 ? fx[code[base + n + 2]!] as string[] : undefined
|
|
@@ -2751,7 +2808,10 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2751
2808
|
let acc: string[] | undefined
|
|
2752
2809
|
let best = pos
|
|
2753
2810
|
if (c < 128) {
|
|
2754
|
-
|
|
2811
|
+
let bits = mask[c < 0 ? 128 : c]!
|
|
2812
|
+
if ((bits & 1) !== 0 && p0 !== undefined && p0(input, pos) < 0) bits &= ~1
|
|
2813
|
+
if ((bits & 2) !== 0 && p1 !== undefined && p1(input, pos) < 0) bits &= ~2
|
|
2814
|
+
if ((bits & 4) !== 0 && p2 !== undefined && p2(input, pos) < 0) bits &= ~4
|
|
2755
2815
|
let prev = 0
|
|
2756
2816
|
if ((bits & 1) !== 0) {
|
|
2757
2817
|
ctx._fc = false
|
|
@@ -2796,7 +2856,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2796
2856
|
return FAIL
|
|
2797
2857
|
}
|
|
2798
2858
|
|
|
2799
|
-
if (g0 === null || classHas(g0, c)) {
|
|
2859
|
+
if ((g0 === null || classHas(g0, c)) && (p0 === undefined || p0(input, pos) >= 0)) {
|
|
2800
2860
|
ctx._fc = false
|
|
2801
2861
|
const v = a0(input, pos, ctx)
|
|
2802
2862
|
if (v !== FAIL) return v
|
|
@@ -2806,7 +2866,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2806
2866
|
if (committed(ctx)) { if (acc !== undefined) ctx._fx = acc; return FAIL }
|
|
2807
2867
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot)
|
|
2808
2868
|
} else if (best === pos) acc = accSet(e0, acc)
|
|
2809
|
-
if (g1 === null || classHas(g1, c)) {
|
|
2869
|
+
if ((g1 === null || classHas(g1, c)) && (p1 === undefined || p1(input, pos) >= 0)) {
|
|
2810
2870
|
ctx._fc = false
|
|
2811
2871
|
const v = a1(input, pos, ctx)
|
|
2812
2872
|
if (v !== FAIL) return v
|
|
@@ -2817,7 +2877,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
2817
2877
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot)
|
|
2818
2878
|
} else if (best === pos) acc = accSet(e1, acc)
|
|
2819
2879
|
if (n === 3) {
|
|
2820
|
-
if (g2 === null || classHas(g2, c)) {
|
|
2880
|
+
if ((g2 === null || classHas(g2, c)) && (p2 === undefined || p2(input, pos) >= 0)) {
|
|
2821
2881
|
ctx._fc = false
|
|
2822
2882
|
const v = a2!(input, pos, ctx)
|
|
2823
2883
|
if (v !== FAIL) return v
|
|
@@ -3432,6 +3492,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
3432
3492
|
// grammar collapse form and the host collapse predicate.
|
|
3433
3493
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap
|
|
3434
3494
|
const rawOnly = !keepChildren
|
|
3495
|
+
const omitsRaw = !hostCst && build !== undefined && proj < 0 && (flags & 2) !== 0
|
|
3435
3496
|
return (input, pos, ctx) => {
|
|
3436
3497
|
const host = HOST
|
|
3437
3498
|
// `beginCstNodeCapture`/`endCstNodeCapture` INLINED, and the two objects
|
|
@@ -3444,17 +3505,12 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
3444
3505
|
// allocations a parse that the compiled engine (which inlines its own
|
|
3445
3506
|
// capture prologue and epilogue) never makes.
|
|
3446
3507
|
const sCh = ctx._cstChildren
|
|
3447
|
-
const sLv = ctx._cstLeaves
|
|
3448
|
-
const sRaw = ctx._cstRawChildren
|
|
3449
|
-
const sTl = ctx._cstTriviaLog
|
|
3450
3508
|
const sCap = ctx.captureTrivia
|
|
3451
3509
|
const sBuf = ctx._cstBuf
|
|
3452
|
-
const buf: CstCaptureBuf = rawOnly
|
|
3510
|
+
const buf: CstCaptureBuf = rawOnly
|
|
3511
|
+
? { rawOnly: true }
|
|
3512
|
+
: omitsRaw ? { noRaw: true, rawLen: 0 } : {}
|
|
3453
3513
|
ctx._cstBuf = buf
|
|
3454
|
-
ctx._cstChildren = undefined
|
|
3455
|
-
ctx._cstLeaves = undefined
|
|
3456
|
-
ctx._cstRawChildren = undefined
|
|
3457
|
-
ctx._cstTriviaLog = undefined
|
|
3458
3514
|
// `begin` sets this true and the caller immediately cleared it when the
|
|
3459
3515
|
// node does not capture wide. Net: the flag IS `captureWide`, a const.
|
|
3460
3516
|
ctx.captureTrivia = captureWide
|
|
@@ -3476,13 +3532,11 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
3476
3532
|
if (structural) ctx._triviaCaptureMask = savedMask
|
|
3477
3533
|
const kids = rawOnly ? EMPTY_CH : buf.ch ?? (buf.single !== undefined ? [buf.single] : EMPTY_CH)
|
|
3478
3534
|
const hostKids = kids
|
|
3479
|
-
const rawKids =
|
|
3535
|
+
const rawKids = omitsRaw
|
|
3536
|
+
? EMPTY_CH
|
|
3537
|
+
: buf.raw ?? (buf.rawSingle !== undefined ? [buf.rawSingle] : EMPTY_CH)
|
|
3480
3538
|
const tlog = buf.tl ?? EMPTY_TLOG
|
|
3481
3539
|
ctx._cstBuf = sBuf
|
|
3482
|
-
ctx._cstChildren = sCh
|
|
3483
|
-
ctx._cstLeaves = sLv
|
|
3484
|
-
ctx._cstRawChildren = sRaw
|
|
3485
|
-
ctx._cstTriviaLog = sTl
|
|
3486
3540
|
ctx.captureTrivia = sCap
|
|
3487
3541
|
if (v === FAIL) return FAIL
|
|
3488
3542
|
const end = EC.e
|
|
@@ -3620,6 +3674,35 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
3620
3674
|
rawScalarSpecs.add(code[child + 1]!)
|
|
3621
3675
|
scalarFor(child)
|
|
3622
3676
|
}
|
|
3677
|
+
} else if (code[ip] === OP_CHOICE && !disp[code[ip + 1]!]!.exclusive) {
|
|
3678
|
+
const n = code[ip + 2]!
|
|
3679
|
+
for (let i = 0; i < n; i++) {
|
|
3680
|
+
const armIp = code[ip + 4 + i]!
|
|
3681
|
+
const child = leadingScalarTerminal(code, armIp, 2, true, true)
|
|
3682
|
+
if (n === 2 || n === 3) {
|
|
3683
|
+
if (child >= 0) scalarFor(child)
|
|
3684
|
+
continue
|
|
3685
|
+
}
|
|
3686
|
+
if (child >= 0) {
|
|
3687
|
+
const spec = k[code[child + 1]!]
|
|
3688
|
+
if (code[child] === OP_LIT && typeof spec === 'string' && spec.length >= 2) {
|
|
3689
|
+
scalarFor(child)
|
|
3690
|
+
continue
|
|
3691
|
+
}
|
|
3692
|
+
}
|
|
3693
|
+
const family = leadingLiteralFamily(code, k, armIp)
|
|
3694
|
+
if (family !== undefined && family.length >= 2 && family.every(terminal => {
|
|
3695
|
+
const value = k[code[terminal + 1]!]
|
|
3696
|
+
return typeof value === 'string' && value.length >= 2
|
|
3697
|
+
})) {
|
|
3698
|
+
for (const terminal of family) scalarFor(terminal)
|
|
3699
|
+
}
|
|
3700
|
+
const sequence = leadingScalarSequence(code, armIp)
|
|
3701
|
+
if (sequence !== undefined && (sequence.trivia < 0
|
|
3702
|
+
|| triviaScan[sequence.trivia] != null)) {
|
|
3703
|
+
for (const terminal of sequence.terminals) scalarFor(terminal)
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3623
3706
|
}
|
|
3624
3707
|
}
|
|
3625
3708
|
const notChild = scalarTerminalNotChild(code, ip)
|
|
@@ -116,16 +116,17 @@ export type CompiledRuleMapTable = {
|
|
|
116
116
|
hostBranchElided: boolean
|
|
117
117
|
reflection: GrammarReflection
|
|
118
118
|
/**
|
|
119
|
-
* The RUNNABLE map, which the source lowering has no counterpart for — it
|
|
119
|
+
* The LIVE RUNNABLE map, which the source lowering has no counterpart for — it
|
|
120
120
|
* hands back text and nothing else, because its artifact only exists once the
|
|
121
121
|
* emitted source is evaluated. A table exists as data before it is printed, so
|
|
122
122
|
* the same call that produces the replacement can also hand back the parser.
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
123
|
+
* It may use runtime assembly specialisation; `prog` and `replacement` remain
|
|
124
|
+
* serialized closure artifacts. That is what makes a differential against the
|
|
125
|
+
* interpreter possible without `eval`, and it is why the table-vs-interpreter
|
|
126
|
+
* test can compare `expected` sets rather than only accept/reject.
|
|
126
127
|
*/
|
|
127
128
|
rules: Record<string, TableRule>
|
|
128
|
-
/** The
|
|
129
|
+
/** The closure-stamped wire program, for a caller that wants to fold or inspect it. */
|
|
129
130
|
prog: TableProgram
|
|
130
131
|
/**
|
|
131
132
|
* The coverage DENOMINATOR — every id this map can hit — present only under
|
|
@@ -237,7 +238,7 @@ export function compileRuleMapRunnable(
|
|
|
237
238
|
hostBranchElided: hostMode === 'ast' && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
238
239
|
reflection: collectGrammarReflection(ruleMap),
|
|
239
240
|
...(plan === undefined ? {} : { coverageDefinitions: plan.definitions }),
|
|
240
|
-
rules: tableRules(
|
|
241
|
+
rules: tableRules(prog),
|
|
241
242
|
prog: artifact,
|
|
242
243
|
}
|
|
243
244
|
}
|
|
@@ -348,7 +349,7 @@ export function compileRuleMap(
|
|
|
348
349
|
hostBranchElided: hostMode === 'ast' && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
349
350
|
reflection: collectGrammarReflection(ruleMap),
|
|
350
351
|
...(plan === undefined ? {} : { coverageDefinitions: plan.definitions }),
|
|
351
|
-
rules: tableRules(
|
|
352
|
+
rules: tableRules(prog),
|
|
352
353
|
prog: artifact,
|
|
353
354
|
}
|
|
354
355
|
}
|
package/src/table/compile.ts
CHANGED
|
@@ -156,17 +156,16 @@ function compileImpl<T>(
|
|
|
156
156
|
// this is the same guard on the single-root entry point.
|
|
157
157
|
const { prog, fnSrcs } = encodeTableProgram({ [ENTRY]: combinator as Combinator<unknown> }, settings)
|
|
158
158
|
/**
|
|
159
|
-
*
|
|
159
|
+
* LIVE parsers may assemble the encoded program into specialised functions.
|
|
160
|
+
* `tableRules` falls back to closure assembly when dynamic construction is not
|
|
161
|
+
* available, so this remains runnable under a restrictive CSP.
|
|
160
162
|
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
* canonical: both paths carry an explicit empty inventory and use the shared
|
|
165
|
-
* closure assembler. Static factories remain an opt-in experiment until they
|
|
166
|
-
* can satisfy both semantic identity and the size budget.
|
|
163
|
+
* PRINTED artifacts are different: they must not require `new Function` after
|
|
164
|
+
* import. Give the emitters the canonical explicit-empty assembly inventory,
|
|
165
|
+
* while the parser returned by this call runs the raw program's fast path.
|
|
167
166
|
*/
|
|
168
167
|
const artifact = closureArtifact(prog)
|
|
169
|
-
const entry = tableRules(
|
|
168
|
+
const entry = tableRules(prog)[ENTRY]!
|
|
170
169
|
|
|
171
170
|
// Captured-first, supplied-as-fill-in. The encoder records a source per author
|
|
172
171
|
// callback from the def (`fnSrc` / `buildSrc` / `predSrc` / `gateSrcs`), which the
|