parseman 0.61.4 → 0.61.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analysis/diagnostics.js +844 -522
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +846 -522
- package/dist/cli/index.js.map +3 -3
- package/dist/cst/capture-buffer.d.ts +3 -2
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.js +846 -520
- package/dist/index.js.map +3 -3
- package/dist/plugin/index.js +844 -518
- package/dist/plugin/index.js.map +3 -3
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/child-slots.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +1 -1
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/fail-clean.d.ts.map +1 -1
- package/dist/table/hold-gap.d.ts.map +1 -1
- package/dist/table/index.js +368 -42
- package/dist/table/index.js.map +3 -3
- package/dist/table/late-frame.d.ts +18 -0
- package/dist/table/late-frame.d.ts.map +1 -0
- package/dist/table/ops.d.ts +17 -0
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/select-hot.d.ts.map +1 -1
- package/dist/table/site-labels.d.ts +5 -1
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/cst/capture-buffer.ts +20 -11
- package/src/table/assemble.ts +124 -4
- package/src/table/child-slots.ts +9 -1
- package/src/table/emit-assembly.ts +101 -14
- package/src/table/encode.ts +69 -6
- package/src/table/exec.ts +7 -1
- package/src/table/fail-clean.ts +8 -1
- package/src/table/hold-gap.ts +5 -1
- package/src/table/late-frame.ts +54 -0
- package/src/table/ops.ts +19 -0
- package/src/table/select-hot.ts +7 -1
- package/src/table/site-labels.ts +38 -14
- package/src/version.ts +1 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type ContinuationGate = {
|
|
2
|
+
/** Class of the first character, past any trivia. */
|
|
3
|
+
readonly cls: number;
|
|
4
|
+
/** The regex row of a leading gap, or −1. */
|
|
5
|
+
readonly gapRow: number;
|
|
6
|
+
/** Class of the character after the gap. */
|
|
7
|
+
readonly follow: number;
|
|
8
|
+
/** Class of an arm that opens without the gap, or −1. */
|
|
9
|
+
readonly other: number;
|
|
10
|
+
};
|
|
11
|
+
export declare function continuationGate(code: ArrayLike<number>, ip: number): ContinuationGate | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Can this assembly decide at this `OP_CONT`? It needs the tail's test, and the
|
|
14
|
+
* trivia the label names: a scope it cannot name, or one with no scanner, would cost a
|
|
15
|
+
* hit more calls than the frame it saves on a miss.
|
|
16
|
+
*/
|
|
17
|
+
export declare function canDecide(code: ArrayLike<number>, ip: number, tri: number, triviaScan: readonly unknown[]): boolean;
|
|
18
|
+
//# sourceMappingURL=late-frame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"late-frame.d.ts","sourceRoot":"","sources":["../../src/table/late-frame.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,qDAAqD;IACrD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAoBlG;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAGnH"}
|
package/dist/table/ops.d.ts
CHANGED
|
@@ -508,6 +508,23 @@ export declare const OP_RGATE2 = 47;
|
|
|
508
508
|
* assembly resolves it to one child; it has no body of its own.
|
|
509
509
|
*/
|
|
510
510
|
export declare const OP_STRICT = 48;
|
|
511
|
+
/**
|
|
512
|
+
* `CONT corner wrapper tail` — a `collapse` node that is `sequence(corner, tail)`, with
|
|
513
|
+
* a tail that can take nothing and a corner that is one node. A strict assembly runs
|
|
514
|
+
* `corner` in the PARENT's collector and looks at the next token. Where `tail` cannot
|
|
515
|
+
* start there, the corner is the result: no frame, no children, no builder. Where it
|
|
516
|
+
* can, the corner's publication is taken back and `wrapper`'s frame opens around it and
|
|
517
|
+
* `tail`, in this one function. `tail` is read for the decision (`late-frame.ts`). Where
|
|
518
|
+
* no decision can be made, and under recovery, a probe or the reference driver, this
|
|
519
|
+
* is `wrapper`, the node as written.
|
|
520
|
+
*/
|
|
521
|
+
export declare const OP_CONT = 49;
|
|
522
|
+
/**
|
|
523
|
+
* `SEED corner` — marks the first term of `wrapper`'s body. Run, it is `corner`. It
|
|
524
|
+
* exists so the labels can leave out the edge from a late frame to its corner, which
|
|
525
|
+
* never runs there.
|
|
526
|
+
*/
|
|
527
|
+
export declare const OP_SEED = 50;
|
|
511
528
|
/**
|
|
512
529
|
* `DISPATCH sel d other otherRouted n a1 … an` — `dispatch()`.
|
|
513
530
|
*
|
package/dist/table/ops.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/table/ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,6FAA6F;AAC7F,eAAO,MAAM,MAAM,IAAI,CAAA;AACvB,kFAAkF;AAClF,eAAO,MAAM,KAAK,IAAI,CAAA;AACtB,6EAA6E;AAC7E,eAAO,MAAM,MAAM,IAAI,CAAA;AACvB,iFAAiF;AACjF,eAAO,MAAM,OAAO,IAAI,CAAA;AACxB;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,IAAI,CAAA;AAC1B;;;;;;;;;;GAUG;AACH,eAAO,MAAM,MAAM,IAAI,CAAA;AACvB,2CAA2C;AAC3C,eAAO,MAAM,OAAO,IAAI,CAAA;AACxB;;;;kDAIkD;AAClD,eAAO,MAAM,MAAM,IAAI,CAAA;AACvB,qEAAqE;AACrE,eAAO,MAAM,QAAQ,IAAI,CAAA;AACzB;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,OAAO,KAAK,CAAA;AACzB,2CAA2C;AAC3C,eAAO,MAAM,OAAO,KAAK,CAAA;AACzB,iIAAiI;AACjI,eAAO,MAAM,OAAO,KAAK,CAAA;AACzB,8FAA8F;AAC9F,eAAO,MAAM,MAAM,KAAK,CAAA;AACxB;;;;;GAKG;AACH,eAAO,MAAM,OAAO,KAAK,CAAA;AACzB,oEAAoE;AACpE,eAAO,MAAM,OAAO,KAAK,CAAA;AACzB,0CAA0C;AAC1C,eAAO,MAAM,QAAQ,KAAK,CAAA;AAC1B;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,KAAK,CAAA;AAC9B,eAAO,MAAM,WAAW,KAAK,CAAA;AAC7B,eAAO,MAAM,aAAa,KAAK,CAAA;AAC/B;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,KAAK,CAAA;AAC1B;;;GAGG;AACH,eAAO,MAAM,SAAS,KAAK,CAAA;AAC3B;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,OAAO,KAAK,CAAA;AACzB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,OAAO,KAAK,CAAA;AACzB;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,KAAK,CAAA;AAC1B;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,KAAK,CAAA;AAC3B,gEAAgE;AAChE,eAAO,MAAM,eAAe,KAAK,CAAA;AACjC;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ,KAAK,CAAA;AAC1B;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,YAAY,KAAK,CAAA;AAC9B;;;;GAIG;AACH,eAAO,MAAM,aAAa,KAAK,CAAA;AAC/B;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,KAAK,CAAA;AAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,MAAM,KAAK,CAAA;AACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,SAAS,KAAK,CAAA;AAC3B;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,SAAS,KAAK,CAAA;AAC3B;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,OAAO,KAAK,CAAA;AACzB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,KAAK,CAAA;AAC1B;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,MAAM,KAAK,CAAA;AACxB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,KAAK,CAAA;AAChC;;;;;;;;;GASG;AACH;kFACkF;AAClF,eAAO,MAAM,WAAW,KAAK,CAAA;AAC7B,0EAA0E;AAC1E,eAAO,MAAM,cAAc,KAAK,CAAA;AAChC,oFAAoF;AACpF,eAAO,MAAM,cAAc,KAAK,CAAA;AAChC;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,KAAK,CAAA;AAC1B;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B;;;;;GAKG;AACH,eAAO,MAAM,SAAS,KAAK,CAAA;AAC3B;;;;;GAKG;AACH,eAAO,MAAM,SAAS,KAAK,CAAA;AAC3B;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,KAAK,CAAA;AAC7B;;;;GAIG;AACH,eAAO,MAAM,SAAS,KAAK,CAAA;AAE3B,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/table/ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select-hot.d.ts","sourceRoot":"","sources":["../../src/table/select-hot.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"select-hot.d.ts","sourceRoot":"","sources":["../../src/table/select-hot.ts"],"names":[],"mappings":"AAwBA;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACtC,MAAM,EAAE,MAAM;AACd;iCACiC;AACjC,OAAO,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,GAC1B,GAAG,CAAC,MAAM,CAAC,CAgBb;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC;AACtC,2DAA2D;AAC3D,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,MAAM,EACnD,OAAO,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,GAC1B;IAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAQ7E"}
|
|
@@ -69,6 +69,8 @@ export declare function gatedPassCollapse(code: Int32Array, ip: number, hostCst:
|
|
|
69
69
|
/** A site's label, or `TOP` for anything the walk did not reach. */
|
|
70
70
|
export type SiteLabels = {
|
|
71
71
|
at: (ip: number) => SiteLabel;
|
|
72
|
+
/** The `OP_CONT` sites whose corner runs in the parent's collector in every engine. */
|
|
73
|
+
late: ReadonlySet<number>;
|
|
72
74
|
};
|
|
73
75
|
/**
|
|
74
76
|
* Compute a label for every site reachable from `roots`.
|
|
@@ -82,7 +84,9 @@ export type SiteLabels = {
|
|
|
82
84
|
* The meet only ever moves a label toward `TOP`, and `TOP` is absorbing, so the
|
|
83
85
|
* lattice has height three and the walk terminates.
|
|
84
86
|
*/
|
|
85
|
-
export declare function computeSiteLabels(code: Int32Array, roots: Iterable<number>, hostCst: boolean
|
|
87
|
+
export declare function computeSiteLabels(code: Int32Array, roots: Iterable<number>, hostCst: boolean,
|
|
88
|
+
/** Does this assembly run this `OP_CONT` late, in EVERY engine it holds? Absent: none. */
|
|
89
|
+
late?: (ip: number, tri: number) => boolean): SiteLabels;
|
|
86
90
|
/**
|
|
87
91
|
* Does a piece entered at `ip` need the caller's INSTALLED trivia scanner handed
|
|
88
92
|
* across an engine boundary?
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-labels.d.ts","sourceRoot":"","sources":["../../src/table/site-labels.ts"],"names":[],"mappings":"AAqEA,iFAAiF;AACjF,eAAO,MAAM,WAAW,KAAK,CAAA;AAC7B,qDAAqD;AACrD,eAAO,MAAM,QAAQ,KAAK,CAAA;AAC1B,0EAA0E;AAE1E,qDAAqD;AACrD,eAAO,MAAM,WAAW,IAAI,CAAA;AAC5B,yDAAyD;AACzD,eAAO,MAAM,OAAO,IAAI,CAAA;AACxB,uDAAuD;AACvD,eAAO,MAAM,MAAM,IAAI,CAAA;AAIvB,uCAAuC;AACvC,eAAO,MAAM,WAAW,IAAI,CAAA;AAC5B,oDAAoD;AACpD,eAAO,MAAM,QAAQ,IAAI,CAAA;AAEzB,MAAM,MAAM,SAAS,GAAG;IACtB,mFAAmF;IACnF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;IACrB,kDAAkD;IAClD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,wDAAwD;AACxD,eAAO,MAAM,GAAG,EAAE,SAAgF,CAAA;AAWlG;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAarF;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAYpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAuB/I;AAqED,oEAAoE;AACpE,MAAM,MAAM,UAAU,GAAG;
|
|
1
|
+
{"version":3,"file":"site-labels.d.ts","sourceRoot":"","sources":["../../src/table/site-labels.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
* Kept in sync with `package.json` by `test/unit/version-sync.test.ts`, which fails
|
|
14
14
|
* the build if this constant drifts from the published version.
|
|
15
15
|
*/
|
|
16
|
-
export declare const PARSEMAN_VERSION = "0.61.
|
|
16
|
+
export declare const PARSEMAN_VERSION = "0.61.5";
|
|
17
17
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -122,26 +122,35 @@ export function pushCstChild(ctx: ParseContext, built: unknown, rawEntry: unknow
|
|
|
122
122
|
/**
|
|
123
123
|
* Undo the LAST `pushCstChild` into the active collector, whichever form it took:
|
|
124
124
|
* a child the lazy buffer's empty sentinel dropped (`undefined` first) leaves no
|
|
125
|
-
* semantic entry to remove, only its raw one.
|
|
125
|
+
* semantic entry to remove, only its raw one. Returns that raw entry, or `undefined`
|
|
126
|
+
* when this collector keeps none.
|
|
126
127
|
*/
|
|
127
|
-
export function popCstChild(ctx: ParseContext):
|
|
128
|
+
export function popCstChild(ctx: ParseContext): unknown {
|
|
128
129
|
const b = ctx._cstBuf
|
|
129
130
|
if (b) {
|
|
130
131
|
const ch = b.ch
|
|
131
|
-
if (b.rawOnly !== true
|
|
132
|
-
ch
|
|
133
|
-
|
|
132
|
+
if (b.rawOnly !== true) {
|
|
133
|
+
if (ch) {
|
|
134
|
+
ch.pop()
|
|
135
|
+
if (ch.length === 1) { b.single = ch[0]; b.ch = undefined }
|
|
136
|
+
} else b.single = undefined
|
|
137
|
+
}
|
|
138
|
+
if (b.noRaw === true) {
|
|
139
|
+
b.rawLen = (b.rawLen ?? 1) - 1
|
|
140
|
+
return undefined
|
|
134
141
|
}
|
|
135
|
-
if (b.
|
|
136
|
-
|
|
137
|
-
b.raw.pop()
|
|
142
|
+
if (b.raw) {
|
|
143
|
+
const entry = b.raw.pop()
|
|
138
144
|
if (b.raw.length === 1) { b.rawSingle = b.raw[0]; b.raw = undefined }
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
return entry
|
|
146
|
+
}
|
|
147
|
+
const entry = b.rawSingle
|
|
148
|
+
b.rawSingle = undefined
|
|
149
|
+
return entry
|
|
141
150
|
}
|
|
142
151
|
if (ctx._cstChildren) ctx._cstChildren.pop()
|
|
143
152
|
else if (ctx._cstLeaves) ctx._cstLeaves.pop()
|
|
144
|
-
|
|
153
|
+
return ctx._cstRawChildren?.pop()
|
|
145
154
|
}
|
|
146
155
|
|
|
147
156
|
export function cstRawLen(ctx: ParseContext): number {
|
package/src/table/assemble.ts
CHANGED
|
@@ -83,6 +83,7 @@ import {
|
|
|
83
83
|
cstCaptureActive, cstLeavesLen, cstTlLen,
|
|
84
84
|
demoteCapturedToRaw, pushCstChild, pushCstLeaf,
|
|
85
85
|
type CstCaptureBuf,
|
|
86
|
+
popCstChild,
|
|
86
87
|
} from '../cst/capture-buffer.ts'
|
|
87
88
|
import { PlainBuf, PlainField, PlainLeaf, PlainNode, PlainSpan } from '../cst/plain.js'
|
|
88
89
|
import {
|
|
@@ -91,7 +92,7 @@ import {
|
|
|
91
92
|
OP_LIT_TRACK, OP_RX_TRACK, OP_NODE_TRACK, OP_SCOPE, OP_SCOPE_CAP, OP_SCOPE_PLAIN, SCOPE_INHERIT, OP_EXPECT, OP_SEQX, OP_SCAN,
|
|
92
93
|
OP_LIVE,
|
|
93
94
|
OP_FIELD, OP_DISPATCH, OP_ROUTED, OP_LIT_CI, OP_LIT_CI_TRACK, OP_TOKEN, OP_WITHCTX, OP_GUARD, OP_ATTEMPT, OP_LABEL,
|
|
94
|
-
OP_COV, OP_GAPGATE, OP_STRICT,
|
|
95
|
+
OP_COV, OP_GAPGATE, OP_STRICT, OP_CONT, OP_SEED,
|
|
95
96
|
OP_ADJ, OP_GREEDY, OP_REJECT, OP_ARMGATE, OP_RGATE, OP_RGATE2,
|
|
96
97
|
OP_LEX_BODY, OP_LEX_PROGRAM,
|
|
97
98
|
} from './ops.ts'
|
|
@@ -110,6 +111,7 @@ import {
|
|
|
110
111
|
type EmittedAssembly, type EmittedFactory,
|
|
111
112
|
} from './emit-assembly.ts'
|
|
112
113
|
import { collapseEmpty, lead, rawEntry, spanLines } from './run-support.ts'
|
|
114
|
+
import { canDecide, continuationGate } from './late-frame.ts'
|
|
113
115
|
import { holdsGap, rowNullable } from './hold-gap.ts'
|
|
114
116
|
import { gapRows, newGapSlot } from './gap-gate.ts'
|
|
115
117
|
import { failCleanAnalysis } from './fail-clean.ts'
|
|
@@ -133,7 +135,7 @@ import {
|
|
|
133
135
|
type SubtreeRef, type TableProgram, type TableRule,
|
|
134
136
|
} from './program.ts'
|
|
135
137
|
import { stampRuleMap } from './stamp.ts'
|
|
136
|
-
import { computeSiteLabels, gatedPassCollapse, passCollapse, reachableSites, scanHandoffNeeded, scopeIsIdentity, triviaLeadRanges } from './site-labels.ts'
|
|
138
|
+
import { CAP_OFF, CAP_ON, type SiteLabel, computeSiteLabels, gatedPassCollapse, passCollapse, reachableSites, scanHandoffNeeded, scopeIsIdentity, triviaLeadRanges, TRI_NONE } from './site-labels.ts'
|
|
137
139
|
import { refuseUnclassifiedRootScope } from '../cst/root-trivia-scope.ts'
|
|
138
140
|
import { captureError, firstSetSentinel, matchesAt, orSentinel, recoverScan } from '../recovery/scan.ts'
|
|
139
141
|
import {
|
|
@@ -544,6 +546,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
544
546
|
const GAP = newGapSlot()
|
|
545
547
|
const closureLabels = computeSiteLabels(
|
|
546
548
|
code, [...Object.values(prog.rules), ...labelExtraIps], hostCst,
|
|
549
|
+
cfg.tolerant || cfg.probe ? undefined : (ip, tri) => canDecide(code, ip, tri, t.triviaScan),
|
|
547
550
|
)
|
|
548
551
|
|
|
549
552
|
/**
|
|
@@ -1177,6 +1180,41 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
1177
1180
|
return cur
|
|
1178
1181
|
}
|
|
1179
1182
|
|
|
1183
|
+
/** Whether `cls` admits the character at `at`, without a call for the ASCII answer. */
|
|
1184
|
+
function startsTail(cls: ResolvedClass, input: string, at: number): boolean {
|
|
1185
|
+
const c = input.charCodeAt(at)
|
|
1186
|
+
return c < 128 ? cls.ascii[c] === 1 : classHas(cls, lead(input, at))
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
/**
|
|
1190
|
+
* The tail of a late frame. The gap was scanned to decide, so with no gap there is
|
|
1191
|
+
* nothing to record or undo, and with nothing recording it is not scanned again.
|
|
1192
|
+
*/
|
|
1193
|
+
function lateTail(tail: Piece, input: string, end: number, at: number, ctx: ParseContext, frame: SiteLabel): unknown {
|
|
1194
|
+
if (at === end) return tail(input, end, ctx)
|
|
1195
|
+
if (ctx._triviaLog === undefined && ctx._rootTriviaLog === undefined
|
|
1196
|
+
&& (frame.cap === CAP_OFF || !((frame.cap === CAP_ON || ctx.captureTrivia === true)
|
|
1197
|
+
&& (frame.buf || ctx._cstBuf !== undefined || ctx._cstTriviaLog !== undefined)))) {
|
|
1198
|
+
const v = tail(input, at, ctx)
|
|
1199
|
+
if (v !== FAIL && EC.e <= at) EC.e = end
|
|
1200
|
+
return v
|
|
1201
|
+
}
|
|
1202
|
+
const need = rollbackNeeded(ctx)
|
|
1203
|
+
const mTl = need ? cstTlLen(ctx) : 0
|
|
1204
|
+
const mLog = need ? ctx._triviaLog?.length ?? 0 : 0
|
|
1205
|
+
const mRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0
|
|
1206
|
+
const scanEnd = skipTrivia(input, end, ctx)
|
|
1207
|
+
const scanTl = need ? cstTlLen(ctx) : 0
|
|
1208
|
+
const scanLog = need ? ctx._triviaLog?.length ?? 0 : 0
|
|
1209
|
+
const scanRoot = need ? ctx._rootTriviaLog?.length ?? 0 : 0
|
|
1210
|
+
const v = tail(input, scanEnd, ctx)
|
|
1211
|
+
if (v !== FAIL && EC.e <= scanEnd) {
|
|
1212
|
+
if (need) rollbackScannedTriviaAt(ctx, mTl, scanTl, mLog, scanLog, mRoot, scanRoot)
|
|
1213
|
+
EC.e = end
|
|
1214
|
+
}
|
|
1215
|
+
return v
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1180
1218
|
/** A non-first term at a site proven to run under an open node capture buffer. */
|
|
1181
1219
|
function nextTermBuffered(child: Piece, input: string, cur: number, ctx: ParseContext): number {
|
|
1182
1220
|
const t = ctx.trivia
|
|
@@ -1846,6 +1884,88 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
1846
1884
|
case OP_EMPTY:
|
|
1847
1885
|
return (_input, pos) => { EC.e = pos; return '' }
|
|
1848
1886
|
|
|
1887
|
+
case OP_SEED:
|
|
1888
|
+
return link(code[ip + 1]!)
|
|
1889
|
+
|
|
1890
|
+
case OP_CONT: {
|
|
1891
|
+
const wrapper = code[ip + 2]!
|
|
1892
|
+
if (!closureLabels.late.has(ip)) return lower(wrapper)
|
|
1893
|
+
const corner = link(code[ip + 1]!)
|
|
1894
|
+
const tail = link(code[ip + 3]!)
|
|
1895
|
+
const g = continuationGate(code, code[ip + 3]!)!
|
|
1896
|
+
const tri = closureLabels.at(ip).tri
|
|
1897
|
+
// The gap the tail would start past, read without recording anything: no scan
|
|
1898
|
+
// at a character no trivia can start.
|
|
1899
|
+
const scan = tri === TRI_NONE ? undefined : t.triviaScan[tri]!
|
|
1900
|
+
const leads = tri === TRI_NONE ? null : LEAD_TABLES[tri]!
|
|
1901
|
+
const cls = cc[g.cls]!
|
|
1902
|
+
const gapRe = g.gapRow < 0 ? undefined : k[code[g.gapRow + 1]!] as RegExp
|
|
1903
|
+
const follow = g.follow < 0 ? undefined : cc[g.follow]!
|
|
1904
|
+
const other = g.other < 0 ? undefined : cc[g.other]!
|
|
1905
|
+
const mayStartPastGap = (input: string, at: number): boolean => {
|
|
1906
|
+
gapRe!.lastIndex = at
|
|
1907
|
+
const q = gapRe!.test(input) ? gapRe!.lastIndex : -1
|
|
1908
|
+
return (q >= 0 && classHas(follow!, lead(input, q))) || (other !== undefined && classHas(other, lead(input, at)))
|
|
1909
|
+
}
|
|
1910
|
+
const frame = closureLabels.at(code[wrapper + 2]!)
|
|
1911
|
+
const flags = code[wrapper + 3]!
|
|
1912
|
+
const buildIdx = code[wrapper + 1]!
|
|
1913
|
+
// The seed for this frame, handed over before anything can parse.
|
|
1914
|
+
let held: unknown
|
|
1915
|
+
let heldRaw: unknown
|
|
1916
|
+
let heldEnd = 0
|
|
1917
|
+
let heldAt = 0
|
|
1918
|
+
const omitsRaw = !hostCst && buildIdx >= 0 && code[wrapper + 4]! < 0 && (flags & 2) !== 0
|
|
1919
|
+
const body: Piece = omitsRaw
|
|
1920
|
+
? (input, _pos, ctx) => {
|
|
1921
|
+
const b = ctx._cstBuf
|
|
1922
|
+
if (b !== undefined) {
|
|
1923
|
+
b.single = held
|
|
1924
|
+
b.rawLen = 1
|
|
1925
|
+
} else ctx._cstChildren!.push(held)
|
|
1926
|
+
held = undefined
|
|
1927
|
+
heldRaw = undefined
|
|
1928
|
+
return lateTail(tail, input, heldEnd, heldAt, ctx, frame)
|
|
1929
|
+
}
|
|
1930
|
+
: (input, pos, ctx) => {
|
|
1931
|
+
const b = ctx._cstBuf
|
|
1932
|
+
if (b !== undefined) {
|
|
1933
|
+
b.single = held
|
|
1934
|
+
b.rawSingle = heldRaw ?? rawEntry(held, input, pos, heldEnd)
|
|
1935
|
+
} else ctx._cstChildren!.push(held)
|
|
1936
|
+
held = undefined
|
|
1937
|
+
heldRaw = undefined
|
|
1938
|
+
return lateTail(tail, input, heldEnd, heldAt, ctx, frame)
|
|
1939
|
+
}
|
|
1940
|
+
let open: Piece
|
|
1941
|
+
// An AST reducer: the frame is one of the two lean bodies. Any other frame is
|
|
1942
|
+
// the node's own closure, with `body` for its child.
|
|
1943
|
+
if (!hostCst && !cfg.trackLines && code[wrapper] === OP_NODE && code[wrapper + 4]! < 0 && (flags === 32 || flags === 34)) {
|
|
1944
|
+
const build = fns[buildIdx] as NodeBuilder
|
|
1945
|
+
open = flags === 34 ? childrenOnlyCollapseBuildNode(body, build) : collapseBuildNode(body, build)
|
|
1946
|
+
} else {
|
|
1947
|
+
NODE_BODY = body
|
|
1948
|
+
open = lower(wrapper)
|
|
1949
|
+
}
|
|
1950
|
+
return (input, pos, ctx) => {
|
|
1951
|
+
const v = corner(input, pos, ctx)
|
|
1952
|
+
if (v === FAIL) return FAIL
|
|
1953
|
+
const end = EC.e
|
|
1954
|
+
let at = end
|
|
1955
|
+
if (scan !== undefined) {
|
|
1956
|
+
const c = input.charCodeAt(end)
|
|
1957
|
+
if (leads === null || !(c < 128) || leads[c] !== 0) at = scan(input, end)
|
|
1958
|
+
}
|
|
1959
|
+
if (v !== undefined && !(gapRe === undefined ? startsTail(cls, input, at) : mayStartPastGap(input, at))) return v
|
|
1960
|
+
if (ctx._cstBuf === undefined && ctx._cstRawChildren === undefined && ctx._cstChildren !== undefined) ctx._cstChildren.pop()
|
|
1961
|
+
else if (ctx._cstBuf !== undefined || ctx._cstChildren !== undefined) heldRaw = popCstChild(ctx)
|
|
1962
|
+
held = v
|
|
1963
|
+
heldEnd = end
|
|
1964
|
+
heldAt = at
|
|
1965
|
+
return open(input, pos, ctx)
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1849
1969
|
/* ── transparent / structural ────────────────────────────────────────── */
|
|
1850
1970
|
|
|
1851
1971
|
case OP_GUARD: {
|
|
@@ -4290,7 +4410,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
4290
4410
|
matchesAt, recoverScan, orSentinel, captureError,
|
|
4291
4411
|
scalarRecognizers, t.lex, adjacencyHolds, t.lexPrograms,
|
|
4292
4412
|
LEAD, triviaFieldCapture, skipDeferredTrivia,
|
|
4293
|
-
collapseEmpty,
|
|
4413
|
+
collapseEmpty, popCstChild,
|
|
4294
4414
|
PlainSpan, PlainLeaf, PlainNode, PlainField, PlainBuf, GAP,
|
|
4295
4415
|
)
|
|
4296
4416
|
emitReached = new Set(pre.reached)
|
|
@@ -4375,7 +4495,7 @@ export function assemble(t: ResolvedTable, prog: TableProgram, cfg: RunCfg): Ass
|
|
|
4375
4495
|
matchesAt, recoverScan, orSentinel, captureError,
|
|
4376
4496
|
scalarRecognizers, t.lex, adjacencyHolds, t.lexPrograms,
|
|
4377
4497
|
LEAD, triviaFieldCapture, skipDeferredTrivia,
|
|
4378
|
-
collapseEmpty,
|
|
4498
|
+
collapseEmpty, popCstChild,
|
|
4379
4499
|
PlainSpan, PlainLeaf, PlainNode, PlainField, PlainBuf, GAP,
|
|
4380
4500
|
)
|
|
4381
4501
|
emitReached = em.reached
|
package/src/table/child-slots.ts
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
OP_LIT_CI_TRACK, OP_LIT_TRACK, OP_LIVE, OP_NODE, OP_NODE_TRACK, OP_NOT, OP_OPT,
|
|
5
5
|
OP_PEEK, OP_REJECT, OP_REP, OP_REPV, OP_ROUTED, OP_RULE, OP_RX, OP_RX_TRACK, OP_SCAN,
|
|
6
6
|
OP_SCOPE, OP_SCOPE_CAP, OP_SCOPE_PLAIN, OP_SEQ, OP_SEQV, OP_SEQX, OP_TOKEN, OP_WITHCTX, OP_XFORM,
|
|
7
|
-
OP_LEX_BODY, OP_LEX_PROGRAM, OP_GAPGATE, OP_RGATE2, OP_STRICT,
|
|
7
|
+
OP_LEX_BODY, OP_LEX_PROGRAM, OP_GAPGATE, OP_RGATE2, OP_STRICT, OP_CONT, OP_SEED,
|
|
8
8
|
} from './ops.ts'
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -73,6 +73,14 @@ export function childSlotOffsets(code: ArrayLike<number>, ip: number, out: numbe
|
|
|
73
73
|
out.push(ip + 2)
|
|
74
74
|
return true
|
|
75
75
|
|
|
76
|
+
// `CONT corner wrapper tail`: `tail` is reached through `wrapper`.
|
|
77
|
+
case OP_CONT:
|
|
78
|
+
out.push(ip + 1, ip + 2)
|
|
79
|
+
return true
|
|
80
|
+
case OP_SEED:
|
|
81
|
+
out.push(ip + 1)
|
|
82
|
+
return true
|
|
83
|
+
|
|
76
84
|
// `STRICT strict tolerant` — both encodings are reachable; an assembly keeps one.
|
|
77
85
|
case OP_STRICT:
|
|
78
86
|
out.push(ip + 1, ip + 2)
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
OP_LABEL, OP_LEAF, OP_SOURCE_LEAF, OP_LIT, OP_LIT_CI, OP_LIT_CI_TRACK, OP_LIT_TRACK, OP_NAMES,
|
|
52
52
|
OP_NODE, OP_NODE_TRACK, OP_NOT, OP_OPT, OP_PEEK, OP_REP, OP_REPV, OP_ROUTED, OP_RULE, OP_RX,
|
|
53
53
|
OP_RX_TRACK, OP_SCAN, OP_SCOPE, OP_SCOPE_CAP, OP_SCOPE_PLAIN, SCOPE_INHERIT, OP_SEQ, OP_SEQV, OP_SEQX, OP_TOKEN, OP_WITHCTX, OP_XFORM,
|
|
54
|
-
OP_LEX_BODY, OP_LEX_PROGRAM, OP_GAPGATE, OP_STRICT,
|
|
54
|
+
OP_LEX_BODY, OP_LEX_PROGRAM, OP_GAPGATE, OP_STRICT, OP_CONT, OP_SEED,
|
|
55
55
|
} from './ops.ts'
|
|
56
56
|
import {
|
|
57
57
|
choiceCannotCommit, choiceLogRollbackMask, choiceRollbackMask, failureLogRollback, failureRollbackClean, validateDispatchSpec,
|
|
@@ -67,6 +67,7 @@ import {
|
|
|
67
67
|
scalarTerminalNodeChild, scalarTerminalNotChild, scalarTerminalPeekChild, type LeadingScalarSequence,
|
|
68
68
|
} from './scalar-terminal.ts'
|
|
69
69
|
import { childSlots } from './child-slots.ts'
|
|
70
|
+
import { canDecide, continuationGate } from './late-frame.ts'
|
|
70
71
|
import { holdsGap, rowNullable } from './hold-gap.ts'
|
|
71
72
|
import { gapRows } from './gap-gate.ts'
|
|
72
73
|
import { fieldSpec, leadingTriviaFieldAt } from './field-spec.ts'
|
|
@@ -139,7 +140,7 @@ export const EMITTED_PARAMS = [
|
|
|
139
140
|
// The deferred-commit trivia skip (`trivia-gap.ts`).
|
|
140
141
|
'skipDeferredTrivia',
|
|
141
142
|
// The pass-through collapse (`run-support.ts`).
|
|
142
|
-
'collapseEmpty',
|
|
143
|
+
'collapseEmpty', 'popCstChild',
|
|
143
144
|
// Constructor-built tree objects (`cst/plain.d.ts`): a `new` call has no
|
|
144
145
|
// allocation site, so V8 cannot pretenure them.
|
|
145
146
|
'_SP', '_LF', '_ND', '_FC', '_BUF',
|
|
@@ -674,7 +675,8 @@ export function emitAssemblySource(
|
|
|
674
675
|
// less than reading the slot costs; only a gap matched by its RegExp takes the
|
|
675
676
|
// slot (`gapRegexLowers`).
|
|
676
677
|
const GAP_ROWS = gapNeutral ? new Set<number>() : new Set([...gapRows(code, roots)].filter(row => !gapRegexLowers(k[code[row + 1]!])))
|
|
677
|
-
const labels = computeSiteLabels(code, roots, hostCst
|
|
678
|
+
const labels = computeSiteLabels(code, roots, hostCst,
|
|
679
|
+
cfg.tolerant || cfg.probe ? undefined : (ip, tri) => canDecide(code, ip, tri, t.triviaScan))
|
|
678
680
|
// Eligibility is pooled by the terminal's existing constant operand, matching
|
|
679
681
|
// the closure recognizer pool: distinct terminal rows sharing one spec share
|
|
680
682
|
// both the recognizer and the ordinary-terminal lowering.
|
|
@@ -1037,6 +1039,17 @@ return 1
|
|
|
1037
1039
|
return c => `${c}<55296&&!(${leads.map(r => r.lo === r.hi ? `${c}===${r.lo}` : `(${c}>=${r.lo}&&${c}<=${r.hi})`).join('||')})`
|
|
1038
1040
|
}
|
|
1039
1041
|
|
|
1042
|
+
/** `ctx.captureTrivia === true && (a sink is open)`, as far as the label resolves it. */
|
|
1043
|
+
function skipCapturing(l: SiteLabel): string {
|
|
1044
|
+
if (l.tri < 0 || !swapLegal || triviaLabelled[l.tri]! || t.triviaScan[l.tri] == null) return 'true'
|
|
1045
|
+
return capturesHere(l)
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
function capturesHere(l: SiteLabel): string {
|
|
1049
|
+
const sink = l.buf ? 'true' : '(ctx._cstBuf!==undefined||ctx._cstTriviaLog!==undefined)'
|
|
1050
|
+
return l.cap === CAP_OFF ? 'false' : l.cap === CAP_ON ? sink : `(ctx.captureTrivia===true&&${sink})`
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1040
1053
|
function skipFor(l: SiteLabel): string {
|
|
1041
1054
|
if (l.tri < 0) return '_skipTrivia'
|
|
1042
1055
|
const ki = l.tri
|
|
@@ -1205,6 +1218,8 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)\n` : ''}return FAIL
|
|
|
1205
1218
|
if (op === OP_GATE && (cfg.tolerant || cfg.probe)) return code[ip + 2]!
|
|
1206
1219
|
if (op === OP_RULE || op === OP_GAPGATE) return code[ip + 1]!
|
|
1207
1220
|
if (op === OP_STRICT) return code[cfg.tolerant || cfg.probe ? ip + 2 : ip + 1]!
|
|
1221
|
+
if (op === OP_CONT && !labels.late.has(ip)) return code[ip + 2]!
|
|
1222
|
+
if (op === OP_SEED) return code[ip + 1]!
|
|
1208
1223
|
// A SCOPE THAT INSTALLS WHAT IS ALREADY INSTALLED. `encode.ts:520` wraps
|
|
1209
1224
|
// EVERY rule of a `rules({ trivia }, …)` map in its own `OP_SCOPE_PLAIN`, so a
|
|
1210
1225
|
// grammar with one ambient trivia re-installs the same slot at every rule
|
|
@@ -1220,6 +1235,9 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)\n` : ''}return FAIL
|
|
|
1220
1235
|
return undefined
|
|
1221
1236
|
}
|
|
1222
1237
|
|
|
1238
|
+
/** Set by `OP_CONT` for the `OP_NODE` it lowers in its own function. */
|
|
1239
|
+
let LATE: { prefix: string; body: string } | undefined
|
|
1240
|
+
|
|
1223
1241
|
function lower(ip: number, fname: string): string {
|
|
1224
1242
|
const op = code[ip]
|
|
1225
1243
|
const head = `function ${fname}(input,pos,ctx){`
|
|
@@ -1428,6 +1446,70 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)\n` : ''}return FAIL
|
|
|
1428
1446
|
// hand-built-program idiom this file's driver tests use.
|
|
1429
1447
|
return `${head}EC.e=pos;return ''}`
|
|
1430
1448
|
|
|
1449
|
+
case OP_CONT: {
|
|
1450
|
+
const tri = L.tri
|
|
1451
|
+
const g = continuationGate(code, code[ip + 3]!)!
|
|
1452
|
+
const missAt = (idx: number, at: string): string => {
|
|
1453
|
+
const resolved = t.cc[idx]!
|
|
1454
|
+
const ci = classes.push([resolved]) - 1
|
|
1455
|
+
classPlan.push([idx])
|
|
1456
|
+
const ref = hoist('cg', `CLS[${ci}][0]`)
|
|
1457
|
+
return isAsciiOnlyClass(resolved) ? `${ref}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${ref},lead(input,${at}))`
|
|
1458
|
+
}
|
|
1459
|
+
// The gap the tail would start past, read without recording anything: no scan
|
|
1460
|
+
// at a character no trivia can start.
|
|
1461
|
+
let scanned = ''
|
|
1462
|
+
if (tri >= 0) {
|
|
1463
|
+
const scan = hoist('cs', `TRIVIASCAN[${tri}]`)
|
|
1464
|
+
const miss = triviaMiss(tri)
|
|
1465
|
+
scanned = miss === undefined
|
|
1466
|
+
? `const q0=${scan}(input,c1)\n`
|
|
1467
|
+
: `const cc=input.charCodeAt(c1)\nconst q0=${miss('cc')}?c1:${scan}(input,c1)\n`
|
|
1468
|
+
}
|
|
1469
|
+
const at = tri >= 0 ? 'q0' : 'c1'
|
|
1470
|
+
let test: string
|
|
1471
|
+
if (g.gapRow < 0) test = `if(c0!==undefined&&${missAt(g.cls, at)})return c0\n`
|
|
1472
|
+
else {
|
|
1473
|
+
const re = hoist('cr', `K[${code[g.gapRow + 1]!}]`)
|
|
1474
|
+
const other = g.other >= 0 ? missAt(g.other, at) : 'true'
|
|
1475
|
+
test = `${re}.lastIndex=${at}\nconst gq=${re}.test(input)?${re}.lastIndex:-1\nif(c0!==undefined&&(gq<0||${missAt(g.follow, 'gq')})&&${other})return c0\n`
|
|
1476
|
+
}
|
|
1477
|
+
const seq = code[code[ip + 2]! + 2]!
|
|
1478
|
+
const seqLabel = labels.at(seq)
|
|
1479
|
+
const tail = link(code[ip + 3]!)
|
|
1480
|
+
const recorded = tri === TRI_NONE ? '' : `const tl0=ctx._cstBuf!==undefined?(ctx._cstBuf.tl!==undefined?ctx._cstBuf.tl.length:0):(ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0)
|
|
1481
|
+
const lg0=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
1482
|
+
const rt0=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0
|
|
1483
|
+
const s0=${skipFor(seqLabel)}(input,c1,ctx)
|
|
1484
|
+
const tl1=ctx._cstBuf!==undefined?(ctx._cstBuf.tl!==undefined?ctx._cstBuf.tl.length:0):(ctx._cstTriviaLog!==undefined?ctx._cstTriviaLog.length:0)
|
|
1485
|
+
const lg1=ctx._triviaLog!==undefined?ctx._triviaLog.length:0
|
|
1486
|
+
const rt1=ctx._rootTriviaLog!==undefined?ctx._rootTriviaLog.length:0
|
|
1487
|
+
v=${tail}(input,s0,ctx)
|
|
1488
|
+
if(v!==FAIL&&EC.e<=s0){rollbackScannedTriviaAt(ctx,tl0,tl1,lg0,lg1,rt0,rt1);EC.e=c1}`
|
|
1489
|
+
const quiet = `v=${tail}(input,${at},ctx)
|
|
1490
|
+
if(v!==FAIL&&EC.e<=${at})EC.e=c1`
|
|
1491
|
+
const capture = capturesHere(seqLabel)
|
|
1492
|
+
// No gap: nothing to record, keep or take back. Nothing recording: not scanned again.
|
|
1493
|
+
const body = `let v
|
|
1494
|
+
${tri === TRI_NONE ? `v=${tail}(input,c1,ctx)`
|
|
1495
|
+
: `if(q0===c1)v=${tail}(input,c1,ctx)
|
|
1496
|
+
else ${capture === 'true' ? `{\n${recorded}\n}`
|
|
1497
|
+
: `if(ctx._triviaLog===undefined&&ctx._rootTriviaLog===undefined${capture === 'false' ? '' : `&&!${capture}`}){
|
|
1498
|
+
${quiet}
|
|
1499
|
+
}else{
|
|
1500
|
+
${recorded}
|
|
1501
|
+
}`}`}`
|
|
1502
|
+
const wrapperIp = code[ip + 2]!
|
|
1503
|
+
LATE = {
|
|
1504
|
+
prefix: `const c0=${link(code[ip + 1]!)}(input,pos,ctx)
|
|
1505
|
+
if(c0===FAIL)return FAIL
|
|
1506
|
+
const c1=EC.e
|
|
1507
|
+
${scanned}${test}`,
|
|
1508
|
+
body,
|
|
1509
|
+
}
|
|
1510
|
+
return lower(wrapperIp, fname)
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1431
1513
|
case OP_GATE: {
|
|
1432
1514
|
const child = link(code[ip + 2]!)
|
|
1433
1515
|
const xf = fxRef(code[ip + 3]!)
|
|
@@ -2661,7 +2743,9 @@ return out
|
|
|
2661
2743
|
case OP_NODE:
|
|
2662
2744
|
case OP_NODE_TRACK: {
|
|
2663
2745
|
const flags = code[ip + 3]!
|
|
2664
|
-
const
|
|
2746
|
+
const late = LATE
|
|
2747
|
+
LATE = undefined
|
|
2748
|
+
const scalarChild = late === undefined ? scalarTerminalNodeChild(code, ip) : -1
|
|
2665
2749
|
if (scalarChild >= 0 && scalarSpecs.has(code[scalarChild + 1]!)) {
|
|
2666
2750
|
const recognize = recognizerRef(code[scalarChild + 1]!)
|
|
2667
2751
|
const spec = code[scalarChild] === OP_RX ? null : k[code[scalarChild + 1]!] as string
|
|
@@ -2687,7 +2771,9 @@ EC.e=end
|
|
|
2687
2771
|
return nd
|
|
2688
2772
|
}`
|
|
2689
2773
|
}
|
|
2690
|
-
const child = link(code[ip + 2]!)
|
|
2774
|
+
const child = late === undefined ? link(code[ip + 2]!) : ''
|
|
2775
|
+
const runBody = late === undefined ? `const v=${child}(input,pos,ctx)` : late.body
|
|
2776
|
+
const takeBack = late === undefined ? '' : 'let c0Raw\nif(sBuf===undefined&&sRaw===undefined&&sCh!==undefined)sCh.pop()\nelse if(sBuf!==undefined||sCh!==undefined)c0Raw=popCstChild(ctx)\n'
|
|
2691
2777
|
const proj = code[ip + 4]!
|
|
2692
2778
|
const buildIdx = code[ip + 1]!
|
|
2693
2779
|
const type = k[code[ip + 5]!] as string
|
|
@@ -2714,7 +2800,7 @@ return nd
|
|
|
2714
2800
|
// THE PASS-THROUGH COLLAPSE (`run-support.ts` `collapseEmpty`): a
|
|
2715
2801
|
// collapse over one node is that node. `passCollapse` is the closure
|
|
2716
2802
|
// engine's test too.
|
|
2717
|
-
if (build !== undefined && passCollapse(code, ip, hostCst)) {
|
|
2803
|
+
if (late === undefined && build !== undefined && passCollapse(code, ip, hostCst)) {
|
|
2718
2804
|
return `${head}
|
|
2719
2805
|
const v=${child}(input,pos,ctx)
|
|
2720
2806
|
if(v!==undefined)return v
|
|
@@ -2725,7 +2811,7 @@ return collapseEmpty(ctx,${build},input,pos,EC.e,${flags === 32})
|
|
|
2725
2811
|
// character at `pos` opens none of the body's optional terms and no
|
|
2726
2812
|
// trivia, the body is its node term, run as a pass-through collapse.
|
|
2727
2813
|
// Not under recovery or a probe: there a gated-out term still runs.
|
|
2728
|
-
const gated = build !== undefined && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : undefined
|
|
2814
|
+
const gated = late === undefined && build !== undefined && !cfg.tolerant && !cfg.probe ? gatedPassCollapse(code, ip, hostCst) : undefined
|
|
2729
2815
|
const triviaLead = gated === undefined ? undefined : triviaLeadRanges(labels.at(code[ip + 2]!).tri, t.trivia)
|
|
2730
2816
|
const gp = gated !== undefined && triviaLead !== undefined && triviaLead.length <= 16
|
|
2731
2817
|
? `const gc=lead(input,pos)
|
|
@@ -2777,9 +2863,9 @@ sCh.push(nd)
|
|
|
2777
2863
|
if(sRaw!==undefined)sRaw.push(rawEntry(nd,input,pos,end))
|
|
2778
2864
|
}`
|
|
2779
2865
|
return `${head}
|
|
2780
|
-
${gp}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
2866
|
+
${late?.prefix ?? ''}${gp}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
2781
2867
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf,sFields=ctx._fields
|
|
2782
|
-
const flat
|
|
2868
|
+
${takeBack}const flat=${late === undefined ? '[]' : '[c0]'}
|
|
2783
2869
|
ctx._cstBuf=undefined
|
|
2784
2870
|
ctx._cstChildren=flat
|
|
2785
2871
|
ctx._cstLeaves=flat
|
|
@@ -2787,7 +2873,7 @@ ctx._cstRawChildren=undefined
|
|
|
2787
2873
|
ctx._cstTriviaLog=undefined
|
|
2788
2874
|
ctx.captureTrivia=false
|
|
2789
2875
|
ctx._fields=${fields ? '[]' : 'undefined'}
|
|
2790
|
-
|
|
2876
|
+
${runBody}
|
|
2791
2877
|
${trailingTrivia && L.tri !== TRI_NONE
|
|
2792
2878
|
? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? '&&ctx.trivia!==undefined' : ''})EC.e=consumeTrivia(input,EC.e,ctx)\n`
|
|
2793
2879
|
: ''}const captured=_capturedFlatChildren(flat)
|
|
@@ -2871,16 +2957,17 @@ const tlog=buf.tl??EMPTY_TLOG`
|
|
|
2871
2957
|
const hostKids=kids
|
|
2872
2958
|
const rawKids=buf.raw??(buf.rawSingle!==undefined?[buf.rawSingle]:EMPTY_CH)
|
|
2873
2959
|
const tlog=buf.tl??EMPTY_TLOG`
|
|
2960
|
+
const seedCapture = late === undefined ? '' : omitsRaw ? 'buf.single=c0\nbuf.rawLen=1\n' : 'buf.single=c0\nbuf.rawSingle=c0Raw!==undefined?c0Raw:rawEntry(c0,input,pos,c1)\n'
|
|
2874
2961
|
return `${head}
|
|
2875
|
-
${!hostCst && !tracked ? gp : ''}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
2962
|
+
${late?.prefix ?? ''}${!hostCst && !tracked ? gp : ''}const sCh=ctx._cstChildren,sLv=ctx._cstLeaves,sRaw=ctx._cstRawChildren,sTl=ctx._cstTriviaLog
|
|
2876
2963
|
const sCap=ctx.captureTrivia,sBuf=ctx._cstBuf
|
|
2877
|
-
${openCapture}
|
|
2878
|
-
ctx.captureTrivia=${captureWide}
|
|
2964
|
+
${takeBack}${openCapture}
|
|
2965
|
+
${seedCapture}ctx.captureTrivia=${captureWide}
|
|
2879
2966
|
const savedFields=ctx._fields
|
|
2880
2967
|
ctx._fields=${wantFields ? '[]' : 'undefined'}
|
|
2881
2968
|
${structural ? `const savedMask=ctx._triviaCaptureMask
|
|
2882
2969
|
if(_pfHost!==undefined&&_pfHost._parsemanTriviaKinds!==undefined)ctx._triviaCaptureMask=_pfHost._parsemanTriviaKinds(${ty})
|
|
2883
|
-
` : ''}
|
|
2970
|
+
` : ''}${runBody}
|
|
2884
2971
|
${trailingTrivia && L.tri !== TRI_NONE
|
|
2885
2972
|
? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? '&&ctx.trivia!==undefined' : ''})EC.e=consumeTrivia(input,EC.e,ctx)\n`
|
|
2886
2973
|
: ''}const fieldMap=${wantFields ? 'buildFieldMap(ctx._fields)' : 'undefined'}
|