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/dist/table/index.js
CHANGED
|
@@ -351,7 +351,8 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
351
351
|
b.single = void 0;
|
|
352
352
|
} else b.single = built;
|
|
353
353
|
}
|
|
354
|
-
if (b.
|
|
354
|
+
if (b.noRaw === true) b.rawLen = (b.rawLen ?? 0) + 1;
|
|
355
|
+
else if (b.raw) b.raw.push(rawEntry2);
|
|
355
356
|
else if (b.rawSingle !== void 0) {
|
|
356
357
|
b.raw = [b.rawSingle, rawEntry2];
|
|
357
358
|
b.rawSingle = void 0;
|
|
@@ -365,6 +366,7 @@ function pushCstChild(ctx, built, rawEntry2) {
|
|
|
365
366
|
function cstRawLen(ctx) {
|
|
366
367
|
const b = ctx._cstBuf;
|
|
367
368
|
if (b) {
|
|
369
|
+
if (b.noRaw === true) return b.rawLen ?? 0;
|
|
368
370
|
if (b.raw) return b.raw.length;
|
|
369
371
|
return b.rawSingle !== void 0 ? 1 : 0;
|
|
370
372
|
}
|
|
@@ -424,19 +426,37 @@ function rollbackCstCaptureAt(ctx, raw, tlog, leaves, fields, errors) {
|
|
|
424
426
|
if (ctx._errors && errors !== void 0 && ctx._errors.length !== errors) ctx._errors.length = errors;
|
|
425
427
|
const b = ctx._cstBuf;
|
|
426
428
|
if (b) {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
+
if (b.noRaw === true) {
|
|
430
|
+
if (b.rawLen !== raw) b.rawLen = raw;
|
|
431
|
+
} else {
|
|
432
|
+
const rawList = b.raw;
|
|
433
|
+
if (rawList) {
|
|
434
|
+
if (raw === 0) b.raw = void 0;
|
|
435
|
+
else if (raw === 1) {
|
|
436
|
+
b.rawSingle = rawList[0];
|
|
437
|
+
b.raw = void 0;
|
|
438
|
+
} else if (rawList.length !== raw) rawList.length = raw;
|
|
439
|
+
} else if (raw === 0) b.rawSingle = void 0;
|
|
440
|
+
}
|
|
441
|
+
const childList = b.ch;
|
|
442
|
+
if (childList) {
|
|
443
|
+
if (leaves === 0) b.ch = void 0;
|
|
444
|
+
else if (leaves === 1) {
|
|
445
|
+
b.single = childList[0];
|
|
446
|
+
b.ch = void 0;
|
|
447
|
+
} else if (childList.length !== leaves) childList.length = leaves;
|
|
448
|
+
} else if (leaves === 0) b.single = void 0;
|
|
429
449
|
if (b.tl) {
|
|
430
450
|
if (tlog === 0) b.tl = void 0;
|
|
431
451
|
else if (b.tl.length !== tlog) b.tl.length = tlog;
|
|
432
452
|
}
|
|
433
|
-
if (ctx._fields && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
453
|
+
if (ctx._fields && fields !== void 0 && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
434
454
|
return;
|
|
435
455
|
}
|
|
436
456
|
if (ctx._cstRawChildren && ctx._cstRawChildren.length !== raw) ctx._cstRawChildren.length = raw;
|
|
437
457
|
if (ctx._cstTriviaLog && ctx._cstTriviaLog.length !== tlog) ctx._cstTriviaLog.length = tlog;
|
|
438
458
|
if (ctx._cstLeaves && ctx._cstLeaves.length !== leaves) ctx._cstLeaves.length = leaves;
|
|
439
|
-
if (ctx._fields && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
459
|
+
if (ctx._fields && fields !== void 0 && ctx._fields.length !== fields) ctx._fields.length = fields;
|
|
440
460
|
}
|
|
441
461
|
function pushCstTriviaEntry(ctx, start, end, kindIndex) {
|
|
442
462
|
const insertIdx = cstRawLen(ctx);
|
|
@@ -908,6 +928,13 @@ function canConsumeNewline(n) {
|
|
|
908
928
|
return n.parts.some(canConsumeNewline);
|
|
909
929
|
}
|
|
910
930
|
}
|
|
931
|
+
function regexCanMatchEmpty(source) {
|
|
932
|
+
try {
|
|
933
|
+
return nullable(parseRegex(source));
|
|
934
|
+
} catch {
|
|
935
|
+
return true;
|
|
936
|
+
}
|
|
937
|
+
}
|
|
911
938
|
function firstSetFromRegex(source) {
|
|
912
939
|
let ast;
|
|
913
940
|
try {
|
|
@@ -3711,6 +3738,7 @@ function confirmedArityForDef(def) {
|
|
|
3711
3738
|
}
|
|
3712
3739
|
function buildReadsRaw(def) {
|
|
3713
3740
|
if (!def.build) return true;
|
|
3741
|
+
if (def.buildRawUnused === true) return false;
|
|
3714
3742
|
const arity = confirmedArityForDef(def);
|
|
3715
3743
|
if (arity === null) return true;
|
|
3716
3744
|
return arity >= 4;
|
|
@@ -4425,8 +4453,26 @@ function validateDispatchSpec(spec, arity, fallbackRouted) {
|
|
|
4425
4453
|
}
|
|
4426
4454
|
}
|
|
4427
4455
|
var TABLE_RUNTIME = /* @__PURE__ */ Symbol("parseman.tableRuntime");
|
|
4428
|
-
function ownTableProgram(prog, resolved) {
|
|
4429
|
-
|
|
4456
|
+
function ownTableProgram(prog, resolved, caches = {}) {
|
|
4457
|
+
const runtime = prog[TABLE_RUNTIME];
|
|
4458
|
+
return {
|
|
4459
|
+
...prog,
|
|
4460
|
+
[TABLE_RUNTIME]: {
|
|
4461
|
+
resolved,
|
|
4462
|
+
choiceRollbackMasks: caches.choiceRollbackMasks ?? runtime?.choiceRollbackMasks,
|
|
4463
|
+
nonCommittingChoiceSites: caches.nonCommittingChoiceSites ?? runtime?.nonCommittingChoiceSites,
|
|
4464
|
+
failureRollbackCleanSites: caches.failureRollbackCleanSites ?? runtime?.failureRollbackCleanSites
|
|
4465
|
+
}
|
|
4466
|
+
};
|
|
4467
|
+
}
|
|
4468
|
+
function choiceRollbackMask(prog, ip) {
|
|
4469
|
+
return prog[TABLE_RUNTIME]?.choiceRollbackMasks?.get(ip);
|
|
4470
|
+
}
|
|
4471
|
+
function choiceCannotCommit(prog, ip) {
|
|
4472
|
+
return prog[TABLE_RUNTIME]?.nonCommittingChoiceSites?.has(ip) === true;
|
|
4473
|
+
}
|
|
4474
|
+
function failureRollbackClean(prog, ip) {
|
|
4475
|
+
return prog[TABLE_RUNTIME]?.failureRollbackCleanSites?.has(ip) === true;
|
|
4430
4476
|
}
|
|
4431
4477
|
var WIDE_CLASS_PREFIX_LO = 65535;
|
|
4432
4478
|
var WIDE_CLASS_PREFIX_HI = 0;
|
|
@@ -5818,13 +5864,17 @@ var TRI_NONE = -1;
|
|
|
5818
5864
|
var CAP_UNKNOWN = 0;
|
|
5819
5865
|
var CAP_OFF = 1;
|
|
5820
5866
|
var CAP_ON = 2;
|
|
5821
|
-
var
|
|
5867
|
+
var RAW_UNKNOWN = 0;
|
|
5868
|
+
var RAW_CAPTURE = 1;
|
|
5869
|
+
var RAW_OMIT = 2;
|
|
5870
|
+
var TOP = { tri: TRI_UNKNOWN, buf: false, raw: RAW_UNKNOWN, cap: CAP_UNKNOWN };
|
|
5822
5871
|
function meet(a, b) {
|
|
5823
5872
|
const tri = a.tri === b.tri ? a.tri : TRI_UNKNOWN;
|
|
5824
5873
|
const buf = a.buf && b.buf;
|
|
5874
|
+
const raw = a.raw === b.raw ? a.raw : RAW_UNKNOWN;
|
|
5825
5875
|
const cap = a.cap === b.cap ? a.cap : CAP_UNKNOWN;
|
|
5826
|
-
if (tri === a.tri && buf === a.buf && cap === a.cap) return a;
|
|
5827
|
-
return { tri, buf, cap };
|
|
5876
|
+
if (tri === a.tri && buf === a.buf && raw === a.raw && cap === a.cap) return a;
|
|
5877
|
+
return { tri, buf, raw, cap };
|
|
5828
5878
|
}
|
|
5829
5879
|
function reachableSites(code, roots) {
|
|
5830
5880
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -5847,25 +5897,26 @@ function transfer(code, ip, at, hostCst) {
|
|
|
5847
5897
|
const tri = ki < 0 ? TRI_NONE : ki;
|
|
5848
5898
|
const cap = op === OP_SCOPE_CAP ? CAP_ON : at.cap;
|
|
5849
5899
|
if (tri === at.tri && cap === at.cap) return at;
|
|
5850
|
-
return { tri, buf: at.buf, cap };
|
|
5900
|
+
return { tri, buf: at.buf, raw: at.raw, cap };
|
|
5851
5901
|
}
|
|
5852
5902
|
if (op === OP_NODE || op === OP_NODE_TRACK) {
|
|
5853
5903
|
const flags = code[ip + 3];
|
|
5854
5904
|
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
|
|
5855
5905
|
if (directChildren) {
|
|
5856
|
-
return { tri: at.tri, buf: false, cap: CAP_OFF };
|
|
5906
|
+
return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
|
|
5857
5907
|
}
|
|
5858
5908
|
const cap = (flags & 4) !== 0 || hostCst ? CAP_ON : CAP_OFF;
|
|
5859
|
-
|
|
5860
|
-
|
|
5909
|
+
const raw = !hostCst && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags & 2) !== 0 ? RAW_OMIT : RAW_CAPTURE;
|
|
5910
|
+
if (at.buf && raw === at.raw && cap === at.cap) return at;
|
|
5911
|
+
return { tri: at.tri, buf: true, raw, cap };
|
|
5861
5912
|
}
|
|
5862
5913
|
if (op === OP_TOKEN) {
|
|
5863
5914
|
if (at.tri === TRI_NONE && !at.buf) return at;
|
|
5864
|
-
return { tri: TRI_NONE, buf: false, cap: at.cap };
|
|
5915
|
+
return { tri: TRI_NONE, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
|
|
5865
5916
|
}
|
|
5866
5917
|
if (op === OP_LEAF) {
|
|
5867
5918
|
if (!at.buf) return at;
|
|
5868
|
-
return { tri: at.tri, buf: false, cap: at.cap };
|
|
5919
|
+
return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: at.cap };
|
|
5869
5920
|
}
|
|
5870
5921
|
return at;
|
|
5871
5922
|
}
|
|
@@ -5932,6 +5983,162 @@ function scalarTerminalNotChild(code, ip) {
|
|
|
5932
5983
|
const op = code[child];
|
|
5933
5984
|
return op === OP_RX || op === OP_LIT ? child : -1;
|
|
5934
5985
|
}
|
|
5986
|
+
function leadingScalarTerminal(code, ip, minDepth = 2, throughAttempt = true, throughPeek = false) {
|
|
5987
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5988
|
+
let at = ip;
|
|
5989
|
+
let depth = 0;
|
|
5990
|
+
while (!seen.has(at)) {
|
|
5991
|
+
seen.add(at);
|
|
5992
|
+
const op = code[at];
|
|
5993
|
+
if (op === OP_LIT || op === OP_RX) return depth >= minDepth ? at : -1;
|
|
5994
|
+
if (op === OP_RULE || op === OP_LABEL || op === OP_TOKEN || throughAttempt && op === OP_ATTEMPT) {
|
|
5995
|
+
at = code[at + 1];
|
|
5996
|
+
depth++;
|
|
5997
|
+
continue;
|
|
5998
|
+
}
|
|
5999
|
+
if (throughPeek && op === OP_PEEK) {
|
|
6000
|
+
at = code[at + 1];
|
|
6001
|
+
depth++;
|
|
6002
|
+
continue;
|
|
6003
|
+
}
|
|
6004
|
+
if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
6005
|
+
at = code[at + 2];
|
|
6006
|
+
depth++;
|
|
6007
|
+
continue;
|
|
6008
|
+
}
|
|
6009
|
+
if (op === OP_SEQ || op === OP_SEQV) {
|
|
6010
|
+
if (code[at + 1] < 1) return -1;
|
|
6011
|
+
at = code[at + 2];
|
|
6012
|
+
depth++;
|
|
6013
|
+
continue;
|
|
6014
|
+
}
|
|
6015
|
+
if (op === OP_SEQX) {
|
|
6016
|
+
if (code[at + 2] < 1) return -1;
|
|
6017
|
+
at = code[at + 3];
|
|
6018
|
+
depth++;
|
|
6019
|
+
continue;
|
|
6020
|
+
}
|
|
6021
|
+
return -1;
|
|
6022
|
+
}
|
|
6023
|
+
return -1;
|
|
6024
|
+
}
|
|
6025
|
+
function leadingScalarSequence(code, ip) {
|
|
6026
|
+
const wholeScalar = (start) => {
|
|
6027
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
6028
|
+
let at2 = start;
|
|
6029
|
+
while (!seen2.has(at2)) {
|
|
6030
|
+
seen2.add(at2);
|
|
6031
|
+
const op = code[at2];
|
|
6032
|
+
if (op === OP_LIT || op === OP_RX) return at2;
|
|
6033
|
+
if (op === OP_RULE || op === OP_TOKEN || op === OP_ATTEMPT) {
|
|
6034
|
+
at2 = code[at2 + 1];
|
|
6035
|
+
continue;
|
|
6036
|
+
}
|
|
6037
|
+
if (op === OP_GATE || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
6038
|
+
at2 = code[at2 + 2];
|
|
6039
|
+
continue;
|
|
6040
|
+
}
|
|
6041
|
+
if (op === OP_SEQ || op === OP_SEQV) {
|
|
6042
|
+
if (code[at2 + 1] !== 1) return -1;
|
|
6043
|
+
at2 = code[at2 + 2];
|
|
6044
|
+
continue;
|
|
6045
|
+
}
|
|
6046
|
+
if (op === OP_SEQX) {
|
|
6047
|
+
if (code[at2 + 2] !== 1) return -1;
|
|
6048
|
+
at2 = code[at2 + 3];
|
|
6049
|
+
continue;
|
|
6050
|
+
}
|
|
6051
|
+
return -1;
|
|
6052
|
+
}
|
|
6053
|
+
return -1;
|
|
6054
|
+
};
|
|
6055
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6056
|
+
let at = ip;
|
|
6057
|
+
let ambientTrivia;
|
|
6058
|
+
while (!seen.has(at)) {
|
|
6059
|
+
seen.add(at);
|
|
6060
|
+
const op = code[at];
|
|
6061
|
+
if (op === OP_RULE) {
|
|
6062
|
+
at = code[at + 1];
|
|
6063
|
+
continue;
|
|
6064
|
+
}
|
|
6065
|
+
if (op === OP_SCOPE_PLAIN) {
|
|
6066
|
+
ambientTrivia = code[at + 1];
|
|
6067
|
+
at = code[at + 2];
|
|
6068
|
+
continue;
|
|
6069
|
+
}
|
|
6070
|
+
if (op === OP_GATE || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
6071
|
+
at = code[at + 2];
|
|
6072
|
+
continue;
|
|
6073
|
+
}
|
|
6074
|
+
const n = op === OP_SEQ || op === OP_SEQV ? code[at + 1] : op === OP_SEQX ? code[at + 2] : 0;
|
|
6075
|
+
if (n < 3 || ambientTrivia === void 0) return void 0;
|
|
6076
|
+
const base = op === OP_SEQX ? at + 3 : at + 2;
|
|
6077
|
+
const terminals = [
|
|
6078
|
+
wholeScalar(code[base]),
|
|
6079
|
+
wholeScalar(code[base + 1]),
|
|
6080
|
+
wholeScalar(code[base + 2])
|
|
6081
|
+
];
|
|
6082
|
+
return terminals.every((terminal) => terminal >= 0) ? { terminals, trivia: ambientTrivia } : void 0;
|
|
6083
|
+
}
|
|
6084
|
+
return void 0;
|
|
6085
|
+
}
|
|
6086
|
+
function leadingLiteralFamily(code, constants, ip, minDepth = 2, limit = 4) {
|
|
6087
|
+
const active = /* @__PURE__ */ new Set();
|
|
6088
|
+
const walk = (at, depth) => {
|
|
6089
|
+
if (active.has(at)) return void 0;
|
|
6090
|
+
active.add(at);
|
|
6091
|
+
try {
|
|
6092
|
+
const op = code[at];
|
|
6093
|
+
if (op === OP_LIT) {
|
|
6094
|
+
const value = constants[code[at + 1]];
|
|
6095
|
+
return depth >= minDepth && typeof value === "string" && value.length > 0 ? [at] : void 0;
|
|
6096
|
+
}
|
|
6097
|
+
if (op === OP_RULE || op === OP_LABEL || op === OP_TOKEN || op === OP_ATTEMPT || op === OP_PEEK) {
|
|
6098
|
+
return walk(code[at + 1], depth + 1);
|
|
6099
|
+
}
|
|
6100
|
+
if (op === OP_GATE || op === OP_SCOPE || op === OP_SCOPE_CAP || op === OP_SCOPE_PLAIN || op === OP_XFORM || op === OP_NODE || op === OP_FIELD || op === OP_LEAF) {
|
|
6101
|
+
return walk(code[at + 2], depth + 1);
|
|
6102
|
+
}
|
|
6103
|
+
if (op === OP_SEQ || op === OP_SEQV) {
|
|
6104
|
+
return code[at + 1] < 1 ? void 0 : walk(code[at + 2], depth + 1);
|
|
6105
|
+
}
|
|
6106
|
+
if (op === OP_SEQX) {
|
|
6107
|
+
return code[at + 2] < 1 ? void 0 : walk(code[at + 3], depth + 1);
|
|
6108
|
+
}
|
|
6109
|
+
if (op !== OP_CHOICE) return void 0;
|
|
6110
|
+
const n = code[at + 2];
|
|
6111
|
+
if (n < 1) return void 0;
|
|
6112
|
+
const out = [];
|
|
6113
|
+
for (let i = 0; i < n; i++) {
|
|
6114
|
+
const branch = walk(code[at + 4 + i], depth + 1);
|
|
6115
|
+
if (branch === void 0) return void 0;
|
|
6116
|
+
for (const terminal of branch) {
|
|
6117
|
+
const value = constants[code[terminal + 1]];
|
|
6118
|
+
let covered = false;
|
|
6119
|
+
for (let j = 0; j < out.length; j++) {
|
|
6120
|
+
const prior = constants[code[out[j] + 1]];
|
|
6121
|
+
if (value.startsWith(prior)) {
|
|
6122
|
+
covered = true;
|
|
6123
|
+
break;
|
|
6124
|
+
}
|
|
6125
|
+
}
|
|
6126
|
+
if (covered) continue;
|
|
6127
|
+
for (let j = out.length - 1; j >= 0; j--) {
|
|
6128
|
+
const prior = constants[code[out[j] + 1]];
|
|
6129
|
+
if (prior.startsWith(value)) out.splice(j, 1);
|
|
6130
|
+
}
|
|
6131
|
+
out.push(terminal);
|
|
6132
|
+
if (out.length > limit) return void 0;
|
|
6133
|
+
}
|
|
6134
|
+
}
|
|
6135
|
+
return out;
|
|
6136
|
+
} finally {
|
|
6137
|
+
active.delete(at);
|
|
6138
|
+
}
|
|
6139
|
+
};
|
|
6140
|
+
return walk(ip, 0);
|
|
6141
|
+
}
|
|
5935
6142
|
|
|
5936
6143
|
// src/table/emit-assembly.ts
|
|
5937
6144
|
var Unemittable = class extends Error {
|
|
@@ -6013,6 +6220,16 @@ let _pfScan=null
|
|
|
6013
6220
|
let _pfHost
|
|
6014
6221
|
let _pfDepth=0
|
|
6015
6222
|
const _pfFrames=[]
|
|
6223
|
+
let _pfTokInput
|
|
6224
|
+
let _pfTokPos=-1
|
|
6225
|
+
let _pfTokBody=-1
|
|
6226
|
+
let _pfTokPacked=-1
|
|
6227
|
+
let _pfTokValue
|
|
6228
|
+
let _pfTokDispatch=-1
|
|
6229
|
+
let _pfTokArm=-1
|
|
6230
|
+
let _pfTokEnd=-1
|
|
6231
|
+
let _pfSeqEnd=-1
|
|
6232
|
+
function _asciiFoldCode(c){return c>=65&&c<=90?c+32:c}
|
|
6016
6233
|
function _skipTrivia(input,cur,ctx){
|
|
6017
6234
|
const s=_pfScan
|
|
6018
6235
|
if(s!==null&&ctx._triviaLog===undefined&&!(ctx.captureTrivia===true&&(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)))return s(input,cur)
|
|
@@ -6078,6 +6295,40 @@ if(ctx._triviaLog!==undefined&&ctx._triviaLog.length!==lg)ctx._triviaLog.length=
|
|
|
6078
6295
|
if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTriviaLog.length=rt
|
|
6079
6296
|
}
|
|
6080
6297
|
`;
|
|
6298
|
+
var NO_RAW_RUNTIME_PRELUDE = `
|
|
6299
|
+
function _pushLeafNoRawBuf(ctx,value,s,e){
|
|
6300
|
+
const l={_tag:'leaf',value,span:{start:s,end:e}}
|
|
6301
|
+
const b=ctx._cstBuf
|
|
6302
|
+
if(b.ch!==undefined)b.ch.push(l)
|
|
6303
|
+
else if(b.single!==undefined){b.ch=[b.single,l];b.single=undefined}
|
|
6304
|
+
else b.single=l
|
|
6305
|
+
b.rawLen++
|
|
6306
|
+
}
|
|
6307
|
+
function _pushNodeNoRawBuf(ctx,value){
|
|
6308
|
+
const b=ctx._cstBuf
|
|
6309
|
+
if(b.ch!==undefined)b.ch.push(value)
|
|
6310
|
+
else if(b.single!==undefined){b.ch=[b.single,value];b.single=undefined}
|
|
6311
|
+
else b.single=value
|
|
6312
|
+
b.rawLen++
|
|
6313
|
+
}
|
|
6314
|
+
function _rbNoRawBuf(ctx,raw,tl,lv,lg,rt){
|
|
6315
|
+
const b=ctx._cstBuf
|
|
6316
|
+
if(b.rawLen!==raw)b.rawLen=raw
|
|
6317
|
+
const ch=b.ch
|
|
6318
|
+
if(ch!==undefined){
|
|
6319
|
+
if(lv===0)b.ch=undefined
|
|
6320
|
+
else if(lv===1){b.single=ch[0];b.ch=undefined}
|
|
6321
|
+
else if(ch.length!==lv)ch.length=lv
|
|
6322
|
+
}else if(lv===0)b.single=undefined
|
|
6323
|
+
const bt=b.tl
|
|
6324
|
+
if(bt!==undefined){
|
|
6325
|
+
if(tl===0)b.tl=undefined
|
|
6326
|
+
else if(bt.length!==tl)bt.length=tl
|
|
6327
|
+
}
|
|
6328
|
+
if(ctx._triviaLog!==undefined&&ctx._triviaLog.length!==lg)ctx._triviaLog.length=lg
|
|
6329
|
+
if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTriviaLog.length=rt
|
|
6330
|
+
}
|
|
6331
|
+
`;
|
|
6081
6332
|
function q(s) {
|
|
6082
6333
|
return JSON.stringify(s);
|
|
6083
6334
|
}
|
|
@@ -6090,11 +6341,12 @@ function sinkReads(t, s) {
|
|
|
6090
6341
|
${t}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${s.er ? `
|
|
6091
6342
|
${t}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
|
|
6092
6343
|
}
|
|
6093
|
-
function emitMark(t, buf, s = NO_SINKS, decl = true) {
|
|
6344
|
+
function emitMark(t, buf, rawMode, s = NO_SINKS, decl = true) {
|
|
6094
6345
|
if (buf) {
|
|
6346
|
+
const raw = rawMode === RAW_OMIT ? `${t}raw=b.rawLen` : rawMode === RAW_CAPTURE ? `const r=b.raw;${t}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0` : `const r=b.raw;${t}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)`;
|
|
6095
6347
|
return `${decl ? `let ${t}raw=0,${t}tl=0,${t}lv=0,${t}lg=0,${t}rt=0${sinkSlots(t, s)}
|
|
6096
6348
|
` : ""}{const b=ctx._cstBuf
|
|
6097
|
-
|
|
6349
|
+
${raw}
|
|
6098
6350
|
const h=b.ch;${t}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
6099
6351
|
const l=b.tl;${t}tl=l!==undefined?l.length:0
|
|
6100
6352
|
${t}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
@@ -6104,7 +6356,7 @@ ${t}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${sinkReads(t,
|
|
|
6104
6356
|
` : `${t}n=false
|
|
6105
6357
|
`}{const b=ctx._cstBuf
|
|
6106
6358
|
if(b!==undefined){
|
|
6107
|
-
const r=b.raw;${t}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
6359
|
+
const r=b.raw;${t}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)
|
|
6108
6360
|
const h=b.ch;${t}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
6109
6361
|
const l=b.tl;${t}tl=l!==undefined?l.length:0
|
|
6110
6362
|
${t}n=true
|
|
@@ -6119,14 +6371,16 @@ ${t}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
|
6119
6371
|
${t}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${sinkReads(t, s)}
|
|
6120
6372
|
}}`;
|
|
6121
6373
|
}
|
|
6122
|
-
function emitRollback(t, buf, s = NO_SINKS) {
|
|
6374
|
+
function emitRollback(t, buf, rawMode, s = NO_SINKS) {
|
|
6123
6375
|
const fd = s.fd ? `
|
|
6124
6376
|
if(ctx._fields!==undefined&&ctx._fields.length!==${t}fd)ctx._fields.length=${t}fd` : "";
|
|
6125
6377
|
const er = s.er ? `
|
|
6126
6378
|
if(ctx._errors!==undefined&&ctx._errors.length!==${t}er)ctx._errors.length=${t}er` : "";
|
|
6127
|
-
if (buf) return `
|
|
6128
|
-
if (
|
|
6129
|
-
return `
|
|
6379
|
+
if (buf && rawMode === RAW_OMIT) return `_rbNoRawBuf(ctx,${t}raw,${t}tl,${t}lv,${t}lg,${t}rt)${fd}${er}`;
|
|
6380
|
+
if (buf && rawMode === RAW_CAPTURE) return `_rbBuf(ctx,${t}raw,${t}tl,${t}lv,${t}lg,${t}rt)${fd}${er}`;
|
|
6381
|
+
if (buf) return `rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,${s.fd ? `${t}fd` : "undefined"},${s.er ? `${t}er` : "undefined"},${t}lg,${t}rt)`;
|
|
6382
|
+
if (!s.fd && !s.er) return `if(${t}n)rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,undefined,undefined,${t}lg,${t}rt)`;
|
|
6383
|
+
return `if(${t}n){rollbackTriviaAt(ctx,${t}raw,${t}tl,${t}lv,${s.fd ? `${t}fd` : "undefined"},${s.er ? `${t}er` : "undefined"},${t}lg,${t}rt)}`;
|
|
6130
6384
|
}
|
|
6131
6385
|
function emitTerm(callee, dst, t, l, skip) {
|
|
6132
6386
|
const fast = `const ${t}v=${callee}(input,cur,ctx)
|
|
@@ -6184,37 +6438,111 @@ function rebuildPools(cc, fx, disp, plan) {
|
|
|
6184
6438
|
})
|
|
6185
6439
|
};
|
|
6186
6440
|
}
|
|
6187
|
-
function emitAssemblySource(t, prog, cfg, extraIps = []) {
|
|
6188
|
-
const { code, k, disp, dsp, triviaLabelled } = t;
|
|
6441
|
+
function emitAssemblySource(t, prog, cfg, extraIps = [], staticBuild = false) {
|
|
6442
|
+
const { code, k, fx, disp, dsp, triviaLabelled } = t;
|
|
6189
6443
|
const swapLegal = !cfg.trackLines;
|
|
6190
6444
|
const hostCst = cfg.hostCst;
|
|
6191
6445
|
const REC = prog.rec === 1 && cfg.tolerant;
|
|
6192
6446
|
if (cfg.coverage) throw new Unemittable("a coverage assembly");
|
|
6193
6447
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
6448
|
+
const reachable = [...reachableSites(code, roots)];
|
|
6194
6449
|
const labels = computeSiteLabels(code, roots, hostCst);
|
|
6195
6450
|
const scalarSpecs = /* @__PURE__ */ new Set();
|
|
6451
|
+
const largeChoiceScalarSpecs = /* @__PURE__ */ new Set();
|
|
6452
|
+
const largeChoiceLiteralFamilies = /* @__PURE__ */ new Map();
|
|
6453
|
+
const largeChoiceScalarSequences = /* @__PURE__ */ new Map();
|
|
6454
|
+
const tokenChoiceCandidates = /* @__PURE__ */ new Map();
|
|
6455
|
+
const tokenChoiceDispatches = /* @__PURE__ */ new Set();
|
|
6456
|
+
const tokenChoiceBodies = /* @__PURE__ */ new Set();
|
|
6196
6457
|
if (!hostCst && !cfg.tolerant && !cfg.probe && !cfg.coverage && !cfg.trackLines) {
|
|
6197
|
-
for (const ip of
|
|
6198
|
-
if (code[ip]
|
|
6199
|
-
|
|
6200
|
-
|
|
6458
|
+
for (const ip of reachable) {
|
|
6459
|
+
if (code[ip] === OP_NODE) {
|
|
6460
|
+
const child = scalarTerminalNodeChild(code, ip);
|
|
6461
|
+
if (child >= 0) scalarSpecs.add(code[child + 1]);
|
|
6462
|
+
continue;
|
|
6463
|
+
}
|
|
6464
|
+
if (code[ip] !== OP_CHOICE || disp[code[ip + 1]].exclusive) continue;
|
|
6465
|
+
const n = code[ip + 2];
|
|
6466
|
+
for (let i = 0; i < n; i++) {
|
|
6467
|
+
const armIp = code[ip + 4 + i];
|
|
6468
|
+
const child = leadingScalarTerminal(code, armIp, 2, true, true);
|
|
6469
|
+
if (n === 2 || n === 3) {
|
|
6470
|
+
if (child >= 0) scalarSpecs.add(code[child + 1]);
|
|
6471
|
+
continue;
|
|
6472
|
+
}
|
|
6473
|
+
if (child >= 0) {
|
|
6474
|
+
const spec = k[code[child + 1]];
|
|
6475
|
+
if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) {
|
|
6476
|
+
largeChoiceScalarSpecs.add(code[child + 1]);
|
|
6477
|
+
continue;
|
|
6478
|
+
}
|
|
6479
|
+
}
|
|
6480
|
+
const family = leadingLiteralFamily(code, k, armIp);
|
|
6481
|
+
if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
6482
|
+
const value = k[code[terminal + 1]];
|
|
6483
|
+
return typeof value === "string" && value.length >= 2;
|
|
6484
|
+
})) {
|
|
6485
|
+
largeChoiceLiteralFamilies.set(armIp, family);
|
|
6486
|
+
}
|
|
6487
|
+
const sequence6 = leadingScalarSequence(code, armIp);
|
|
6488
|
+
if (sequence6 !== void 0 && (sequence6.trivia < 0 || swapLegal && t.triviaScan[sequence6.trivia] != null)) {
|
|
6489
|
+
largeChoiceScalarSequences.set(armIp, sequence6);
|
|
6490
|
+
}
|
|
6491
|
+
}
|
|
6492
|
+
let candidate;
|
|
6493
|
+
let ambiguous = false;
|
|
6494
|
+
for (let i = 0; i < n; i++) {
|
|
6495
|
+
const armIp = code[ip + 4 + i];
|
|
6496
|
+
if (code[armIp] !== OP_XFORM) continue;
|
|
6497
|
+
const dispatchIp = code[armIp + 2];
|
|
6498
|
+
if (code[dispatchIp] !== OP_DISPATCH) continue;
|
|
6499
|
+
const selectorIp = code[dispatchIp + 1];
|
|
6500
|
+
if (code[selectorIp] !== OP_LEX_BODY) continue;
|
|
6501
|
+
if (candidate !== void 0) {
|
|
6502
|
+
ambiguous = true;
|
|
6503
|
+
break;
|
|
6504
|
+
}
|
|
6505
|
+
candidate = { arm: i, dispatchIp };
|
|
6506
|
+
}
|
|
6507
|
+
if (!ambiguous && candidate !== void 0) {
|
|
6508
|
+
tokenChoiceCandidates.set(ip, candidate);
|
|
6509
|
+
tokenChoiceDispatches.add(candidate.dispatchIp);
|
|
6510
|
+
tokenChoiceBodies.add(code[code[candidate.dispatchIp + 1] + 1]);
|
|
6511
|
+
}
|
|
6201
6512
|
}
|
|
6202
6513
|
}
|
|
6203
|
-
const
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6514
|
+
const needsNoRawPrelude = !hostCst && reachable.some((ip) => {
|
|
6515
|
+
const op = code[ip];
|
|
6516
|
+
return (op === OP_NODE || op === OP_NODE_TRACK) && code[ip + 1] >= 0 && code[ip + 4] < 0 && (code[ip + 3] & 2) !== 0;
|
|
6517
|
+
});
|
|
6518
|
+
const sinkSites = reachable;
|
|
6519
|
+
const sinkBits = /* @__PURE__ */ new Map();
|
|
6520
|
+
for (const ip of sinkSites) {
|
|
6521
|
+
const op = code[ip];
|
|
6522
|
+
sinkBits.set(
|
|
6523
|
+
ip,
|
|
6524
|
+
op === OP_SCAN ? 3 : (op === OP_FIELD ? 1 : 0) | (op === OP_EXPECT || REC && (op === OP_REP || op === OP_REPV) ? 2 : 0)
|
|
6525
|
+
);
|
|
6526
|
+
}
|
|
6527
|
+
const sinkKids = [];
|
|
6528
|
+
let sinkChanged = true;
|
|
6529
|
+
while (sinkChanged) {
|
|
6530
|
+
sinkChanged = false;
|
|
6531
|
+
for (const ip of sinkSites) {
|
|
6532
|
+
let bits = sinkBits.get(ip) ?? 0;
|
|
6533
|
+
sinkKids.length = 0;
|
|
6534
|
+
childSlots(code, ip, sinkKids);
|
|
6535
|
+
for (let i = 0; i < sinkKids.length; i++) bits |= sinkBits.get(sinkKids[i]) ?? 0;
|
|
6536
|
+
if (bits !== sinkBits.get(ip)) {
|
|
6537
|
+
sinkBits.set(ip, bits);
|
|
6538
|
+
sinkChanged = true;
|
|
6212
6539
|
}
|
|
6213
|
-
if (op === OP_FIELD) fd = true;
|
|
6214
|
-
else if (op === OP_EXPECT) er = true;
|
|
6215
6540
|
}
|
|
6216
|
-
|
|
6217
|
-
|
|
6541
|
+
}
|
|
6542
|
+
const sinksAt = (ip) => {
|
|
6543
|
+
const bits = sinkBits.get(ip) ?? 0;
|
|
6544
|
+
return bits === 0 ? NO_SINKS : { fd: (bits & 1) !== 0, er: (bits & 2) !== 0 };
|
|
6545
|
+
};
|
|
6218
6546
|
const bodies = [];
|
|
6219
6547
|
const byIp = /* @__PURE__ */ new Map();
|
|
6220
6548
|
const reached = /* @__PURE__ */ new Set();
|
|
@@ -6241,9 +6569,117 @@ function emitAssemblySource(t, prog, cfg, extraIps = []) {
|
|
|
6241
6569
|
const fxRef = (i) => hoist("fx", `FX[${i}]`);
|
|
6242
6570
|
const fnRef = (i) => hoist("fn", `FNS[${i}]`);
|
|
6243
6571
|
const recognizerRef = (i) => hoist("rec", `RECOG[${i}]`);
|
|
6572
|
+
const scalarSequenceRefs = /* @__PURE__ */ new Map();
|
|
6573
|
+
const scalarSequenceRef = (sequence6) => {
|
|
6574
|
+
const key = `${sequence6.trivia}:${sequence6.terminals.map((terminal) => code[terminal + 1]).join(",")}`;
|
|
6575
|
+
const prior = scalarSequenceRefs.get(key);
|
|
6576
|
+
if (prior !== void 0) return prior;
|
|
6577
|
+
const recognizers = sequence6.terminals.map((terminal) => recognizerRef(code[terminal + 1]));
|
|
6578
|
+
const expected = sequence6.terminals.map((terminal) => fxRef(code[terminal + 2]));
|
|
6579
|
+
const scan = sequence6.trivia < 0 ? void 0 : hoist("ts", `TRIVIASCAN[${sequence6.trivia}]`);
|
|
6580
|
+
const name = `_sd${scalarSequenceRefs.size}_`;
|
|
6581
|
+
const steps = recognizers.map((recognize, i) => `${i === 0 ? "let " : ""}at=${i === 0 ? "pos" : scan === void 0 ? "cur" : `${scan}(input,cur)`}
|
|
6582
|
+
${i === 0 ? "let " : ""}cur=${recognize}(input,at)
|
|
6583
|
+
if(cur<0){_pfSeqEnd=at;return ${~i}}`).join("\n");
|
|
6584
|
+
choiceDefs.push(`function ${name}(input,pos){
|
|
6585
|
+
${steps}
|
|
6586
|
+
return cur
|
|
6587
|
+
}`);
|
|
6588
|
+
const made = { name, expected };
|
|
6589
|
+
scalarSequenceRefs.set(key, made);
|
|
6590
|
+
return made;
|
|
6591
|
+
};
|
|
6244
6592
|
const sentRef = (cls) => cls < 0 ? "undefined" : hoist("sent", `SENTS[${cls}]`);
|
|
6245
6593
|
let uid = 0;
|
|
6246
6594
|
const tmp = () => `_t${uid++}_`;
|
|
6595
|
+
const dispatchClaim = (m) => {
|
|
6596
|
+
switch (m[0]) {
|
|
6597
|
+
case 0:
|
|
6598
|
+
return `key.startsWith(${q(m[1])})`;
|
|
6599
|
+
case 1:
|
|
6600
|
+
return `key.endsWith(${q(m[1])})`;
|
|
6601
|
+
case 3:
|
|
6602
|
+
return `asciiFoldKey(key).startsWith(${q(m[1])})`;
|
|
6603
|
+
case 4:
|
|
6604
|
+
return `asciiFoldKey(key).endsWith(${q(m[1])})`;
|
|
6605
|
+
default: {
|
|
6606
|
+
if (!m[2].includes("g") && !m[2].includes("y")) {
|
|
6607
|
+
try {
|
|
6608
|
+
new RegExp(m[1], m[2]);
|
|
6609
|
+
return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
|
|
6610
|
+
} catch {
|
|
6611
|
+
}
|
|
6612
|
+
}
|
|
6613
|
+
return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
|
|
6614
|
+
}
|
|
6615
|
+
}
|
|
6616
|
+
};
|
|
6617
|
+
const tokenDecisionRefs = /* @__PURE__ */ new Map();
|
|
6618
|
+
function tokenDecisionFor(dispatchIp) {
|
|
6619
|
+
const prior = tokenDecisionRefs.get(dispatchIp);
|
|
6620
|
+
if (prior !== void 0) return prior;
|
|
6621
|
+
const selectorIp = code[dispatchIp + 1];
|
|
6622
|
+
const body = code[selectorIp + 1];
|
|
6623
|
+
const lineFlags = code[selectorIp + 4];
|
|
6624
|
+
const hasSuffix = (lineFlags & 4) !== 0;
|
|
6625
|
+
const di = code[dispatchIp + 2];
|
|
6626
|
+
const spec = dsp[di];
|
|
6627
|
+
const n = code[dispatchIp + 5];
|
|
6628
|
+
validateDispatchSpec(spec, n, code[dispatchIp + 4]);
|
|
6629
|
+
const recognize = hoist("lex", `LEX[${body}]`);
|
|
6630
|
+
const bk = hoist("bk", `DSP[${di}].byKey`);
|
|
6631
|
+
const expected = hoist("dx", `DSP[${di}].expected`);
|
|
6632
|
+
const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
|
|
6633
|
+
` : "";
|
|
6634
|
+
const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
|
|
6635
|
+
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${dispatchClaim(m)})arm=${m[3]}`).join("\n")}
|
|
6636
|
+
}
|
|
6637
|
+
`;
|
|
6638
|
+
const foldedEntries = [...spec.byFold.entries()];
|
|
6639
|
+
const fixedFunctionChoice = spec.byKey.size === 0 && foldedEntries.length === 1 && spec.match.length === 1 && spec.match[0][0] === 2 && spec.match[0][1] === "^(?!(?:url|calc)\\($).+\\($" && spec.match[0][2] === "i" && code[dispatchIp + 3] < 0;
|
|
6640
|
+
const foldedRangeEquals = (value) => {
|
|
6641
|
+
const folded = value.replace(/[A-Z]/g, (c) => c.toLowerCase());
|
|
6642
|
+
return `e-pos===${folded.length}&&${[...folded].map((c, i) => {
|
|
6643
|
+
const cc = c.charCodeAt(0);
|
|
6644
|
+
return `_asciiFoldCode(input.charCodeAt(pos+${i}))===${cc}`;
|
|
6645
|
+
}).join("&&")}`;
|
|
6646
|
+
};
|
|
6647
|
+
const classify = fixedFunctionChoice ? (() => {
|
|
6648
|
+
const [exact, exactArm] = foldedEntries[0];
|
|
6649
|
+
const genericArm = spec.match[0][3];
|
|
6650
|
+
return `let arm
|
|
6651
|
+
if(${foldedRangeEquals(exact)})arm=${exactArm}
|
|
6652
|
+
else if(sm&&e>pos+1){
|
|
6653
|
+
let clean=true
|
|
6654
|
+
for(let i=pos;i<e;i++){const c=input.charCodeAt(i);if(c===10||c===13||c===0x2028||c===0x2029){clean=false;break}}
|
|
6655
|
+
if(clean&&!(${foldedRangeEquals("url(")})&&!(${foldedRangeEquals("calc(")}))arm=${genericArm}
|
|
6656
|
+
}`;
|
|
6657
|
+
})() : `const key=input.slice(pos,e)
|
|
6658
|
+
let arm=${bk}.get(key)
|
|
6659
|
+
${fold}${chain}`;
|
|
6660
|
+
const name = `_td${tokenDecisionRefs.size}_`;
|
|
6661
|
+
choiceDefs.push(`function ${name}(input,pos){
|
|
6662
|
+
const r=${recognize}(input,pos)
|
|
6663
|
+
if(r<0)return -1
|
|
6664
|
+
const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
|
|
6665
|
+
${classify}
|
|
6666
|
+
if(arm===undefined){
|
|
6667
|
+
${code[dispatchIp + 3] < 0 ? "_pfTokEnd=e;return 0" : `arm=${n}`}
|
|
6668
|
+
}
|
|
6669
|
+
${fixedFunctionChoice ? "const key=input.slice(pos,e)" : ""}
|
|
6670
|
+
_pfTokInput=input
|
|
6671
|
+
_pfTokPos=pos
|
|
6672
|
+
_pfTokBody=${body}
|
|
6673
|
+
_pfTokPacked=r
|
|
6674
|
+
_pfTokValue=key
|
|
6675
|
+
_pfTokDispatch=${dispatchIp}
|
|
6676
|
+
_pfTokArm=arm
|
|
6677
|
+
return 1
|
|
6678
|
+
}`);
|
|
6679
|
+
const made = { name, expected };
|
|
6680
|
+
tokenDecisionRefs.set(dispatchIp, made);
|
|
6681
|
+
return made;
|
|
6682
|
+
}
|
|
6247
6683
|
function skipFor(l) {
|
|
6248
6684
|
if (l.tri < 0) return "_skipTrivia";
|
|
6249
6685
|
const ki = l.tri;
|
|
@@ -6331,7 +6767,8 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
6331
6767
|
const op = code[ip];
|
|
6332
6768
|
const head = `function ${fname}(input,pos,ctx){`;
|
|
6333
6769
|
const L = labels.at(ip);
|
|
6334
|
-
const
|
|
6770
|
+
const sinks = sinksAt(ip);
|
|
6771
|
+
const pushLeaf = L.buf && !cfg.trackLines ? L.raw === RAW_OMIT ? "_pushLeafNoRawBuf" : L.raw === RAW_CAPTURE ? "_pushLeafBuf" : "_pushLeaf" : "_pushLeaf";
|
|
6335
6772
|
const captureLeaf = (value) => {
|
|
6336
6773
|
const call = `${pushLeaf}(ctx,${value},pos,e)`;
|
|
6337
6774
|
return L.buf ? call : `if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)${call}`;
|
|
@@ -6582,20 +7019,24 @@ return out
|
|
|
6582
7019
|
}`;
|
|
6583
7020
|
}
|
|
6584
7021
|
case OP_LEX_BODY: {
|
|
6585
|
-
const
|
|
7022
|
+
const body = code[ip + 1];
|
|
7023
|
+
const recognize = hoist("lex", `LEX[${body}]`);
|
|
6586
7024
|
const expected = fxRef(code[ip + 2]);
|
|
6587
7025
|
const suffixExpected = fxRef(code[ip + 3]);
|
|
6588
7026
|
const lineFlags = code[ip + 4];
|
|
6589
7027
|
const hasSuffix = (lineFlags & 4) !== 0;
|
|
7028
|
+
const pending = tokenChoiceBodies.has(body);
|
|
6590
7029
|
return `${head}
|
|
6591
|
-
const
|
|
7030
|
+
${pending ? `const tp=_pfTokBody===${body}&&_pfTokInput===input&&_pfTokPos===pos
|
|
7031
|
+
const r=tp?_pfTokPacked:${recognize}(input,pos)` : `const r=${recognize}(input,pos)`}
|
|
6592
7032
|
if(r<0){ctx._fe=pos;ctx._fx=${expected};if(ctx._probe!==undefined)failAt(ctx,${expected},pos);return FAIL}
|
|
6593
7033
|
const sm=${hasSuffix ? "r%2===1" : "false"},e=(r-(sm?1:0))/2
|
|
6594
7034
|
${(lineFlags & 1) !== 0 ? "_trackLines(ctx,input,sm?e-1:e)" : ""}
|
|
6595
7035
|
${hasSuffix ? "ctx._fc=false" : ""}
|
|
6596
7036
|
${hasSuffix && (lineFlags & 2) !== 0 ? "if(sm)_trackLines(ctx,input,e)" : ""}
|
|
6597
7037
|
${hasSuffix ? `if(!sm){ctx._fe=e;ctx._fx=${suffixExpected};if(ctx._probe!==undefined)failAt(ctx,${suffixExpected},e)}` : ""}
|
|
6598
|
-
const v
|
|
7038
|
+
const v=${pending ? "tp?_pfTokValue:" : ""}input.slice(pos,e)
|
|
7039
|
+
${pending ? "if(tp){_pfTokBody=-1;_pfTokValue=undefined}" : ""}
|
|
6599
7040
|
if(ctx._cstBuf!==undefined||ctx._cstLeaves!==undefined)pushCstLeaf(ctx,{_tag:'leaf',value:v,span:{start:pos,end:e}})
|
|
6600
7041
|
EC.e=e
|
|
6601
7042
|
return v
|
|
@@ -6651,12 +7092,13 @@ return v
|
|
|
6651
7092
|
/* ── transaction ─────────────────────────────────────────────────────── */
|
|
6652
7093
|
case OP_ATTEMPT: {
|
|
6653
7094
|
const child = link(code[ip + 1]);
|
|
7095
|
+
const clean = !REC && failureRollbackClean(prog, ip);
|
|
6654
7096
|
const p = tmp();
|
|
6655
7097
|
return `${head}
|
|
6656
|
-
${emitMark(p, L.buf, sinks)}
|
|
7098
|
+
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
6657
7099
|
const v=${child}(input,pos,ctx)
|
|
6658
7100
|
if(v!==FAIL)return v
|
|
6659
|
-
${emitRollback(p, L.buf, sinks)}
|
|
7101
|
+
${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
|
|
6660
7102
|
if(ctx._fc===true)return FAIL
|
|
6661
7103
|
ctx._fe=pos
|
|
6662
7104
|
return FAIL
|
|
@@ -6679,9 +7121,9 @@ return FAIL
|
|
|
6679
7121
|
const xf = fxRef(code[ip + 2]);
|
|
6680
7122
|
const p = tmp();
|
|
6681
7123
|
return `${head}
|
|
6682
|
-
${emitMark(p, L.buf, sinks)}
|
|
7124
|
+
${emitMark(p, L.buf, L.raw, sinks)}
|
|
6683
7125
|
const v=${child}(input,pos,ctx)
|
|
6684
|
-
${emitRollback(p, L.buf, sinks)}
|
|
7126
|
+
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
6685
7127
|
if(v===FAIL){EC.e=pos;return null}
|
|
6686
7128
|
ctx._fe=pos
|
|
6687
7129
|
ctx._fx=${xf}
|
|
@@ -6693,9 +7135,9 @@ return FAIL
|
|
|
6693
7135
|
const xf = fxRef(code[ip + 2]);
|
|
6694
7136
|
const p = tmp();
|
|
6695
7137
|
return `${head}
|
|
6696
|
-
${emitMark(p, L.buf, sinks)}
|
|
7138
|
+
${emitMark(p, L.buf, L.raw, sinks)}
|
|
6697
7139
|
const v=${child}(input,pos,ctx)
|
|
6698
|
-
${emitRollback(p, L.buf, sinks)}
|
|
7140
|
+
${emitRollback(p, L.buf, L.raw, sinks)}
|
|
6699
7141
|
if(v===FAIL){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
6700
7142
|
EC.e=pos
|
|
6701
7143
|
return null
|
|
@@ -6703,14 +7145,15 @@ return null
|
|
|
6703
7145
|
}
|
|
6704
7146
|
case OP_OPT: {
|
|
6705
7147
|
const child = link(code[ip + 1]);
|
|
7148
|
+
const clean = !REC && failureRollbackClean(prog, ip);
|
|
6706
7149
|
const p = tmp();
|
|
6707
7150
|
return `${head}
|
|
6708
|
-
${emitMark(p, L.buf, sinks)}
|
|
7151
|
+
${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
6709
7152
|
ctx._fc=false
|
|
6710
7153
|
const v=${child}(input,pos,ctx)
|
|
6711
7154
|
if(v===FAIL){
|
|
6712
7155
|
if(ctx._fc===true)return FAIL
|
|
6713
|
-
${emitRollback(p, L.buf, sinks)}
|
|
7156
|
+
${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
|
|
6714
7157
|
EC.e=pos
|
|
6715
7158
|
return null
|
|
6716
7159
|
}
|
|
@@ -6809,57 +7252,193 @@ return FAIL
|
|
|
6809
7252
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
6810
7253
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
6811
7254
|
const gateRefs = Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
7255
|
+
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
7256
|
+
const pretests = Array.from({ length: n }, (_, i) => {
|
|
7257
|
+
if (tokenCandidate?.arm === i) {
|
|
7258
|
+
return { token: tokenDecisionFor(tokenCandidate.dispatchIp) };
|
|
7259
|
+
}
|
|
7260
|
+
const terminal = leadingScalarTerminal(code, code[base + i], 2, true, true);
|
|
7261
|
+
if (terminal >= 0) {
|
|
7262
|
+
const spec = code[terminal + 1];
|
|
7263
|
+
if ((n === 2 || n === 3 ? scalarSpecs : largeChoiceScalarSpecs).has(spec)) {
|
|
7264
|
+
return { scalar: [recognizerRef(spec)] };
|
|
7265
|
+
}
|
|
7266
|
+
}
|
|
7267
|
+
const family = largeChoiceLiteralFamilies.get(code[base + i]);
|
|
7268
|
+
if (family !== void 0) {
|
|
7269
|
+
return { scalar: family.map((member) => recognizerRef(code[member + 1])) };
|
|
7270
|
+
}
|
|
7271
|
+
const sequence6 = largeChoiceScalarSequences.get(code[base + i]);
|
|
7272
|
+
return sequence6 === void 0 ? void 0 : { sequence: scalarSequenceRef(sequence6) };
|
|
7273
|
+
});
|
|
6812
7274
|
const maskable = n <= 32;
|
|
6813
7275
|
const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
|
|
6814
7276
|
if (maskable) maskPlan.push(~di);
|
|
6815
7277
|
const p = tmp();
|
|
6816
|
-
const
|
|
6817
|
-
|
|
7278
|
+
const encodedRollbackMask = choiceRollbackMask(prog, ip) ?? -1;
|
|
7279
|
+
const rollbackMask = REC ? -1 : encodedRollbackMask;
|
|
7280
|
+
const hasRollback = rollbackMask !== 0;
|
|
7281
|
+
const startFailureExact = arms.every((_arm, i) => {
|
|
7282
|
+
const terminal = leadingScalarTerminal(code, code[base + i], 0, false);
|
|
7283
|
+
if (terminal < 0) return false;
|
|
7284
|
+
const op2 = code[terminal];
|
|
7285
|
+
const spec = k[code[terminal + 1]];
|
|
7286
|
+
const terminalFx = fx[code[terminal + 2]];
|
|
7287
|
+
const armFx = fx[code[base + n + i]];
|
|
7288
|
+
if (terminalFx.length !== armFx.length || terminalFx.some((expected2, at) => expected2 !== armFx[at])) return false;
|
|
7289
|
+
if (op2 === OP_LIT) return typeof spec === "string" && spec.length > 0;
|
|
7290
|
+
return op2 === OP_RX && spec instanceof RegExp && !regexCanMatchEmpty(spec.source);
|
|
7291
|
+
});
|
|
7292
|
+
const rollbackFor = (i) => rollbackMask === -1 || (rollbackMask & 1 << i) !== 0 ? emitRollback(p, L.buf, L.raw, sinks) : "";
|
|
7293
|
+
if (choiceCannotCommit(prog, ip) && !startFailureExact) {
|
|
7294
|
+
const deepAt = Array.from({ length: n }, () => tmp());
|
|
7295
|
+
const deepFx = Array.from({ length: n }, () => tmp());
|
|
7296
|
+
const remember = (i, at, expectedSet) => `${deepAt[i]}=${at};${deepFx[i]}=${expectedSet}`;
|
|
7297
|
+
const lazyArms = (ascii) => arms.map((arm, i) => {
|
|
7298
|
+
const pretest = pretests[i];
|
|
7299
|
+
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
7300
|
+
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
7301
|
+
const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
|
|
7302
|
+
const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
|
|
7303
|
+
const gate = ascii ? `(bits&${1 << i})!==0${condition}` : `(${gateRefs[i]}===null||classHas(${gateRefs[i]},c))${condition}`;
|
|
7304
|
+
const routeMiss = pretest?.token === void 0 ? "" : `
|
|
7305
|
+
if(${decision}===0){
|
|
7306
|
+
ctx._fc=false
|
|
7307
|
+
{const at=_pfTokEnd
|
|
7308
|
+
${remember(i, "at", pretest.token.expected)}}
|
|
7309
|
+
}`;
|
|
7310
|
+
const sequenceMiss = pretest?.sequence === void 0 ? "" : `
|
|
7311
|
+
else if(${ascii ? `(bits&${1 << i})!==0&&` : ""}${decision}<0){
|
|
7312
|
+
ctx._fc=false
|
|
7313
|
+
{const at=_pfSeqEnd
|
|
7314
|
+
${remember(i, "at", pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("") + pretest.sequence.expected.at(-1))}}
|
|
7315
|
+
}`;
|
|
7316
|
+
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
7317
|
+
`}if(${gate}){
|
|
7318
|
+
ctx._fc=false
|
|
7319
|
+
{const v=${arm}(input,pos,ctx)
|
|
7320
|
+
if(v!==FAIL)return v}
|
|
7321
|
+
{const at=ctx._fe??pos
|
|
7322
|
+
${remember(i, "at", "ctx._fx")}}
|
|
7323
|
+
${rollbackFor(i)}
|
|
7324
|
+
}${routeMiss}${sequenceMiss}`;
|
|
7325
|
+
}).join("\n");
|
|
7326
|
+
const merge = deepAt.map((at, i) => `{const at=${at}??pos
|
|
7327
|
+
const ex=${at}===undefined?${expected[i]}:${deepFx[i]}
|
|
7328
|
+
if(at>best){best=at;acc=_accSet(ex,undefined)}
|
|
7329
|
+
else if(at===best)acc=_accSet(ex,acc)
|
|
7330
|
+
}`).join("\n");
|
|
7331
|
+
const finish = `let best=pos,acc
|
|
7332
|
+
${merge}
|
|
7333
|
+
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
7334
|
+
return FAIL`;
|
|
7335
|
+
return `${head}
|
|
7336
|
+
const c=lead(input,pos)
|
|
7337
|
+
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
7338
|
+
${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
|
|
7339
|
+
${maskable ? `if(c<128){
|
|
7340
|
+
const bits=${maskName}[c<0?128:c]
|
|
7341
|
+
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
7342
|
+
${lazyArms(true)}
|
|
7343
|
+
}else{
|
|
7344
|
+
${lazyArms(false)}
|
|
7345
|
+
}
|
|
7346
|
+
` : lazyArms(false)}
|
|
7347
|
+
${finish}
|
|
7348
|
+
}`;
|
|
7349
|
+
}
|
|
7350
|
+
const needsCatch = maskable || startFailureExact;
|
|
7351
|
+
const catchName = needsCatch ? `_cx${uid++}_` : "";
|
|
7352
|
+
if (needsCatch) {
|
|
6818
7353
|
const catchCases = expected.map((e, i) => `case ${i}:if(target<=${i})return acc;acc=_accSet(${e},acc)`).join("\n");
|
|
6819
7354
|
choiceDefs.push(`function ${catchName}(target,prev,acc){switch(prev){
|
|
6820
7355
|
${catchCases}
|
|
6821
7356
|
}return acc}`);
|
|
6822
7357
|
}
|
|
6823
7358
|
const maskArms = maskable ? arms.map((arm, i) => {
|
|
6824
|
-
|
|
7359
|
+
const pretest = pretests[i];
|
|
7360
|
+
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
7361
|
+
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
7362
|
+
const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
|
|
7363
|
+
const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
|
|
7364
|
+
const routeMiss = pretest?.token === void 0 ? "" : `
|
|
7365
|
+
if(${decision}===0){
|
|
7366
|
+
ctx._fc=false
|
|
7367
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
7368
|
+
prev=${i + 1}`}
|
|
7369
|
+
{const at=_pfTokEnd
|
|
7370
|
+
if(at>best){best=at;acc=undefined}
|
|
7371
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.token.expected},acc)}
|
|
7372
|
+
}`;
|
|
7373
|
+
const sequenceMiss = pretest?.sequence === void 0 ? "" : `
|
|
7374
|
+
else if((bits&${1 << i})!==0&&${decision}<0){
|
|
7375
|
+
ctx._fc=false
|
|
7376
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
7377
|
+
prev=${i + 1}`}
|
|
7378
|
+
{const at=_pfSeqEnd
|
|
7379
|
+
if(at>best){best=at;acc=undefined}
|
|
7380
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("")}${pretest.sequence.expected.at(-1)},acc)}
|
|
7381
|
+
}`;
|
|
7382
|
+
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
7383
|
+
`}if((bits&${1 << i})!==0${condition}){
|
|
6825
7384
|
ctx._fc=false
|
|
6826
7385
|
{const v=${arm}(input,pos,ctx)
|
|
6827
7386
|
if(v!==FAIL)return v}
|
|
6828
|
-
if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
6829
|
-
prev=${i + 1}
|
|
7387
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${i},prev,acc)
|
|
7388
|
+
prev=${i + 1}`}
|
|
6830
7389
|
{const at=ctx._fe??pos
|
|
6831
7390
|
if(at>best){best=at;acc=undefined}
|
|
6832
|
-
if(at===best)acc=_accSet(ctx._fx,acc)}
|
|
6833
|
-
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
6834
|
-
${
|
|
6835
|
-
}`;
|
|
7391
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(ctx._fx,acc)}
|
|
7392
|
+
if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0,undefined);acc=_accSet(ctx._fx,acc)}` : ""}if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
7393
|
+
${rollbackFor(i)}
|
|
7394
|
+
}${routeMiss}${sequenceMiss}`;
|
|
6836
7395
|
}).join("\n") : "";
|
|
6837
|
-
const generalArms = arms.map((arm, i) =>
|
|
7396
|
+
const generalArms = arms.map((arm, i) => {
|
|
7397
|
+
const pretest = pretests[i];
|
|
7398
|
+
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
7399
|
+
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
7400
|
+
const sequenceCondition = pretest?.sequence === void 0 ? "" : `&&(${decision}=${pretest.sequence.name}(input,pos))>=0`;
|
|
7401
|
+
const condition = pretest?.token !== void 0 ? `&&(${decision}=${pretest.token.name}(input,pos))>0` : scalarCondition || sequenceCondition;
|
|
7402
|
+
const miss = pretest?.sequence !== void 0 ? `else if(${decision}<0){
|
|
7403
|
+
ctx._fc=false
|
|
7404
|
+
const at=_pfSeqEnd
|
|
7405
|
+
if(at>best){best=at;acc=undefined}
|
|
7406
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.sequence.expected.map((value, at) => `${decision}===${~at}?${value}:`).join("")}${pretest.sequence.expected.at(-1)},acc)
|
|
7407
|
+
}${startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)`}` : pretest?.token === void 0 ? startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)` : `else if(${decision}===0){
|
|
7408
|
+
ctx._fc=false
|
|
7409
|
+
const at=_pfTokEnd
|
|
7410
|
+
if(at>best){best=at;acc=undefined}
|
|
7411
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(${pretest.token.expected},acc)
|
|
7412
|
+
}${startFailureExact ? "" : `else if(best===pos)acc=_accSet(${expected[i]},acc)`}`;
|
|
7413
|
+
return `${decision === "" ? "" : `let ${decision}=${pretest?.sequence === void 0 ? -1 : 0}
|
|
7414
|
+
`}if((${gateRefs[i]}===null||classHas(${gateRefs[i]},c))${condition}){
|
|
6838
7415
|
ctx._fc=false
|
|
6839
7416
|
{const v=${arm}(input,pos,ctx)
|
|
6840
7417
|
if(v!==FAIL)return v}
|
|
6841
7418
|
{const at=ctx._fe??pos
|
|
6842
7419
|
if(at>best){best=at;acc=undefined}
|
|
6843
|
-
if(at===best)acc=_accSet(ctx._fx,acc)}
|
|
6844
|
-
if(ctx._fc===true){if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
6845
|
-
${
|
|
6846
|
-
}
|
|
7420
|
+
if(at===best${startFailureExact ? "&&at>pos" : ""})acc=_accSet(ctx._fx,acc)}
|
|
7421
|
+
if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0,undefined);acc=_accSet(ctx._fx,acc)}` : ""}if(acc!==undefined)ctx._fx=acc;return FAIL}
|
|
7422
|
+
${rollbackFor(i)}
|
|
7423
|
+
}${miss}`;
|
|
7424
|
+
}).join("\n");
|
|
6847
7425
|
return `${head}
|
|
6848
7426
|
const c=lead(input,pos)
|
|
6849
|
-
${emitMark(p, L.buf, sinks)}
|
|
7427
|
+
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
6850
7428
|
let acc
|
|
6851
7429
|
let best=pos
|
|
6852
7430
|
${maskable ? `if(c<128){
|
|
6853
7431
|
const bits=${maskName}[c<0?128:c]
|
|
6854
|
-
|
|
7432
|
+
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
7433
|
+
${startFailureExact ? "" : "let prev=0"}
|
|
6855
7434
|
${maskArms}
|
|
6856
|
-
if(best===pos)acc=${catchName}(${n},prev,acc)
|
|
6857
|
-
ctx._fe=pos;ctx._fx
|
|
7435
|
+
${startFailureExact ? "" : `if(best===pos)acc=${catchName}(${n},prev,acc)`}
|
|
7436
|
+
ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
|
|
6858
7437
|
return FAIL
|
|
6859
7438
|
}
|
|
6860
7439
|
` : ""}
|
|
6861
7440
|
${generalArms}
|
|
6862
|
-
ctx._fe=pos;ctx._fx
|
|
7441
|
+
ctx._fe=pos;ctx._fx=${startFailureExact ? `best===pos?${choiceFx}:acc??${choiceFx}` : `acc??${choiceFx}`}
|
|
6863
7442
|
return FAIL
|
|
6864
7443
|
}`;
|
|
6865
7444
|
}
|
|
@@ -6878,30 +7457,8 @@ return FAIL
|
|
|
6878
7457
|
for (let i = 0; i < n; i++) arms.push(link(code[armBase + i]));
|
|
6879
7458
|
const bk = hoist("bk", `DSP[${di}].byKey`);
|
|
6880
7459
|
const dx = hoist("dx", `DSP[${di}].expected`);
|
|
6881
|
-
const claims = (m) => {
|
|
6882
|
-
switch (m[0]) {
|
|
6883
|
-
case 0:
|
|
6884
|
-
return `key.startsWith(${q(m[1])})`;
|
|
6885
|
-
case 1:
|
|
6886
|
-
return `key.endsWith(${q(m[1])})`;
|
|
6887
|
-
case 3:
|
|
6888
|
-
return `asciiFoldKey(key).startsWith(${q(m[1])})`;
|
|
6889
|
-
case 4:
|
|
6890
|
-
return `asciiFoldKey(key).endsWith(${q(m[1])})`;
|
|
6891
|
-
default: {
|
|
6892
|
-
if (!m[2].includes("g") && !m[2].includes("y")) {
|
|
6893
|
-
try {
|
|
6894
|
-
new RegExp(m[1], m[2]);
|
|
6895
|
-
return `${hoist("dm", `new RegExp(${q(m[1])},${q(m[2])})`)}.test(key)`;
|
|
6896
|
-
} catch {
|
|
6897
|
-
}
|
|
6898
|
-
}
|
|
6899
|
-
return `new RegExp(${q(m[1])},${q(m[2])}).test(key)`;
|
|
6900
|
-
}
|
|
6901
|
-
}
|
|
6902
|
-
};
|
|
6903
7460
|
const chain = spec.match.length === 0 ? "" : `if(arm===undefined){
|
|
6904
|
-
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${
|
|
7461
|
+
${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${dispatchClaim(m)})arm=${m[3]}`).join("\n")}
|
|
6905
7462
|
}
|
|
6906
7463
|
`;
|
|
6907
7464
|
const fold = spec.byFold.size > 0 ? `if(arm===undefined)arm=${hoist("bf", `DSP[${di}].byFold`)}.get(asciiFoldKey(key))
|
|
@@ -6909,33 +7466,43 @@ ${spec.match.map((m, i) => `${i === 0 ? "" : "else "}if(${claims(m)})arm=${m[3]}
|
|
|
6909
7466
|
const m1 = tmp();
|
|
6910
7467
|
const m2 = tmp();
|
|
6911
7468
|
const routedCall = (target) => `{const savedRouted=ctx._routed
|
|
6912
|
-
${emitRollback(m1, L.buf, sinks)}
|
|
6913
|
-
${emitMark(m2, L.buf, sinks, false)}
|
|
7469
|
+
${emitRollback(m1, L.buf, L.raw, sinks)}
|
|
7470
|
+
${emitMark(m2, L.buf, L.raw, sinks, false)}
|
|
6914
7471
|
ctx._routed={value:key,span:{start:pos,end:selEnd}}
|
|
6915
7472
|
try{v=${target}(input,pos,ctx)}finally{ctx._routed=savedRouted}
|
|
6916
7473
|
break}`;
|
|
6917
7474
|
const plainCall = (target) => `v=${target}(input,selEnd,ctx);break`;
|
|
6918
7475
|
const armCases = arms.map((target, i) => `case ${i}:${spec.routed[i] === 1 ? routedCall(target) : plainCall(target)}`).join("\n");
|
|
6919
7476
|
const fallbackCase = other === void 0 ? "" : `default:${otherRouted ? routedCall(other) : plainCall(other)}`;
|
|
7477
|
+
const armSelection = tokenChoiceDispatches.has(ip) ? `const tp=_pfTokDispatch===${ip}&&_pfTokInput===input&&_pfTokPos===pos
|
|
7478
|
+
let arm
|
|
7479
|
+
if(tp){
|
|
7480
|
+
arm=_pfTokArm
|
|
7481
|
+
_pfTokDispatch=-1
|
|
7482
|
+
_pfTokInput=undefined
|
|
7483
|
+
if(arm===${n})arm=undefined
|
|
7484
|
+
}else{
|
|
7485
|
+
arm=${bk}.get(key)
|
|
7486
|
+
${fold}${chain}}` : `let arm=${bk}.get(key)
|
|
7487
|
+
${fold}${chain}`;
|
|
6920
7488
|
return `${head}
|
|
6921
|
-
${emitMark(m1, L.buf, sinks)}
|
|
7489
|
+
${emitMark(m1, L.buf, L.raw, sinks)}
|
|
6922
7490
|
const sv=${selector}(input,pos,ctx)
|
|
6923
7491
|
if(sv===FAIL)return FAIL
|
|
6924
7492
|
const selEnd=EC.e
|
|
6925
7493
|
const key=sv
|
|
6926
|
-
|
|
6927
|
-
${fold}${chain}
|
|
7494
|
+
${armSelection}
|
|
6928
7495
|
if(arm===undefined){
|
|
6929
7496
|
${other === void 0 ? `ctx._fe=selEnd;ctx._fx=${dx};return FAIL` : ""}
|
|
6930
7497
|
}
|
|
6931
|
-
${emitMark(m2, L.buf, sinks)}
|
|
7498
|
+
${emitMark(m2, L.buf, L.raw, sinks)}
|
|
6932
7499
|
let v
|
|
6933
7500
|
switch(arm){
|
|
6934
7501
|
${armCases}
|
|
6935
7502
|
${fallbackCase}
|
|
6936
7503
|
}
|
|
6937
7504
|
if(v===FAIL){
|
|
6938
|
-
${emitRollback(m2, L.buf, sinks)}
|
|
7505
|
+
${emitRollback(m2, L.buf, L.raw, sinks)}
|
|
6939
7506
|
ctx._fc=true
|
|
6940
7507
|
return FAIL
|
|
6941
7508
|
}
|
|
@@ -6971,23 +7538,25 @@ return [key,v]
|
|
|
6971
7538
|
const skip = skipFor(L);
|
|
6972
7539
|
const knownTrivia = L.tri === TRI_NONE ? false : L.tri !== TRI_UNKNOWN ? true : void 0;
|
|
6973
7540
|
const hasTrivia = knownTrivia === void 0 ? "hasTrivia" : String(knownTrivia);
|
|
6974
|
-
const pfd = sinks.fd ? `${p}fd` : "
|
|
7541
|
+
const pfd = sinks.fd ? `${p}fd` : "undefined";
|
|
6975
7542
|
const per = sinks.er ? `${p}er` : "undefined";
|
|
6976
|
-
const
|
|
7543
|
+
const rbHelper = L.raw === RAW_OMIT ? "_rbNoRawBuf" : "_rbBuf";
|
|
7544
|
+
const rb = L.buf && L.raw !== 0 ? `${rbHelper}(ctx,${p}raw,${p}tl,${p}lv,${p}lg,${p}rt)${sinks.fd ? `
|
|
6977
7545
|
if(ctx._fields!==undefined&&ctx._fields.length!==${p}fd)ctx._fields.length=${p}fd` : ""}${sinks.er ? `
|
|
6978
|
-
if(ctx._errors!==undefined&&ctx._errors.length!==${p}er)ctx._errors.length=${p}er` : ""}` : `if(needMark)rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)`;
|
|
7546
|
+
if(ctx._errors!==undefined&&ctx._errors.length!==${p}er)ctx._errors.length=${p}er` : ""}` : L.buf ? `rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)` : `if(needMark)rollbackTriviaAt(ctx,${p}raw,${p}tl,${p}lv,${pfd},${per},${p}lg,${p}rt)`;
|
|
6979
7547
|
const markSinks = `${sinks.fd ? `
|
|
6980
7548
|
${p}fd=ctx._fields!==undefined?ctx._fields.length:0` : ""}${sinks.er ? `
|
|
6981
7549
|
${p}er=ctx._errors!==undefined?ctx._errors.length:0` : ""}`;
|
|
7550
|
+
const markRaw = L.raw === RAW_OMIT ? `${p}raw=b.rawLen` : L.raw === RAW_CAPTURE ? `const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0` : `const r=b.raw;${p}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)`;
|
|
6982
7551
|
const markBody = L.buf ? `const b=ctx._cstBuf
|
|
6983
|
-
|
|
7552
|
+
${markRaw}
|
|
6984
7553
|
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
6985
7554
|
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
6986
7555
|
${p}lg=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
6987
7556
|
${p}rt=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0${markSinks}` : `if(needMark){
|
|
6988
7557
|
const b=ctx._cstBuf
|
|
6989
7558
|
if(b!==undefined){
|
|
6990
|
-
const r=b.raw;${p}raw=r!==undefined?r.length:b.rawSingle!==undefined?1:0
|
|
7559
|
+
const r=b.raw;${p}raw=b.noRaw===true?b.rawLen:(r!==undefined?r.length:b.rawSingle!==undefined?1:0)
|
|
6991
7560
|
const h=b.ch;${p}lv=h!==undefined?h.length:b.single!==undefined?1:0
|
|
6992
7561
|
const l=b.tl;${p}tl=l!==undefined?l.length:0
|
|
6993
7562
|
}else{
|
|
@@ -7094,7 +7663,7 @@ const leaf={_tag:'leaf',value,span:{start:pos,end}}
|
|
|
7094
7663
|
const kids=[leaf],rawKids=[leaf],span={start:pos,end}
|
|
7095
7664
|
EC.e=end
|
|
7096
7665
|
const nd=${build2}(kids,undefined,span,rawKids,EMPTY_TL,undefined)
|
|
7097
|
-
${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
7666
|
+
${L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : staticBuild ? "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,ctx._cstBuf!==undefined&&ctx._cstBuf.noRaw===true?undefined:ctx._cstBuf!==undefined||ctx._cstRawChildren!==undefined?rawEntry(nd,input,pos,end):undefined)" : "if(ctx._cstBuf!==undefined||ctx._cstChildren!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
7098
7667
|
EC.e=end
|
|
7099
7668
|
return nd
|
|
7100
7669
|
}`;
|
|
@@ -7116,7 +7685,22 @@ return nd
|
|
|
7116
7685
|
if (!hostCst && !tracked && build !== void 0 && proj < 0 && (flags === 2 || flags === 18 || flags === 34)) {
|
|
7117
7686
|
const fields = flags === 18;
|
|
7118
7687
|
const collapseChildren = flags === 34;
|
|
7119
|
-
const publish = `if(sBuf!==undefined){
|
|
7688
|
+
const publish = L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? `if(sBuf!==undefined){
|
|
7689
|
+
if(sBuf.rawOnly!==true){
|
|
7690
|
+
if(sBuf.ch!==undefined)sBuf.ch.push(nd)
|
|
7691
|
+
else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
|
|
7692
|
+
else sBuf.single=nd
|
|
7693
|
+
}
|
|
7694
|
+
const rawNd=rawEntry(nd,input,pos,end)
|
|
7695
|
+
if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
|
|
7696
|
+
else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
|
|
7697
|
+
else sBuf.rawSingle=rawNd
|
|
7698
|
+
}else if(sCh!==undefined){
|
|
7699
|
+
sCh.push(nd)
|
|
7700
|
+
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
7701
|
+
}` : `if(sBuf!==undefined){
|
|
7702
|
+
if(sBuf.noRaw===true)_pushNodeNoRawBuf(ctx,nd)
|
|
7703
|
+
else{
|
|
7120
7704
|
if(sBuf.rawOnly!==true){
|
|
7121
7705
|
if(sBuf.ch!==undefined)sBuf.ch.push(nd)
|
|
7122
7706
|
else if(sBuf.single!==undefined){sBuf.ch=[sBuf.single,nd];sBuf.single=undefined}
|
|
@@ -7126,6 +7710,7 @@ const rawNd=rawEntry(nd,input,pos,end)
|
|
|
7126
7710
|
if(sBuf.raw!==undefined)sBuf.raw.push(rawNd)
|
|
7127
7711
|
else if(sBuf.rawSingle!==undefined){sBuf.raw=[sBuf.rawSingle,rawNd];sBuf.rawSingle=undefined}
|
|
7128
7712
|
else sBuf.rawSingle=rawNd
|
|
7713
|
+
}
|
|
7129
7714
|
}else if(sCh!==undefined){
|
|
7130
7715
|
sCh.push(nd)
|
|
7131
7716
|
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
@@ -7164,6 +7749,7 @@ return nd
|
|
|
7164
7749
|
const wantFields = hasFields || hostCst;
|
|
7165
7750
|
const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
|
|
7166
7751
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
7752
|
+
const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
|
|
7167
7753
|
const ty = q(type);
|
|
7168
7754
|
const stArg = readsState ? "st" : "(ctx.state!==undefined?Object.assign({},ctx.state):undefined)";
|
|
7169
7755
|
const hostCall = `_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,${stArg},${tags})`;
|
|
@@ -7177,7 +7763,12 @@ return nd
|
|
|
7177
7763
|
value = `nd=_pfHost!==undefined?_pfHost(${ty},hostKids,fieldMap,span,rawKids,tlog,st,${tags}):{_tag:'node',type:${ty},span,state:st??null,children:kids}`;
|
|
7178
7764
|
}
|
|
7179
7765
|
const collapsible = keepChildren && (hostCst || build === void 0 && proj < 0);
|
|
7180
|
-
const openCapture =
|
|
7766
|
+
const openCapture = omitsRaw ? `const buf={noRaw:true,rawLen:0}
|
|
7767
|
+
ctx._cstBuf=buf
|
|
7768
|
+
ctx._cstChildren=undefined
|
|
7769
|
+
ctx._cstLeaves=undefined
|
|
7770
|
+
ctx._cstRawChildren=undefined
|
|
7771
|
+
ctx._cstTriviaLog=undefined` : keepChildren ? `const buf={}
|
|
7181
7772
|
ctx._cstBuf=buf
|
|
7182
7773
|
ctx._cstChildren=undefined
|
|
7183
7774
|
ctx._cstLeaves=undefined
|
|
@@ -7188,7 +7779,10 @@ ctx._cstChildren=undefined
|
|
|
7188
7779
|
ctx._cstLeaves=undefined
|
|
7189
7780
|
ctx._cstRawChildren=undefined
|
|
7190
7781
|
ctx._cstTriviaLog=undefined`;
|
|
7191
|
-
const finishCapture =
|
|
7782
|
+
const finishCapture = omitsRaw ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
|
|
7783
|
+
const hostKids=kids
|
|
7784
|
+
const rawKids=EMPTY_CH
|
|
7785
|
+
const tlog=buf.tl??EMPTY_TLOG` : keepChildren ? `const kids=buf.ch??(buf.single!==undefined?[buf.single]:EMPTY_CH)
|
|
7192
7786
|
const hostKids=kids
|
|
7193
7787
|
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
7194
7788
|
const tlog=buf.tl??EMPTY_TLOG` : `const kids=EMPTY_CH
|
|
@@ -7222,7 +7816,7 @@ const st=${readsState ? "(ctx.state!==undefined?Object.assign({},ctx.state):unde
|
|
|
7222
7816
|
let nd
|
|
7223
7817
|
${unwrap ? "if(kids.length===1)nd=unwrapChild(kids[0])\nelse " : ""}${collapse ? "if(kids.length===1)nd=kids[0]\nelse " : ""}${collapsible ? `if(_pfHost!==undefined&&_pfHost._parsemanCstCollapse!==undefined&&kids.length===1&&rawKids.length===1&&_pfHost._parsemanCstCollapse(${ty},kids[0],kids,rawKids))nd=kids[0]
|
|
7224
7818
|
else ` : ""}{${value}}
|
|
7225
|
-
${L.buf ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
7819
|
+
${L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? "pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))" : staticBuild ? "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,sBuf!==undefined?(sBuf.noRaw===true?undefined:rawEntry(nd,input,pos,end)):sRaw!==undefined?rawEntry(nd,input,pos,end):undefined)" : "if(sBuf!==undefined||sCh!==undefined)pushCstChild(ctx,nd,rawEntry(nd,input,pos,end))"}
|
|
7226
7820
|
EC.e=end
|
|
7227
7821
|
return nd
|
|
7228
7822
|
}`;
|
|
@@ -7240,7 +7834,7 @@ return nd
|
|
|
7240
7834
|
}
|
|
7241
7835
|
const extra = [];
|
|
7242
7836
|
for (const ip of extraIps) extra.push(`${ip}:${link(ip)}`);
|
|
7243
|
-
const source = `${RUNTIME_PRELUDE}
|
|
7837
|
+
const source = `${RUNTIME_PRELUDE}${needsNoRawPrelude ? NO_RAW_RUNTIME_PRELUDE : ""}
|
|
7244
7838
|
${prelude.join("\n")}
|
|
7245
7839
|
${skipDefs.join("\n")}
|
|
7246
7840
|
${choiceDefs.join("\n")}
|
|
@@ -7255,7 +7849,13 @@ _pfHost=host
|
|
|
7255
7849
|
function _finish(){
|
|
7256
7850
|
if(_pfDepth<=0)throw new Error('parseman emitted table assembly frame underflow')
|
|
7257
7851
|
_pfDepth--
|
|
7258
|
-
if(_pfDepth===0)
|
|
7852
|
+
if(_pfDepth===0){
|
|
7853
|
+
_pfTokInput=undefined
|
|
7854
|
+
_pfTokBody=-1
|
|
7855
|
+
_pfTokValue=undefined
|
|
7856
|
+
_pfTokDispatch=-1
|
|
7857
|
+
return
|
|
7858
|
+
}
|
|
7259
7859
|
const prior=_pfFrames.pop()
|
|
7260
7860
|
_pfScan=prior[0]
|
|
7261
7861
|
_pfHost=prior[1]
|
|
@@ -7503,6 +8103,17 @@ function assemble(t, prog, cfg) {
|
|
|
7503
8103
|
}
|
|
7504
8104
|
return recognize;
|
|
7505
8105
|
}
|
|
8106
|
+
const labelExtraIps = [];
|
|
8107
|
+
for (const s of prog.scans ?? []) {
|
|
8108
|
+
for (const r of s.skip) labelExtraIps.push(r[0]);
|
|
8109
|
+
if (s.sentinel !== void 0) labelExtraIps.push(s.sentinel[0]);
|
|
8110
|
+
}
|
|
8111
|
+
for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
|
|
8112
|
+
const closureLabels = computeSiteLabels(
|
|
8113
|
+
code,
|
|
8114
|
+
[...Object.values(prog.rules), ...labelExtraIps],
|
|
8115
|
+
hostCst
|
|
8116
|
+
);
|
|
7506
8117
|
let SCAN = null;
|
|
7507
8118
|
const memo = /* @__PURE__ */ new Map();
|
|
7508
8119
|
const reached = /* @__PURE__ */ new Set();
|
|
@@ -7748,7 +8359,7 @@ function assemble(t, prog, cfg) {
|
|
|
7748
8359
|
const b = ctx._cstBuf;
|
|
7749
8360
|
if (b !== void 0) {
|
|
7750
8361
|
const raw = b.raw;
|
|
7751
|
-
MRAW = raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
|
|
8362
|
+
MRAW = b.noRaw === true ? b.rawLen ?? 0 : raw !== void 0 ? raw.length : b.rawSingle !== void 0 ? 1 : 0;
|
|
7752
8363
|
const ch2 = b.ch;
|
|
7753
8364
|
MLV = ch2 !== void 0 ? ch2.length : b.single !== void 0 ? 1 : 0;
|
|
7754
8365
|
const tl = b.tl;
|
|
@@ -7832,6 +8443,31 @@ function assemble(t, prog, cfg) {
|
|
|
7832
8443
|
if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
7833
8444
|
return cur;
|
|
7834
8445
|
}
|
|
8446
|
+
function nextTermBuffered(child, input, cur, ctx) {
|
|
8447
|
+
if (ctx.trivia === void 0) {
|
|
8448
|
+
const v2 = child(input, cur, ctx);
|
|
8449
|
+
if (v2 === FAIL) return -1;
|
|
8450
|
+
TERMV = v2;
|
|
8451
|
+
return EC.e;
|
|
8452
|
+
}
|
|
8453
|
+
const before = ctx._cstBuf;
|
|
8454
|
+
const beforeTl = before.tl;
|
|
8455
|
+
const mTl = beforeTl === void 0 ? 0 : beforeTl.length;
|
|
8456
|
+
const mLog = ctx._triviaLog?.length ?? 0;
|
|
8457
|
+
const mRoot = ctx._rootTriviaLog?.length ?? 0;
|
|
8458
|
+
const scanEnd = skipTrivia(input, cur, ctx);
|
|
8459
|
+
const scanned = ctx._cstBuf;
|
|
8460
|
+
const scannedTl = scanned.tl;
|
|
8461
|
+
const scanTl = scannedTl === void 0 ? 0 : scannedTl.length;
|
|
8462
|
+
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
8463
|
+
const scanRoot = ctx._rootTriviaLog?.length ?? 0;
|
|
8464
|
+
const v = child(input, scanEnd, ctx);
|
|
8465
|
+
if (v === FAIL) return -1;
|
|
8466
|
+
TERMV = v;
|
|
8467
|
+
if (EC.e > scanEnd) return EC.e;
|
|
8468
|
+
rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot);
|
|
8469
|
+
return cur;
|
|
8470
|
+
}
|
|
7835
8471
|
function committed3(c) {
|
|
7836
8472
|
return c._fc === true;
|
|
7837
8473
|
}
|
|
@@ -8102,7 +8738,8 @@ function assemble(t, prog, cfg) {
|
|
|
8102
8738
|
target = p;
|
|
8103
8739
|
} };
|
|
8104
8740
|
inFlight.set(ip, holder);
|
|
8105
|
-
const
|
|
8741
|
+
const op = code[ip];
|
|
8742
|
+
const piece = (op === OP_SCOPE_PLAIN || op === OP_SCOPE && code[ip + 3] === 0) && code[ip + 1] >= 0 && closureLabels.at(ip).tri === code[ip + 1] ? link(code[ip + 2]) : lower(ip);
|
|
8106
8743
|
inFlight.delete(ip);
|
|
8107
8744
|
holder.set(piece);
|
|
8108
8745
|
memo.set(ip, piece);
|
|
@@ -8845,6 +9482,7 @@ function assemble(t, prog, cfg) {
|
|
|
8845
9482
|
const reducer = fused ? code[ip + 1] : -1;
|
|
8846
9483
|
const projection = reducer < 0 ? ~reducer : -1;
|
|
8847
9484
|
const fn = fused && projection < 0 ? fns[reducer] : void 0;
|
|
9485
|
+
const step = closureLabels.at(ip).buf ? nextTermBuffered : nextTerm;
|
|
8848
9486
|
const runnerBlock = (count, r0, r1, r2, r3, next) => {
|
|
8849
9487
|
if (count === 1) return (input, cur, ctx, values, inherited) => {
|
|
8850
9488
|
cur = r0(input, cur, ctx, inherited);
|
|
@@ -8899,7 +9537,7 @@ function assemble(t, prog, cfg) {
|
|
|
8899
9537
|
const kid = link(kidIp);
|
|
8900
9538
|
return (input, cur, ctx, inherited) => {
|
|
8901
9539
|
ctx._sync = sync ?? inherited;
|
|
8902
|
-
return
|
|
9540
|
+
return step(kid, input, cur, ctx);
|
|
8903
9541
|
};
|
|
8904
9542
|
}
|
|
8905
9543
|
const negated = code[kidIp + 1] === 1;
|
|
@@ -8984,7 +9622,7 @@ function assemble(t, prog, cfg) {
|
|
|
8984
9622
|
const kidIp = code[base + i];
|
|
8985
9623
|
if (code[kidIp] !== OP_ADJ) {
|
|
8986
9624
|
const kid = link(kidIp);
|
|
8987
|
-
return (input, cur, ctx) =>
|
|
9625
|
+
return (input, cur, ctx) => step(kid, input, cur, ctx);
|
|
8988
9626
|
}
|
|
8989
9627
|
const negated = code[kidIp + 1] === 1;
|
|
8990
9628
|
const ki = code[kidIp + 2];
|
|
@@ -9073,7 +9711,7 @@ function assemble(t, prog, cfg) {
|
|
|
9073
9711
|
return (input, pos, ctx) => {
|
|
9074
9712
|
const v0 = k0(input, pos, ctx);
|
|
9075
9713
|
if (v0 === FAIL) return FAIL;
|
|
9076
|
-
const cur =
|
|
9714
|
+
const cur = step(k1, input, EC.e, ctx);
|
|
9077
9715
|
if (cur < 0) return FAIL;
|
|
9078
9716
|
EC.e = cur;
|
|
9079
9717
|
return projection === 0 ? v0 : projection === 1 ? TERMV : fn([v0, TERMV], { start: pos, end: cur });
|
|
@@ -9083,7 +9721,7 @@ function assemble(t, prog, cfg) {
|
|
|
9083
9721
|
return (input, pos, ctx) => {
|
|
9084
9722
|
const v0 = k0(input, pos, ctx);
|
|
9085
9723
|
if (v0 === FAIL) return FAIL;
|
|
9086
|
-
const cur =
|
|
9724
|
+
const cur = step(k1, input, EC.e, ctx);
|
|
9087
9725
|
if (cur < 0) return FAIL;
|
|
9088
9726
|
EC.e = cur;
|
|
9089
9727
|
return [v0, TERMV];
|
|
@@ -9092,7 +9730,7 @@ function assemble(t, prog, cfg) {
|
|
|
9092
9730
|
return (input, pos, ctx) => {
|
|
9093
9731
|
const v0 = k0(input, pos, ctx);
|
|
9094
9732
|
if (v0 === FAIL) return FAIL;
|
|
9095
|
-
const cur =
|
|
9733
|
+
const cur = step(k1, input, EC.e, ctx);
|
|
9096
9734
|
if (cur < 0) return FAIL;
|
|
9097
9735
|
EC.e = cur;
|
|
9098
9736
|
return void 0;
|
|
@@ -9104,10 +9742,10 @@ function assemble(t, prog, cfg) {
|
|
|
9104
9742
|
return (input, pos, ctx) => {
|
|
9105
9743
|
const v0 = k0(input, pos, ctx);
|
|
9106
9744
|
if (v0 === FAIL) return FAIL;
|
|
9107
|
-
let cur =
|
|
9745
|
+
let cur = step(k1, input, EC.e, ctx);
|
|
9108
9746
|
if (cur < 0) return FAIL;
|
|
9109
9747
|
const v1 = TERMV;
|
|
9110
|
-
cur =
|
|
9748
|
+
cur = step(k2, input, cur, ctx);
|
|
9111
9749
|
if (cur < 0) return FAIL;
|
|
9112
9750
|
EC.e = cur;
|
|
9113
9751
|
return projection === 0 ? v0 : projection === 1 ? v1 : projection === 2 ? TERMV : fn([v0, v1, TERMV], { start: pos, end: cur });
|
|
@@ -9117,10 +9755,10 @@ function assemble(t, prog, cfg) {
|
|
|
9117
9755
|
return (input, pos, ctx) => {
|
|
9118
9756
|
const v0 = k0(input, pos, ctx);
|
|
9119
9757
|
if (v0 === FAIL) return FAIL;
|
|
9120
|
-
let cur =
|
|
9758
|
+
let cur = step(k1, input, EC.e, ctx);
|
|
9121
9759
|
if (cur < 0) return FAIL;
|
|
9122
9760
|
const v1 = TERMV;
|
|
9123
|
-
cur =
|
|
9761
|
+
cur = step(k2, input, cur, ctx);
|
|
9124
9762
|
if (cur < 0) return FAIL;
|
|
9125
9763
|
EC.e = cur;
|
|
9126
9764
|
return [v0, v1, TERMV];
|
|
@@ -9129,9 +9767,9 @@ function assemble(t, prog, cfg) {
|
|
|
9129
9767
|
return (input, pos, ctx) => {
|
|
9130
9768
|
const v0 = k0(input, pos, ctx);
|
|
9131
9769
|
if (v0 === FAIL) return FAIL;
|
|
9132
|
-
let cur =
|
|
9770
|
+
let cur = step(k1, input, EC.e, ctx);
|
|
9133
9771
|
if (cur < 0) return FAIL;
|
|
9134
|
-
cur =
|
|
9772
|
+
cur = step(k2, input, cur, ctx);
|
|
9135
9773
|
if (cur < 0) return FAIL;
|
|
9136
9774
|
EC.e = cur;
|
|
9137
9775
|
return void 0;
|
|
@@ -9139,43 +9777,43 @@ function assemble(t, prog, cfg) {
|
|
|
9139
9777
|
}
|
|
9140
9778
|
const block = (count, k0, k1, k2, k3, next) => {
|
|
9141
9779
|
if (count === 1) return (input, cur, ctx, values) => {
|
|
9142
|
-
cur =
|
|
9780
|
+
cur = step(k0, input, cur, ctx);
|
|
9143
9781
|
if (cur < 0) return -1;
|
|
9144
9782
|
if (values !== void 0) values.push(TERMV);
|
|
9145
9783
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
9146
9784
|
};
|
|
9147
9785
|
if (count === 2) return (input, cur, ctx, values) => {
|
|
9148
|
-
cur =
|
|
9786
|
+
cur = step(k0, input, cur, ctx);
|
|
9149
9787
|
if (cur < 0) return -1;
|
|
9150
9788
|
if (values !== void 0) values.push(TERMV);
|
|
9151
|
-
cur =
|
|
9789
|
+
cur = step(k1, input, cur, ctx);
|
|
9152
9790
|
if (cur < 0) return -1;
|
|
9153
9791
|
if (values !== void 0) values.push(TERMV);
|
|
9154
9792
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
9155
9793
|
};
|
|
9156
9794
|
if (count === 3) return (input, cur, ctx, values) => {
|
|
9157
|
-
cur =
|
|
9795
|
+
cur = step(k0, input, cur, ctx);
|
|
9158
9796
|
if (cur < 0) return -1;
|
|
9159
9797
|
if (values !== void 0) values.push(TERMV);
|
|
9160
|
-
cur =
|
|
9798
|
+
cur = step(k1, input, cur, ctx);
|
|
9161
9799
|
if (cur < 0) return -1;
|
|
9162
9800
|
if (values !== void 0) values.push(TERMV);
|
|
9163
|
-
cur =
|
|
9801
|
+
cur = step(k2, input, cur, ctx);
|
|
9164
9802
|
if (cur < 0) return -1;
|
|
9165
9803
|
if (values !== void 0) values.push(TERMV);
|
|
9166
9804
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
9167
9805
|
};
|
|
9168
9806
|
return (input, cur, ctx, values) => {
|
|
9169
|
-
cur =
|
|
9807
|
+
cur = step(k0, input, cur, ctx);
|
|
9170
9808
|
if (cur < 0) return -1;
|
|
9171
9809
|
if (values !== void 0) values.push(TERMV);
|
|
9172
|
-
cur =
|
|
9810
|
+
cur = step(k1, input, cur, ctx);
|
|
9173
9811
|
if (cur < 0) return -1;
|
|
9174
9812
|
if (values !== void 0) values.push(TERMV);
|
|
9175
|
-
cur =
|
|
9813
|
+
cur = step(k2, input, cur, ctx);
|
|
9176
9814
|
if (cur < 0) return -1;
|
|
9177
9815
|
if (values !== void 0) values.push(TERMV);
|
|
9178
|
-
cur =
|
|
9816
|
+
cur = step(k3, input, cur, ctx);
|
|
9179
9817
|
if (cur < 0) return -1;
|
|
9180
9818
|
if (values !== void 0) values.push(TERMV);
|
|
9181
9819
|
return next === void 0 ? cur : next(input, cur, ctx, values);
|
|
@@ -9346,6 +9984,13 @@ function assemble(t, prog, cfg) {
|
|
|
9346
9984
|
if (n === 2 || n === 3) {
|
|
9347
9985
|
const a0 = link(code[base]), a1 = link(code[base + 1]);
|
|
9348
9986
|
const a2 = n === 3 ? link(code[base + 2]) : void 0;
|
|
9987
|
+
const predecide = !hostCst && !REC && !cfg.probe && !cfg.coverage && !cfg.trackLines;
|
|
9988
|
+
const p0ip = predecide ? leadingScalarTerminal(code, code[base], 2, true, true) : -1;
|
|
9989
|
+
const p1ip = predecide ? leadingScalarTerminal(code, code[base + 1], 2, true, true) : -1;
|
|
9990
|
+
const p2ip = predecide && n === 3 ? leadingScalarTerminal(code, code[base + 2], 2, true, true) : -1;
|
|
9991
|
+
const p0 = p0ip < 0 ? void 0 : scalarFor(p0ip);
|
|
9992
|
+
const p1 = p1ip < 0 ? void 0 : scalarFor(p1ip);
|
|
9993
|
+
const p2 = p2ip < 0 ? void 0 : scalarFor(p2ip);
|
|
9349
9994
|
const e0 = fx[code[base + n]];
|
|
9350
9995
|
const e1 = fx[code[base + n + 1]];
|
|
9351
9996
|
const e2 = n === 3 ? fx[code[base + n + 2]] : void 0;
|
|
@@ -9375,7 +10020,10 @@ function assemble(t, prog, cfg) {
|
|
|
9375
10020
|
let acc;
|
|
9376
10021
|
let best = pos;
|
|
9377
10022
|
if (c < 128) {
|
|
9378
|
-
|
|
10023
|
+
let bits = mask[c < 0 ? 128 : c];
|
|
10024
|
+
if ((bits & 1) !== 0 && p0 !== void 0 && p0(input, pos) < 0) bits &= ~1;
|
|
10025
|
+
if ((bits & 2) !== 0 && p1 !== void 0 && p1(input, pos) < 0) bits &= ~2;
|
|
10026
|
+
if ((bits & 4) !== 0 && p2 !== void 0 && p2(input, pos) < 0) bits &= ~4;
|
|
9379
10027
|
let prev = 0;
|
|
9380
10028
|
if ((bits & 1) !== 0) {
|
|
9381
10029
|
ctx._fc = false;
|
|
@@ -9438,7 +10086,7 @@ function assemble(t, prog, cfg) {
|
|
|
9438
10086
|
ctx._fx = acc ?? choiceFx;
|
|
9439
10087
|
return FAIL;
|
|
9440
10088
|
}
|
|
9441
|
-
if (g0 === null || classHas2(g0, c)) {
|
|
10089
|
+
if ((g0 === null || classHas2(g0, c)) && (p0 === void 0 || p0(input, pos) >= 0)) {
|
|
9442
10090
|
ctx._fc = false;
|
|
9443
10091
|
const v = a0(input, pos, ctx);
|
|
9444
10092
|
if (v !== FAIL) return v;
|
|
@@ -9454,7 +10102,7 @@ function assemble(t, prog, cfg) {
|
|
|
9454
10102
|
}
|
|
9455
10103
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9456
10104
|
} else if (best === pos) acc = accSet(e0, acc);
|
|
9457
|
-
if (g1 === null || classHas2(g1, c)) {
|
|
10105
|
+
if ((g1 === null || classHas2(g1, c)) && (p1 === void 0 || p1(input, pos) >= 0)) {
|
|
9458
10106
|
ctx._fc = false;
|
|
9459
10107
|
const v = a1(input, pos, ctx);
|
|
9460
10108
|
if (v !== FAIL) return v;
|
|
@@ -9471,7 +10119,7 @@ function assemble(t, prog, cfg) {
|
|
|
9471
10119
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
9472
10120
|
} else if (best === pos) acc = accSet(e1, acc);
|
|
9473
10121
|
if (n === 3) {
|
|
9474
|
-
if (g2 === null || classHas2(g2, c)) {
|
|
10122
|
+
if ((g2 === null || classHas2(g2, c)) && (p2 === void 0 || p2(input, pos) >= 0)) {
|
|
9475
10123
|
ctx._fc = false;
|
|
9476
10124
|
const v = a2(input, pos, ctx);
|
|
9477
10125
|
if (v !== FAIL) return v;
|
|
@@ -10044,20 +10692,14 @@ function assemble(t, prog, cfg) {
|
|
|
10044
10692
|
const captureWide = readsTrivia || hostCst ? !structural || grammarCapture || hostCapturesThisType !== false : hostCapturesThisType === true;
|
|
10045
10693
|
const keepChildren = !structural || cfg.hostReadsChildren !== false || collapse || unwrap;
|
|
10046
10694
|
const rawOnly = !keepChildren;
|
|
10695
|
+
const omitsRaw = !hostCst && build !== void 0 && proj < 0 && (flags & 2) !== 0;
|
|
10047
10696
|
return (input, pos, ctx) => {
|
|
10048
10697
|
const host = HOST;
|
|
10049
10698
|
const sCh = ctx._cstChildren;
|
|
10050
|
-
const sLv = ctx._cstLeaves;
|
|
10051
|
-
const sRaw = ctx._cstRawChildren;
|
|
10052
|
-
const sTl = ctx._cstTriviaLog;
|
|
10053
10699
|
const sCap = ctx.captureTrivia;
|
|
10054
10700
|
const sBuf = ctx._cstBuf;
|
|
10055
|
-
const buf = rawOnly ? { rawOnly: true } : {};
|
|
10701
|
+
const buf = rawOnly ? { rawOnly: true } : omitsRaw ? { noRaw: true, rawLen: 0 } : {};
|
|
10056
10702
|
ctx._cstBuf = buf;
|
|
10057
|
-
ctx._cstChildren = void 0;
|
|
10058
|
-
ctx._cstLeaves = void 0;
|
|
10059
|
-
ctx._cstRawChildren = void 0;
|
|
10060
|
-
ctx._cstTriviaLog = void 0;
|
|
10061
10703
|
ctx.captureTrivia = captureWide;
|
|
10062
10704
|
const savedFields = ctx._fields;
|
|
10063
10705
|
ctx._fields = wantFields ? [] : void 0;
|
|
@@ -10072,13 +10714,9 @@ function assemble(t, prog, cfg) {
|
|
|
10072
10714
|
if (structural) ctx._triviaCaptureMask = savedMask;
|
|
10073
10715
|
const kids = rawOnly ? EMPTY_CH : buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
|
|
10074
10716
|
const hostKids = kids;
|
|
10075
|
-
const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
|
|
10717
|
+
const rawKids = omitsRaw ? EMPTY_CH : buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
|
|
10076
10718
|
const tlog = buf.tl ?? EMPTY_TLOG;
|
|
10077
10719
|
ctx._cstBuf = sBuf;
|
|
10078
|
-
ctx._cstChildren = sCh;
|
|
10079
|
-
ctx._cstLeaves = sLv;
|
|
10080
|
-
ctx._cstRawChildren = sRaw;
|
|
10081
|
-
ctx._cstTriviaLog = sTl;
|
|
10082
10720
|
ctx.captureTrivia = sCap;
|
|
10083
10721
|
if (v === FAIL) return FAIL;
|
|
10084
10722
|
const end = EC.e;
|
|
@@ -10169,6 +10807,34 @@ function assemble(t, prog, cfg) {
|
|
|
10169
10807
|
rawScalarSpecs.add(code[child + 1]);
|
|
10170
10808
|
scalarFor(child);
|
|
10171
10809
|
}
|
|
10810
|
+
} else if (code[ip] === OP_CHOICE && !disp[code[ip + 1]].exclusive) {
|
|
10811
|
+
const n = code[ip + 2];
|
|
10812
|
+
for (let i = 0; i < n; i++) {
|
|
10813
|
+
const armIp = code[ip + 4 + i];
|
|
10814
|
+
const child = leadingScalarTerminal(code, armIp, 2, true, true);
|
|
10815
|
+
if (n === 2 || n === 3) {
|
|
10816
|
+
if (child >= 0) scalarFor(child);
|
|
10817
|
+
continue;
|
|
10818
|
+
}
|
|
10819
|
+
if (child >= 0) {
|
|
10820
|
+
const spec = k[code[child + 1]];
|
|
10821
|
+
if (code[child] === OP_LIT && typeof spec === "string" && spec.length >= 2) {
|
|
10822
|
+
scalarFor(child);
|
|
10823
|
+
continue;
|
|
10824
|
+
}
|
|
10825
|
+
}
|
|
10826
|
+
const family = leadingLiteralFamily(code, k, armIp);
|
|
10827
|
+
if (family !== void 0 && family.length >= 2 && family.every((terminal) => {
|
|
10828
|
+
const value = k[code[terminal + 1]];
|
|
10829
|
+
return typeof value === "string" && value.length >= 2;
|
|
10830
|
+
})) {
|
|
10831
|
+
for (const terminal of family) scalarFor(terminal);
|
|
10832
|
+
}
|
|
10833
|
+
const sequence6 = leadingScalarSequence(code, armIp);
|
|
10834
|
+
if (sequence6 !== void 0 && (sequence6.trivia < 0 || triviaScan[sequence6.trivia] != null)) {
|
|
10835
|
+
for (const terminal of sequence6.terminals) scalarFor(terminal);
|
|
10836
|
+
}
|
|
10837
|
+
}
|
|
10172
10838
|
}
|
|
10173
10839
|
}
|
|
10174
10840
|
const notChild = scalarTerminalNotChild(code, ip);
|
|
@@ -10562,25 +11228,367 @@ function firstSetToString(fs) {
|
|
|
10562
11228
|
return fs.ranges.map((r) => r.lo === r.hi ? ch(r.lo) : `${ch(r.lo)}-${ch(r.hi)}`).join(",");
|
|
10563
11229
|
}
|
|
10564
11230
|
|
|
10565
|
-
// src/
|
|
10566
|
-
function
|
|
10567
|
-
|
|
10568
|
-
|
|
10569
|
-
|
|
10570
|
-
|
|
10571
|
-
|
|
10572
|
-
|
|
10573
|
-
|
|
10574
|
-
|
|
10575
|
-
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
|
|
10582
|
-
|
|
10583
|
-
|
|
11231
|
+
// src/analysis/commitment.ts
|
|
11232
|
+
function mayFail(p, seen = /* @__PURE__ */ new Set()) {
|
|
11233
|
+
if (seen.has(p)) return true;
|
|
11234
|
+
seen.add(p);
|
|
11235
|
+
const d = p._def;
|
|
11236
|
+
switch (d.tag) {
|
|
11237
|
+
case "literal":
|
|
11238
|
+
return d.value.length > 0;
|
|
11239
|
+
case "trivia":
|
|
11240
|
+
return false;
|
|
11241
|
+
// `optional`/`many`/a min-0 `sepBy` swallow an ORDINARY failure — zero
|
|
11242
|
+
// repetitions is a match. They do NOT swallow a COMMITTED one: a dispatch
|
|
11243
|
+
// that has selected an arm and then failed inside it breaks out past every
|
|
11244
|
+
// enclosing repeat, straight to the fallible boundary. So these are total
|
|
11245
|
+
// exactly when their body cannot commit. (Measured: treating them as
|
|
11246
|
+
// unconditionally total left an extra zero-width leaf in
|
|
11247
|
+
// `BareInterpolatedSelector` on benchmark.less — a rollback the legacy
|
|
11248
|
+
// build fired and this one had deleted.)
|
|
11249
|
+
case "optional":
|
|
11250
|
+
case "many":
|
|
11251
|
+
return mayCommitFailure(d.parser);
|
|
11252
|
+
case "sepBy":
|
|
11253
|
+
return d.min >= 1 ? mayFail(d.parser, seen) : mayCommitFailure(d.parser) || mayCommitFailure(d.separator);
|
|
11254
|
+
case "oneOrMore":
|
|
11255
|
+
return mayFail(d.parser, seen);
|
|
11256
|
+
case "sequence":
|
|
11257
|
+
return d.parsers.some((x) => mayFail(x, seen));
|
|
11258
|
+
// Delegating wrappers: as fallible as what they wrap.
|
|
11259
|
+
case "node":
|
|
11260
|
+
case "transform":
|
|
11261
|
+
case "label":
|
|
11262
|
+
case "field":
|
|
11263
|
+
case "expect":
|
|
11264
|
+
case "withCtx":
|
|
11265
|
+
case "grammar":
|
|
11266
|
+
case "token":
|
|
11267
|
+
case "leaf":
|
|
11268
|
+
return mayFail(d.parser, seen);
|
|
11269
|
+
case "lazy": {
|
|
11270
|
+
try {
|
|
11271
|
+
return mayFail(d.thunk(), seen);
|
|
11272
|
+
} catch {
|
|
11273
|
+
return true;
|
|
11274
|
+
}
|
|
11275
|
+
}
|
|
11276
|
+
// An adjacency assertion is a TEST — failing is its whole job.
|
|
11277
|
+
case "adjacency":
|
|
11278
|
+
return true;
|
|
11279
|
+
default:
|
|
11280
|
+
return true;
|
|
11281
|
+
}
|
|
11282
|
+
}
|
|
11283
|
+
function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set(), triviaActive = true) {
|
|
11284
|
+
if (seen.has(p)) return false;
|
|
11285
|
+
seen.add(p);
|
|
11286
|
+
const d = p._def;
|
|
11287
|
+
switch (d.tag) {
|
|
11288
|
+
// Atomic / non-capturing-then-failing: a failure happens before any push.
|
|
11289
|
+
case "literal":
|
|
11290
|
+
case "regex":
|
|
11291
|
+
case "keywords":
|
|
11292
|
+
case "guard":
|
|
11293
|
+
// Adjacency probes with `_cap = 0` / no `commit()`: it cannot push anything.
|
|
11294
|
+
case "adjacency":
|
|
11295
|
+
case "not":
|
|
11296
|
+
// peek(): emitted under a non-capturing probe ctx and zero-width on both
|
|
11297
|
+
// outcomes, so it can never leave a partial capture behind.
|
|
11298
|
+
case "peek":
|
|
11299
|
+
case "trivia":
|
|
11300
|
+
case "token":
|
|
11301
|
+
case "leaf":
|
|
11302
|
+
case "scanTo":
|
|
11303
|
+
case "unknown":
|
|
11304
|
+
return false;
|
|
11305
|
+
// node() captures into its own private buffers and rolls them back on
|
|
11306
|
+
// failure (emitNode restores _ctx.* and never pushes on the !ok path).
|
|
11307
|
+
case "node":
|
|
11308
|
+
return false;
|
|
11309
|
+
// choice/firstMatch already roll back each failed arm; on overall failure
|
|
11310
|
+
// nothing committed remains.
|
|
11311
|
+
case "choice":
|
|
11312
|
+
return false;
|
|
11313
|
+
case "dispatch":
|
|
11314
|
+
return capturesLeaf(d.selector, new Set(seen)) || d.cases.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) || (d.matchers ? d.matchers.some((x) => mayLeavePartialCapture(x.parser, new Set(seen), triviaActive) || capturesLeaf(x.parser, new Set(seen))) : false) || (d.otherwise ? mayLeavePartialCapture(d.otherwise, new Set(seen), triviaActive) || capturesLeaf(d.otherwise, new Set(seen)) : false);
|
|
11315
|
+
case "attempt":
|
|
11316
|
+
return false;
|
|
11317
|
+
// optional never fails; many/oneOrMore only "fail" with zero captured items.
|
|
11318
|
+
case "optional":
|
|
11319
|
+
case "many":
|
|
11320
|
+
case "oneOrMore":
|
|
11321
|
+
return false;
|
|
11322
|
+
// sepBy emits its own per-iteration rollback in emitSepBy.
|
|
11323
|
+
case "sepBy":
|
|
11324
|
+
return false;
|
|
11325
|
+
// A sequence is the real case: an earlier capturing term followed by a term
|
|
11326
|
+
// that can fail leaves the earlier captures buffered.
|
|
11327
|
+
//
|
|
11328
|
+
// BOTH halves of that sentence are load-bearing, and the second half is what
|
|
11329
|
+
// this walk exists to exploit. "Some earlier term captures" alone was the old
|
|
11330
|
+
// test, and it is true of very nearly every sequence in a real grammar — a
|
|
11331
|
+
// sequence almost always opens with a literal or a node. The rollback is only
|
|
11332
|
+
// reachable if something AFTER the capture can still fail; once the remainder
|
|
11333
|
+
// is total (`optional`/`many`/trivia/a min-0 `sepBy`), the sequence has no
|
|
11334
|
+
// failure path left to roll back from, and the save+restore is dead code.
|
|
11335
|
+
//
|
|
11336
|
+
// `captured` tracks whether anything is in the buffers yet as the scan moves
|
|
11337
|
+
// left to right. Two things put it there:
|
|
11338
|
+
// - a term that captures (`capturesLeaf`/`hasNodeDef`), and
|
|
11339
|
+
// - the inter-term TRIVIA scan, which under `capturing` pushes into
|
|
11340
|
+
// `_cstRawChildren`/`_cstTriviaLog` BEFORE the term at each boundary
|
|
11341
|
+
// i >= 1. `emitSeqValues` only rewinds that push on the term's SUCCESS
|
|
11342
|
+
// path (the "matched empty, so leave the whitespace out of the span"
|
|
11343
|
+
// branch); a term that FAILS breaks straight out with the trivia still
|
|
11344
|
+
// buffered, so from boundary 1 onward the buffers are dirty regardless of
|
|
11345
|
+
// what the earlier terms did.
|
|
11346
|
+
// Each term is also asked about itself: a nested sequence can leave its own
|
|
11347
|
+
// partial capture behind, and its terms are emitted inline into this same
|
|
11348
|
+
// block with no boundary of their own to roll them back.
|
|
11349
|
+
case "sequence": {
|
|
11350
|
+
const parts = d.parsers;
|
|
11351
|
+
let captured = false;
|
|
11352
|
+
for (let i = 0; i < parts.length; i++) {
|
|
11353
|
+
const part = parts[i];
|
|
11354
|
+
if (i > 0 && triviaActive) captured = true;
|
|
11355
|
+
if (captured && mayFail(part)) return true;
|
|
11356
|
+
if (mayLeavePartialCapture(part, seen, triviaActive)) return true;
|
|
11357
|
+
if (capturesLeaf(part) || hasNodeDef(part)) captured = true;
|
|
11358
|
+
}
|
|
11359
|
+
return false;
|
|
11360
|
+
}
|
|
11361
|
+
// Delegating wrappers: defer to the wrapped parser.
|
|
11362
|
+
case "transform":
|
|
11363
|
+
case "label":
|
|
11364
|
+
case "field":
|
|
11365
|
+
case "expect":
|
|
11366
|
+
case "withCtx":
|
|
11367
|
+
case "grammar":
|
|
11368
|
+
return mayLeavePartialCapture(d.parser, seen, triviaActive);
|
|
11369
|
+
case "recover":
|
|
11370
|
+
return mayLeavePartialCapture(d.parser, seen, triviaActive);
|
|
11371
|
+
case "lazy": {
|
|
11372
|
+
try {
|
|
11373
|
+
return mayLeavePartialCapture(d.thunk(), seen, triviaActive);
|
|
11374
|
+
} catch {
|
|
11375
|
+
return true;
|
|
11376
|
+
}
|
|
11377
|
+
}
|
|
11378
|
+
// Unknown shapes: be safe and keep the rollback.
|
|
11379
|
+
default:
|
|
11380
|
+
return true;
|
|
11381
|
+
}
|
|
11382
|
+
}
|
|
11383
|
+
function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
|
|
11384
|
+
if (seen.has(p)) return false;
|
|
11385
|
+
seen.add(p);
|
|
11386
|
+
const d = p._def;
|
|
11387
|
+
switch (d.tag) {
|
|
11388
|
+
case "literal":
|
|
11389
|
+
case "regex":
|
|
11390
|
+
case "keywords":
|
|
11391
|
+
case "node":
|
|
11392
|
+
case "token":
|
|
11393
|
+
case "routed":
|
|
11394
|
+
case "leaf":
|
|
11395
|
+
return true;
|
|
11396
|
+
case "not":
|
|
11397
|
+
case "peek":
|
|
11398
|
+
case "guard":
|
|
11399
|
+
case "adjacency":
|
|
11400
|
+
case "trivia":
|
|
11401
|
+
case "unknown":
|
|
11402
|
+
return false;
|
|
11403
|
+
case "sequence":
|
|
11404
|
+
case "choice":
|
|
11405
|
+
return d.parsers.some((x) => capturesLeaf(x, seen));
|
|
11406
|
+
case "dispatch":
|
|
11407
|
+
return capturesLeaf(d.selector, seen) || d.cases.some((x) => capturesLeaf(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => capturesLeaf(entry.parser, seen)) : false) || (d.otherwise ? capturesLeaf(d.otherwise, seen) : false);
|
|
11408
|
+
case "sepBy":
|
|
11409
|
+
return capturesLeaf(d.parser, seen) || capturesLeaf(d.separator, seen);
|
|
11410
|
+
case "many":
|
|
11411
|
+
case "oneOrMore":
|
|
11412
|
+
case "optional":
|
|
11413
|
+
case "attempt":
|
|
11414
|
+
case "transform":
|
|
11415
|
+
case "label":
|
|
11416
|
+
case "field":
|
|
11417
|
+
case "expect":
|
|
11418
|
+
case "withCtx":
|
|
11419
|
+
case "grammar":
|
|
11420
|
+
case "recover":
|
|
11421
|
+
return capturesLeaf(d.parser, seen);
|
|
11422
|
+
case "scanTo":
|
|
11423
|
+
return true;
|
|
11424
|
+
case "lazy": {
|
|
11425
|
+
try {
|
|
11426
|
+
return capturesLeaf(d.thunk(), seen);
|
|
11427
|
+
} catch {
|
|
11428
|
+
return true;
|
|
11429
|
+
}
|
|
11430
|
+
}
|
|
11431
|
+
default:
|
|
11432
|
+
return true;
|
|
11433
|
+
}
|
|
11434
|
+
}
|
|
11435
|
+
function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
11436
|
+
if (seen.has(p)) return false;
|
|
11437
|
+
seen.add(p);
|
|
11438
|
+
const d = p._def;
|
|
11439
|
+
switch (d.tag) {
|
|
11440
|
+
case "node":
|
|
11441
|
+
return true;
|
|
11442
|
+
case "lazy": {
|
|
11443
|
+
try {
|
|
11444
|
+
return hasNodeDef(d.thunk(), seen);
|
|
11445
|
+
} catch {
|
|
11446
|
+
return false;
|
|
11447
|
+
}
|
|
11448
|
+
}
|
|
11449
|
+
case "grammar":
|
|
11450
|
+
case "trivia":
|
|
11451
|
+
case "token":
|
|
11452
|
+
case "leaf":
|
|
11453
|
+
case "label":
|
|
11454
|
+
case "field":
|
|
11455
|
+
case "optional":
|
|
11456
|
+
case "many":
|
|
11457
|
+
case "oneOrMore":
|
|
11458
|
+
case "not":
|
|
11459
|
+
case "peek":
|
|
11460
|
+
case "transform":
|
|
11461
|
+
return hasNodeDef(d.parser, seen);
|
|
11462
|
+
case "sequence":
|
|
11463
|
+
case "choice":
|
|
11464
|
+
return d.parsers.some((x) => hasNodeDef(x, seen));
|
|
11465
|
+
case "dispatch":
|
|
11466
|
+
return hasNodeDef(d.selector, seen) || d.cases.some((x) => hasNodeDef(x.parser, seen)) || (d.matchers ? d.matchers.some((entry) => hasNodeDef(entry.parser, seen)) : false) || (d.otherwise ? hasNodeDef(d.otherwise, seen) : false);
|
|
11467
|
+
case "sepBy":
|
|
11468
|
+
return hasNodeDef(d.parser, seen) || hasNodeDef(d.separator, seen);
|
|
11469
|
+
case "scanTo":
|
|
11470
|
+
return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen));
|
|
11471
|
+
case "recover":
|
|
11472
|
+
return hasNodeDef(d.parser, seen) || hasNodeDef(d.sentinel, seen);
|
|
11473
|
+
case "expect":
|
|
11474
|
+
return hasNodeDef(d.parser, seen);
|
|
11475
|
+
case "withCtx":
|
|
11476
|
+
return hasNodeDef(d.parser, seen);
|
|
11477
|
+
default:
|
|
11478
|
+
return false;
|
|
11479
|
+
}
|
|
11480
|
+
}
|
|
11481
|
+
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
11482
|
+
if (seen.has(p)) return false;
|
|
11483
|
+
seen.add(p);
|
|
11484
|
+
const d = p._def;
|
|
11485
|
+
switch (d.tag) {
|
|
11486
|
+
case "node":
|
|
11487
|
+
return d.build !== void 0 || hasDirectBuildDef(d.parser, seen);
|
|
11488
|
+
case "lazy": {
|
|
11489
|
+
try {
|
|
11490
|
+
return hasDirectBuildDef(d.thunk(), seen);
|
|
11491
|
+
} catch {
|
|
11492
|
+
return false;
|
|
11493
|
+
}
|
|
11494
|
+
}
|
|
11495
|
+
case "grammar":
|
|
11496
|
+
case "trivia":
|
|
11497
|
+
case "token":
|
|
11498
|
+
case "leaf":
|
|
11499
|
+
case "label":
|
|
11500
|
+
case "field":
|
|
11501
|
+
case "optional":
|
|
11502
|
+
case "many":
|
|
11503
|
+
case "oneOrMore":
|
|
11504
|
+
case "attempt":
|
|
11505
|
+
case "not":
|
|
11506
|
+
case "peek":
|
|
11507
|
+
case "withCtx":
|
|
11508
|
+
case "expect":
|
|
11509
|
+
case "transform":
|
|
11510
|
+
return hasDirectBuildDef(d.parser, seen);
|
|
11511
|
+
case "sequence":
|
|
11512
|
+
case "choice":
|
|
11513
|
+
return d.parsers.some((x) => hasDirectBuildDef(x, seen));
|
|
11514
|
+
case "dispatch":
|
|
11515
|
+
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);
|
|
11516
|
+
case "sepBy":
|
|
11517
|
+
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.separator, seen);
|
|
11518
|
+
case "scanTo":
|
|
11519
|
+
return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen));
|
|
11520
|
+
case "recover":
|
|
11521
|
+
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.sentinel, seen);
|
|
11522
|
+
case "routed":
|
|
11523
|
+
return d.fallback ? hasDirectBuildDef(d.fallback, seen) : false;
|
|
11524
|
+
default:
|
|
11525
|
+
return false;
|
|
11526
|
+
}
|
|
11527
|
+
}
|
|
11528
|
+
function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve) {
|
|
11529
|
+
if (seen.has(p)) return false;
|
|
11530
|
+
seen.add(p);
|
|
11531
|
+
const d = p._def;
|
|
11532
|
+
switch (d.tag) {
|
|
11533
|
+
case "dispatch":
|
|
11534
|
+
return true;
|
|
11535
|
+
case "choice":
|
|
11536
|
+
case "sequence":
|
|
11537
|
+
return d.parsers.some((x) => mayCommitFailure(x, seen, resolve));
|
|
11538
|
+
case "many":
|
|
11539
|
+
case "oneOrMore":
|
|
11540
|
+
case "optional":
|
|
11541
|
+
case "attempt":
|
|
11542
|
+
case "transform":
|
|
11543
|
+
case "label":
|
|
11544
|
+
case "field":
|
|
11545
|
+
case "grammar":
|
|
11546
|
+
case "node":
|
|
11547
|
+
return mayCommitFailure(d.parser, seen, resolve);
|
|
11548
|
+
case "sepBy":
|
|
11549
|
+
return mayCommitFailure(d.parser, seen, resolve) || mayCommitFailure(d.separator, seen, resolve);
|
|
11550
|
+
case "token":
|
|
11551
|
+
case "leaf":
|
|
11552
|
+
return mayCommitFailure(d.parser, seen, resolve);
|
|
11553
|
+
case "withCtx":
|
|
11554
|
+
return mayCommitFailure(d.parser, seen, resolve);
|
|
11555
|
+
case "scanTo":
|
|
11556
|
+
return mayCommitFailure(d.sentinel, seen, resolve) || d.skip.some((x) => mayCommitFailure(x, seen, resolve));
|
|
11557
|
+
case "lazy": {
|
|
11558
|
+
try {
|
|
11559
|
+
return mayCommitFailure(d.thunk(), seen, resolve);
|
|
11560
|
+
} catch {
|
|
11561
|
+
const name = p._ruleName;
|
|
11562
|
+
const target = name === void 0 ? void 0 : resolve?.(name);
|
|
11563
|
+
return target === void 0 ? true : mayCommitFailure(target, seen, resolve);
|
|
11564
|
+
}
|
|
11565
|
+
}
|
|
11566
|
+
case "unknown":
|
|
11567
|
+
return true;
|
|
11568
|
+
default:
|
|
11569
|
+
return false;
|
|
11570
|
+
}
|
|
11571
|
+
}
|
|
11572
|
+
|
|
11573
|
+
// src/compiler/direct-projection.ts
|
|
11574
|
+
function directArrayProjection(fn, fnSrc, arity) {
|
|
11575
|
+
let source = fnSrc;
|
|
11576
|
+
if (source === void 0) {
|
|
11577
|
+
source = Function.prototype.toString.call(fn);
|
|
11578
|
+
if (source.includes("[native code]")) return null;
|
|
11579
|
+
}
|
|
11580
|
+
const match = /^\s*\(\s*\[([^\]]*)\]\s*\)\s*=>\s*([A-Za-z_$][\w$]*)\s*$/.exec(source);
|
|
11581
|
+
if (match === null) return null;
|
|
11582
|
+
const slots = match[1].split(",").map((slot) => slot.trim());
|
|
11583
|
+
if (slots.length > arity) return null;
|
|
11584
|
+
const result = match[2];
|
|
11585
|
+
let selected = -1;
|
|
11586
|
+
for (let i = 0; i < slots.length; i++) {
|
|
11587
|
+
const slot = slots[i];
|
|
11588
|
+
if (slot === "") continue;
|
|
11589
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(slot)) return null;
|
|
11590
|
+
if (slot === result) {
|
|
11591
|
+
if (selected >= 0) return null;
|
|
10584
11592
|
selected = i;
|
|
10585
11593
|
}
|
|
10586
11594
|
}
|
|
@@ -10589,7 +11597,6 @@ function directArrayProjection(fn, fnSrc, arity) {
|
|
|
10589
11597
|
|
|
10590
11598
|
// src/table/encode.ts
|
|
10591
11599
|
import {
|
|
10592
|
-
assertLexicalCapabilityClosure,
|
|
10593
11600
|
collectLexicalCapabilities,
|
|
10594
11601
|
winnerWrapsReference as winnerWrapsReference2
|
|
10595
11602
|
} from "../compiler/token-capability.js";
|
|
@@ -10981,6 +11988,9 @@ var Encoder = class {
|
|
|
10981
11988
|
lexIndex = /* @__PURE__ */ new Map();
|
|
10982
11989
|
lexPrograms = [];
|
|
10983
11990
|
lexProgramIndex = /* @__PURE__ */ new Map();
|
|
11991
|
+
choiceRollbackMasks = /* @__PURE__ */ new Map();
|
|
11992
|
+
nonCommittingChoiceSites = /* @__PURE__ */ new Set();
|
|
11993
|
+
failureRollbackCleanSites = /* @__PURE__ */ new Set();
|
|
10984
11994
|
labels = void 0;
|
|
10985
11995
|
/** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
|
|
10986
11996
|
activeTrivia = void 0;
|
|
@@ -11391,6 +12401,71 @@ var Encoder = class {
|
|
|
11391
12401
|
const w = this.winners;
|
|
11392
12402
|
return w === void 0 ? void 0 : (name) => w[name];
|
|
11393
12403
|
}
|
|
12404
|
+
/**
|
|
12405
|
+
* Whether a failed ordered-choice arm can leave state that the enclosing
|
|
12406
|
+
* choice must restore before trying its successor.
|
|
12407
|
+
*
|
|
12408
|
+
* `mayLeavePartialCapture` is the existing sound CST/trivia proof. The extra
|
|
12409
|
+
* writer census covers the side sinks that proof deliberately does not model:
|
|
12410
|
+
* fields, recovered errors, and interpreted scanners. Strict assemblies do
|
|
12411
|
+
* not run repeat recovery, but these rows can still publish through a caller's
|
|
12412
|
+
* context. Cycles are safe to stop: revisiting the same combinator cannot
|
|
12413
|
+
* discover a writer the first traversal did not already reach.
|
|
12414
|
+
*/
|
|
12415
|
+
failureNeedsRollback(p, autoNot) {
|
|
12416
|
+
const refName = p._ruleName;
|
|
12417
|
+
const winner = refName === void 0 ? void 0 : this.winners?.[refName];
|
|
12418
|
+
const root = winner !== void 0 && !winnerWrapsReference2(winner, p) ? winner : p;
|
|
12419
|
+
const sideWriterMemo = /* @__PURE__ */ new Map();
|
|
12420
|
+
const hasSideWriter = (current, seen = /* @__PURE__ */ new Set()) => {
|
|
12421
|
+
const cached = sideWriterMemo.get(current);
|
|
12422
|
+
if (cached !== void 0) return { found: cached, complete: true };
|
|
12423
|
+
if (seen.has(current)) return { found: false, complete: false };
|
|
12424
|
+
const next = new Set(seen);
|
|
12425
|
+
next.add(current);
|
|
12426
|
+
const def = current._def;
|
|
12427
|
+
let result;
|
|
12428
|
+
switch (def.tag) {
|
|
12429
|
+
case "field":
|
|
12430
|
+
case "expect":
|
|
12431
|
+
case "recover":
|
|
12432
|
+
case "scanTo":
|
|
12433
|
+
case "unknown":
|
|
12434
|
+
result = { found: true, complete: true };
|
|
12435
|
+
break;
|
|
12436
|
+
case "lazy": {
|
|
12437
|
+
const name = current._ruleName;
|
|
12438
|
+
const resolvedWinner = name === void 0 ? void 0 : this.winners?.[name];
|
|
12439
|
+
if (resolvedWinner !== void 0 && !winnerWrapsReference2(resolvedWinner, current)) {
|
|
12440
|
+
result = hasSideWriter(resolvedWinner, next);
|
|
12441
|
+
break;
|
|
12442
|
+
}
|
|
12443
|
+
try {
|
|
12444
|
+
result = hasSideWriter(def.thunk(), next);
|
|
12445
|
+
} catch {
|
|
12446
|
+
result = { found: true, complete: true };
|
|
12447
|
+
}
|
|
12448
|
+
break;
|
|
12449
|
+
}
|
|
12450
|
+
default: {
|
|
12451
|
+
let complete = true;
|
|
12452
|
+
result = { found: false, complete: true };
|
|
12453
|
+
for (const child of childrenOf(def)) {
|
|
12454
|
+
const childResult = hasSideWriter(child, next);
|
|
12455
|
+
if (childResult.found) {
|
|
12456
|
+
result = { found: true, complete: true };
|
|
12457
|
+
break;
|
|
12458
|
+
}
|
|
12459
|
+
complete &&= childResult.complete;
|
|
12460
|
+
}
|
|
12461
|
+
if (!result.found) result = { found: false, complete };
|
|
12462
|
+
}
|
|
12463
|
+
}
|
|
12464
|
+
if (result.found || result.complete) sideWriterMemo.set(current, result.found);
|
|
12465
|
+
return result;
|
|
12466
|
+
};
|
|
12467
|
+
return mayLeavePartialCapture(root, /* @__PURE__ */ new Set(), true) || hasSideWriter(root).found || (autoNot?.length ?? 0) > 0 && capturesLeaf(root);
|
|
12468
|
+
}
|
|
11394
12469
|
/** A first set becomes a char class string, or −1 for `any`. */
|
|
11395
12470
|
charClass(fs) {
|
|
11396
12471
|
if (fs.kind !== "ranges" || fs.ranges.length === 0) return -1;
|
|
@@ -11676,9 +12751,39 @@ var Encoder = class {
|
|
|
11676
12751
|
});
|
|
11677
12752
|
const rr = this.refResolver();
|
|
11678
12753
|
const finalChoice = classifyFinalChoice(arms, rr);
|
|
11679
|
-
const
|
|
12754
|
+
const transactionalFirst = arms.map((arm, i) => {
|
|
12755
|
+
if (!finalChoice.nullable[i]) return void 0;
|
|
12756
|
+
const def = arm._def;
|
|
12757
|
+
if (def.tag !== "attempt" || matchesEmpty(def.parser, /* @__PURE__ */ new Set(), rr)) return void 0;
|
|
12758
|
+
return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr);
|
|
12759
|
+
});
|
|
12760
|
+
const gateFirst = finalChoice.firstSets.map((first, i) => transactionalFirst[i] ?? first);
|
|
12761
|
+
const classes = gateFirst.map((first, i) => finalChoice.nullable[i] && transactionalFirst[i] === void 0 ? -1 : this.charClass(first));
|
|
12762
|
+
if (transactionalFirst.some((first) => first !== void 0) && classes.every((cls) => cls >= 0)) {
|
|
12763
|
+
let overlap = false;
|
|
12764
|
+
for (let i = 0; i < gateFirst.length && !overlap; i++) {
|
|
12765
|
+
for (let j = i + 1; j < gateFirst.length; j++) {
|
|
12766
|
+
if (intersects(gateFirst[i], gateFirst[j])) {
|
|
12767
|
+
overlap = true;
|
|
12768
|
+
break;
|
|
12769
|
+
}
|
|
12770
|
+
}
|
|
12771
|
+
}
|
|
12772
|
+
if (!overlap) for (let i = 0; i < classes.length; i++) {
|
|
12773
|
+
if (transactionalFirst[i] !== void 0) classes[i] = -1;
|
|
12774
|
+
}
|
|
12775
|
+
}
|
|
11680
12776
|
const dispIdx = this.disp.length;
|
|
11681
12777
|
this.disp.push(classes);
|
|
12778
|
+
let rollbackMask = kids.length > 31 ? -1 : 0;
|
|
12779
|
+
if (rollbackMask === 0) {
|
|
12780
|
+
for (let i = 0; i < arms.length; i++) {
|
|
12781
|
+
const src = order[i];
|
|
12782
|
+
if (this.failureNeedsRollback(arms[i], d.autoNot[src])) {
|
|
12783
|
+
rollbackMask |= 1 << i;
|
|
12784
|
+
}
|
|
12785
|
+
}
|
|
12786
|
+
}
|
|
11682
12787
|
const head = this.emitHead(OP_CHOICE, 3 + 2 * kids.length);
|
|
11683
12788
|
this.code[head + 1] = dispIdx;
|
|
11684
12789
|
this.code[head + 2] = kids.length;
|
|
@@ -11687,6 +12792,10 @@ var Encoder = class {
|
|
|
11687
12792
|
this.code[head + 4 + i] = kids[i];
|
|
11688
12793
|
this.code[head + 4 + kids.length + i] = this.expected(deriveExpected(arms[i]));
|
|
11689
12794
|
}
|
|
12795
|
+
this.choiceRollbackMasks.set(head, rollbackMask);
|
|
12796
|
+
if (arms.every((arm) => !mayCommitFailure(arm, /* @__PURE__ */ new Set(), rr))) {
|
|
12797
|
+
this.nonCommittingChoiceSites.add(head);
|
|
12798
|
+
}
|
|
11690
12799
|
return head;
|
|
11691
12800
|
}
|
|
11692
12801
|
case "many":
|
|
@@ -11716,8 +12825,11 @@ var Encoder = class {
|
|
|
11716
12825
|
}
|
|
11717
12826
|
return d.min >= 2 ? this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags, this.expected(deriveExpected(d.parser))) : this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags);
|
|
11718
12827
|
}
|
|
11719
|
-
case "optional":
|
|
11720
|
-
|
|
12828
|
+
case "optional": {
|
|
12829
|
+
const head = this.emit(OP_OPT, this.node(d.parser).ip);
|
|
12830
|
+
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(head);
|
|
12831
|
+
return head;
|
|
12832
|
+
}
|
|
11721
12833
|
case "transform": {
|
|
11722
12834
|
const inner = d.parser._def;
|
|
11723
12835
|
if (inner.tag === "sequence" && !this.memo.has(d.parser) && !this.pending.has(d.parser)) {
|
|
@@ -11876,6 +12988,7 @@ var Encoder = class {
|
|
|
11876
12988
|
// lowering was correct only for a choice arm.
|
|
11877
12989
|
case "attempt": {
|
|
11878
12990
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
|
|
12991
|
+
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
11879
12992
|
const fs = d.parser._meta.firstSet;
|
|
11880
12993
|
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
11881
12994
|
const cls = this.charClass(fs);
|
|
@@ -12044,6 +13157,10 @@ var Encoder = class {
|
|
|
12044
13157
|
...this.rec ? { rec: 1 } : {},
|
|
12045
13158
|
...this.cov === void 0 ? {} : { cov: this.cov },
|
|
12046
13159
|
lines: this.track ? 1 : 0
|
|
13160
|
+
}, void 0, {
|
|
13161
|
+
choiceRollbackMasks: this.choiceRollbackMasks,
|
|
13162
|
+
failureRollbackCleanSites: this.failureRollbackCleanSites,
|
|
13163
|
+
nonCommittingChoiceSites: this.nonCommittingChoiceSites
|
|
12047
13164
|
});
|
|
12048
13165
|
}
|
|
12049
13166
|
};
|
|
@@ -12091,7 +13208,6 @@ function encodeTableProgram(ruleMap, settings = {}) {
|
|
|
12091
13208
|
const lexicalRoots = [...names].sort().map((name) => ruleMap[name]);
|
|
12092
13209
|
const resolveLexical = (name) => ruleMap[name];
|
|
12093
13210
|
const capabilities = collectLexicalCapabilities(lexicalRoots, resolveLexical);
|
|
12094
|
-
assertLexicalCapabilityClosure(lexicalRoots, capabilities, resolveLexical);
|
|
12095
13211
|
const enc = new Encoder(resolvedSettings, capabilities.capabilityComplete);
|
|
12096
13212
|
enc.winners = ruleMap;
|
|
12097
13213
|
for (const name of names) enc.encodeRule(name, ruleMap[name]);
|
|
@@ -12177,7 +13293,7 @@ function emitAssemblies(prog, cfgs) {
|
|
|
12177
13293
|
seen.add(key);
|
|
12178
13294
|
let em;
|
|
12179
13295
|
try {
|
|
12180
|
-
em = emitAssemblySource(t, prog, cfg, extraIps);
|
|
13296
|
+
em = emitAssemblySource(t, prog, cfg, extraIps, true);
|
|
12181
13297
|
} catch (e) {
|
|
12182
13298
|
if (e instanceof Unemittable) continue;
|
|
12183
13299
|
throw e;
|
|
@@ -13739,7 +14855,7 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
|
13739
14855
|
};
|
|
13740
14856
|
const { prog, fnSrcs } = encodeTableProgram({ [ENTRY]: combinator }, settings);
|
|
13741
14857
|
const artifact = closureArtifact(prog);
|
|
13742
|
-
const entry = tableRules(
|
|
14858
|
+
const entry = tableRules(prog)[ENTRY];
|
|
13743
14859
|
const offered = opts.fnSources ?? mapFnSources;
|
|
13744
14860
|
const supplied = offered !== void 0 && offered.length === fnSrcs.length ? offered : void 0;
|
|
13745
14861
|
const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? ownSource(prog.fns[i]));
|
|
@@ -13788,55 +14904,6 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
|
13788
14904
|
};
|
|
13789
14905
|
}
|
|
13790
14906
|
|
|
13791
|
-
// src/analysis/commitment.ts
|
|
13792
|
-
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
13793
|
-
if (seen.has(p)) return false;
|
|
13794
|
-
seen.add(p);
|
|
13795
|
-
const d = p._def;
|
|
13796
|
-
switch (d.tag) {
|
|
13797
|
-
case "node":
|
|
13798
|
-
return d.build !== void 0 || hasDirectBuildDef(d.parser, seen);
|
|
13799
|
-
case "lazy": {
|
|
13800
|
-
try {
|
|
13801
|
-
return hasDirectBuildDef(d.thunk(), seen);
|
|
13802
|
-
} catch {
|
|
13803
|
-
return false;
|
|
13804
|
-
}
|
|
13805
|
-
}
|
|
13806
|
-
case "grammar":
|
|
13807
|
-
case "trivia":
|
|
13808
|
-
case "token":
|
|
13809
|
-
case "leaf":
|
|
13810
|
-
case "label":
|
|
13811
|
-
case "field":
|
|
13812
|
-
case "optional":
|
|
13813
|
-
case "many":
|
|
13814
|
-
case "oneOrMore":
|
|
13815
|
-
case "attempt":
|
|
13816
|
-
case "not":
|
|
13817
|
-
case "peek":
|
|
13818
|
-
case "withCtx":
|
|
13819
|
-
case "expect":
|
|
13820
|
-
case "transform":
|
|
13821
|
-
return hasDirectBuildDef(d.parser, seen);
|
|
13822
|
-
case "sequence":
|
|
13823
|
-
case "choice":
|
|
13824
|
-
return d.parsers.some((x) => hasDirectBuildDef(x, seen));
|
|
13825
|
-
case "dispatch":
|
|
13826
|
-
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);
|
|
13827
|
-
case "sepBy":
|
|
13828
|
-
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.separator, seen);
|
|
13829
|
-
case "scanTo":
|
|
13830
|
-
return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen));
|
|
13831
|
-
case "recover":
|
|
13832
|
-
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.sentinel, seen);
|
|
13833
|
-
case "routed":
|
|
13834
|
-
return d.fallback ? hasDirectBuildDef(d.fallback, seen) : false;
|
|
13835
|
-
default:
|
|
13836
|
-
return false;
|
|
13837
|
-
}
|
|
13838
|
-
}
|
|
13839
|
-
|
|
13840
14907
|
// src/cst/reflection.ts
|
|
13841
14908
|
function childrenOf2(def) {
|
|
13842
14909
|
switch (def.tag) {
|
|
@@ -14030,7 +15097,7 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
14030
15097
|
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
14031
15098
|
reflection: collectGrammarReflection(ruleMap),
|
|
14032
15099
|
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
14033
|
-
rules: tableRules(
|
|
15100
|
+
rules: tableRules(prog),
|
|
14034
15101
|
prog: artifact
|
|
14035
15102
|
};
|
|
14036
15103
|
}
|