parseman 0.57.0 → 0.58.1
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 +1800 -962
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +1929 -1091
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts +11 -1
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +69 -16
- package/dist/compiler/token-capability.js.map +2 -2
- package/dist/cst/capture-buffer.d.ts +6 -0
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/index.js +1017 -177
- package/dist/index.js.map +3 -3
- package/dist/plugin/index.d.ts +25 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1210 -236
- package/dist/plugin/index.js.map +3 -3
- package/dist/run/index.d.ts +2 -0
- package/dist/run/index.d.ts.map +1 -1
- package/dist/run/index.js +9 -0
- package/dist/run/index.js.map +1 -1
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/compile-rule-map.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/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/factor-choice.d.ts +42 -0
- package/dist/table/factor-choice.d.ts.map +1 -0
- package/dist/table/fail-clean.d.ts +3 -0
- package/dist/table/fail-clean.d.ts.map +1 -0
- package/dist/table/hold-gap.d.ts +8 -0
- package/dist/table/hold-gap.d.ts.map +1 -0
- package/dist/table/index.js +1370 -259
- package/dist/table/index.js.map +3 -3
- package/dist/table/lex-program.d.ts +7 -3
- package/dist/table/lex-program.d.ts.map +1 -1
- package/dist/table/ops.d.ts +8 -0
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/run-support.d.ts +19 -0
- package/dist/table/run-support.d.ts.map +1 -1
- package/dist/table/scalar-terminal.d.ts +2 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -1
- package/dist/table/site-labels.d.ts +66 -0
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/combinators/dispatch.ts +12 -3
- package/src/compiler/token-alphabet.ts +57 -17
- package/src/cst/capture-buffer.ts +25 -0
- package/src/plugin/index.ts +230 -35
- package/src/run/index.ts +5 -0
- package/src/table/assemble.ts +252 -62
- package/src/table/child-slots.ts +2 -2
- package/src/table/compile-rule-map.ts +14 -5
- package/src/table/emit-assembly.ts +112 -23
- package/src/table/emit.ts +3 -1
- package/src/table/encode.ts +83 -14
- package/src/table/exec.ts +27 -8
- package/src/table/factor-choice.ts +173 -0
- package/src/table/fail-clean.ts +130 -0
- package/src/table/hold-gap.ts +68 -0
- package/src/table/lex-program.ts +197 -43
- package/src/table/ops.ts +9 -1
- package/src/table/run-support.ts +35 -0
- package/src/table/scalar-terminal.ts +8 -0
- package/src/table/site-labels.ts +135 -4
- package/src/version.ts +1 -1
|
@@ -13,11 +13,15 @@ export declare const LEX_NODE_SEQUENCE2 = 1;
|
|
|
13
13
|
export declare const LEX_NODE_SEQUENCE3 = 2;
|
|
14
14
|
export declare const LEX_NODE_SEQUENCE4 = 3;
|
|
15
15
|
export declare const LEX_NODE_SEQUENCE5 = 4;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
/**
|
|
17
|
+
* `[op, armCount, exclusive, choiceFx, (armClass, armFx) × armCount]`: any arity,
|
|
18
|
+
* no padding. `exclusive` is the character choice's one-arm dispatch decision.
|
|
19
|
+
*/
|
|
20
|
+
export declare const LEX_NODE_CHOICE = 5;
|
|
19
21
|
export declare const LEX_NODE_NOT = 8;
|
|
20
22
|
export declare const LEX_NODE_OPTIONAL = 9;
|
|
23
|
+
/** `[op, min, max]` after the item: a separator-less repeat, `max` −1 unbounded. */
|
|
24
|
+
export declare const LEX_NODE_REPEAT = 10;
|
|
21
25
|
export declare function lexProgramDigest(words: readonly number[]): number;
|
|
22
26
|
/** Decode one fixed selected-body tuple. There is no lexical opcode loop on
|
|
23
27
|
* the parse path: each supported tuple becomes one scalar closure here. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lex-program.d.ts","sourceRoot":"","sources":["../../src/table/lex-program.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"lex-program.d.ts","sourceRoot":"","sources":["../../src/table/lex-program.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAEjE;;0EAE0E;AAC1E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM,CAAA;IACnF,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,eAAO,MAAM,iBAAiB,IAAI,CAAA;AAClC,eAAO,MAAM,kBAAkB,IAAI,CAAA;AACnC,eAAO,MAAM,kBAAkB,IAAI,CAAA;AACnC,eAAO,MAAM,kBAAkB,IAAI,CAAA;AACnC,eAAO,MAAM,kBAAkB,IAAI,CAAA;AACnC;;;GAGG;AACH,eAAO,MAAM,eAAe,IAAI,CAAA;AAChC,eAAO,MAAM,YAAY,IAAI,CAAA;AAC7B,eAAO,MAAM,iBAAiB,IAAI,CAAA;AAClC,oFAAoF;AACpF,eAAO,MAAM,eAAe,KAAK,CAAA;AAEjC,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAOjE;AAoaD;2EAC2E;AAC3E,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,cAAc,EACpB,QAAQ,EAAE,SAAS,iBAAiB,EAAE,EACtC,OAAO,EAAE,SAAS,aAAa,EAAE,EACjC,QAAQ,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,GACvC,gBAAgB,CAyHlB"}
|
package/dist/table/ops.d.ts
CHANGED
|
@@ -477,6 +477,14 @@ export declare const OP_LEX_BODY = 42;
|
|
|
477
477
|
export declare const OP_LEX_PROGRAM = 43;
|
|
478
478
|
/** `SOURCE_LEAF f c` — `sourceLeaf()`: reduce semantically, capture source text. */
|
|
479
479
|
export declare const OP_SOURCE_LEAF = 44;
|
|
480
|
+
/**
|
|
481
|
+
* `RGATE cls child fx` — a choice arm that opens with the token its `dispatch()`
|
|
482
|
+
* already routed. `cls` is what may follow that token (the arm's next term,
|
|
483
|
+
* with the sequence's trivia), tested at the routed token's END; a miss fails
|
|
484
|
+
* there with the next term's set `fx`, as running the arm would. No routed token
|
|
485
|
+
* at this position, a completions probe, or tolerant recovery enters the arm.
|
|
486
|
+
*/
|
|
487
|
+
export declare const OP_RGATE = 45;
|
|
480
488
|
/**
|
|
481
489
|
* `DISPATCH sel d other otherRouted n a1 … an` — `dispatch()`.
|
|
482
490
|
*
|
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":"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"}
|
|
1
|
+
{"version":3,"file":"ops.d.ts","sourceRoot":"","sources":["../../src/table/ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,4 +35,23 @@ export declare function spanLines(ctx: ParseContext, start: number, end: number)
|
|
|
35
35
|
export declare function rawEntry(v: unknown, input: string, s: number, e: number): unknown;
|
|
36
36
|
/** `input`'s code point at `pos`, or −1 at EOF. Surrogate-pair aware. */
|
|
37
37
|
export declare function lead(input: string, pos: number): number;
|
|
38
|
+
type CollapseBuild = (children: readonly unknown[], fields: undefined, span: {
|
|
39
|
+
start: number;
|
|
40
|
+
end: number;
|
|
41
|
+
}, rawChildren: readonly unknown[], triviaLog: readonly number[], state: undefined) => unknown;
|
|
42
|
+
/**
|
|
43
|
+
* A PASS-THROUGH COLLAPSE whose one child built `undefined` (`site-labels.ts`
|
|
44
|
+
* `passCollapse`).
|
|
45
|
+
*
|
|
46
|
+
* A collapse over a single node is that node: the node publishes its value into
|
|
47
|
+
* the collector the collapse's parent opened, exactly where the collapse would
|
|
48
|
+
* have published it, over the same span. So both engines run the body with no
|
|
49
|
+
* frame of the collapse's own and hand its value up. The one value a frame would
|
|
50
|
+
* have treated differently is `undefined`, which a frame does not count as a
|
|
51
|
+
* child: the collapse then builds from no children. This is that case — take the
|
|
52
|
+
* child's publication back and publish the build instead, as the frame would
|
|
53
|
+
* have. The caller has already set `EC.e`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function collapseEmpty(ctx: ParseContext, build: CollapseBuild, input: string, pos: number, end: number, readsRaw: boolean): unknown;
|
|
56
|
+
export {};
|
|
38
57
|
//# sourceMappingURL=run-support.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-support.d.ts","sourceRoot":"","sources":["../../src/table/run-support.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"run-support.d.ts","sourceRoot":"","sources":["../../src/table/run-support.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG/C,MAAM,MAAM,IAAI,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AACjD,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,2EAA2E;AAC3E,wBAAgB,OAAO,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAS3E;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAGjF;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAUjF;AAED,yEAAyE;AACzE,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKvD;AAKD,KAAK,aAAa,GAAG,CACnB,QAAQ,EAAE,SAAS,OAAO,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACrF,WAAW,EAAE,SAAS,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,KAC5E,OAAO,CAAA;AAEZ;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAClG,OAAO,CAST"}
|
|
@@ -10,6 +10,8 @@ export declare function makeScalarRecognizer(op: number, spec: unknown): ScalarR
|
|
|
10
10
|
export declare function scalarTerminalNodeChild(code: ArrayLike<number>, ip: number): number;
|
|
11
11
|
/** Direct untracked terminal whose recognition `not()` can inspect without materializing it. */
|
|
12
12
|
export declare function scalarTerminalNotChild(code: ArrayLike<number>, ip: number): number;
|
|
13
|
+
/** The same terminal under `peek()`: its match decides the lookahead, and nothing it captured survives it. */
|
|
14
|
+
export declare function scalarTerminalPeekChild(code: ArrayLike<number>, ip: number): number;
|
|
13
15
|
/**
|
|
14
16
|
* A direct scalar terminal that every successful execution of `ip` must match
|
|
15
17
|
* first, through wrappers that cannot consume or select before their child.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scalar-terminal.d.ts","sourceRoot":"","sources":["../../src/table/scalar-terminal.ts"],"names":[],"mappings":"AAMA,4FAA4F;AAC5F,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;AAEpF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAwB5F;AAED,iGAAiG;AACjG,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAKnF;AAED,gGAAgG;AAChG,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAKlF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,SAAI,EAAE,cAAc,UAAO,EAAE,WAAW,UAAQ,GAC5F,MAAM,CA4CR;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IACrC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,GAClC,qBAAqB,GAAG,SAAS,CAmEnC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,EAClE,QAAQ,SAAI,EAAE,KAAK,SAAI,GACtB,SAAS,MAAM,EAAE,GAAG,SAAS,CAwD/B;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,GACpE,SAAS,MAAM,EAAE,GAAG,SAAS,CAW/B"}
|
|
1
|
+
{"version":3,"file":"scalar-terminal.d.ts","sourceRoot":"","sources":["../../src/table/scalar-terminal.ts"],"names":[],"mappings":"AAMA,4FAA4F;AAC5F,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;AAEpF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAwB5F;AAED,iGAAiG;AACjG,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAKnF;AAED,gGAAgG;AAChG,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAKlF;AAED,8GAA8G;AAC9G,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAKnF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,SAAI,EAAE,cAAc,UAAO,EAAE,WAAW,UAAQ,GAC5F,MAAM,CA4CR;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IACrC,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,GAClC,qBAAqB,GAAG,SAAS,CAmEnC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,EAClE,QAAQ,SAAI,EAAE,KAAK,SAAI,GACtB,SAAS,MAAM,EAAE,GAAG,SAAS,CAwD/B;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,GACpE,SAAS,MAAM,EAAE,GAAG,SAAS,CAW/B"}
|
|
@@ -46,6 +46,28 @@ export declare const TOP: SiteLabel;
|
|
|
46
46
|
* unemittable regardless.
|
|
47
47
|
*/
|
|
48
48
|
export declare function reachableSites(code: Int32Array, roots: Iterable<number>): Set<number>;
|
|
49
|
+
/**
|
|
50
|
+
* A node both engines lower as a PASS-THROUGH COLLAPSE (`run-support.ts`
|
|
51
|
+
* `collapseEmpty`): `collapse: true` over a direct reducer, no projection, no CST
|
|
52
|
+
* host, no line tracking, whose body is one node behind wrappers that consume and
|
|
53
|
+
* capture nothing (a first-set gate, a trivia scope, a rule reference). One
|
|
54
|
+
* predicate, so the two engines and the labels cannot disagree on a site.
|
|
55
|
+
*/
|
|
56
|
+
export declare function passCollapse(code: Int32Array, ip: number, hostCst: boolean): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* A collapse that a FIRST CHARACTER can reduce to a pass-through: its body is a
|
|
59
|
+
* sequence of `optional`/`not` terms, each behind a first-character gate, then
|
|
60
|
+
* one node. Where the character at the collapse's start opens none of those
|
|
61
|
+
* terms (nor its sequence's trivia — the engines test that against the site's
|
|
62
|
+
* label), every one of them matches empty there and the body is that node alone.
|
|
63
|
+
* `leads` are the gate rows, `lits` the constant indices of direct literal terms,
|
|
64
|
+
* `last` the node term. Not a `passCollapse`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function gatedPassCollapse(code: Int32Array, ip: number, hostCst: boolean): {
|
|
67
|
+
leads: number[];
|
|
68
|
+
lits: number[];
|
|
69
|
+
last: number;
|
|
70
|
+
} | undefined;
|
|
49
71
|
/** A site's label, or `TOP` for anything the walk did not reach. */
|
|
50
72
|
export type SiteLabels = {
|
|
51
73
|
at: (ip: number) => SiteLabel;
|
|
@@ -63,4 +85,48 @@ export type SiteLabels = {
|
|
|
63
85
|
* lattice has height three and the walk terminates.
|
|
64
86
|
*/
|
|
65
87
|
export declare function computeSiteLabels(code: Int32Array, roots: Iterable<number>, hostCst: boolean): SiteLabels;
|
|
88
|
+
/**
|
|
89
|
+
* Does a piece entered at `ip` need the caller's INSTALLED trivia scanner handed
|
|
90
|
+
* across an engine boundary?
|
|
91
|
+
*
|
|
92
|
+
* Each table engine keeps its own installed-scanner slot, and the two hand theirs
|
|
93
|
+
* across at every call between them. A site whose label names its trivia (`tri`)
|
|
94
|
+
* reads no slot: both engines lower its skips onto that trivia's own scanner, and
|
|
95
|
+
* a call out of it can hand that scanner across instead of the slot. Only a site
|
|
96
|
+
* whose trivia the labels cannot name (`TRI_UNKNOWN`) reads the slot. So the
|
|
97
|
+
* handoff is needed exactly when such a site is reachable from `ip` before a
|
|
98
|
+
* scope installs a scanner of its own (an aliased scope, which installs what is
|
|
99
|
+
* already installed, does not). `false` is also the answer for a body with no
|
|
100
|
+
* trivia at all.
|
|
101
|
+
*/
|
|
102
|
+
/**
|
|
103
|
+
* A trivia scope that writes only what its label proves is already in force, so
|
|
104
|
+
* it runs as its child. A slot scope under that same slot is one; so is a scope
|
|
105
|
+
* with no trivia where the label proves none (inside `token()` or another such
|
|
106
|
+
* scope), since every way to `TRI_NONE` leaves no trivia, no kind labels and no
|
|
107
|
+
* scanner — what this scope would write. `OP_SCOPE_PLAIN` has no root policy; a
|
|
108
|
+
* policy-bearing `OP_SCOPE` is one only with policy zero, and `OP_SCOPE_CAP`
|
|
109
|
+
* never is, since it raises `captureTrivia`. `TRI_UNKNOWN` matches nothing.
|
|
110
|
+
*/
|
|
111
|
+
export declare function scopeIsIdentity(code: Int32Array, ip: number, at: SiteLabel): boolean;
|
|
112
|
+
export declare function scanHandoffNeeded(code: Int32Array, ip: number, labels: SiteLabels): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* The first characters that can start trivia at a site labelled `tri`, as code
|
|
115
|
+
* point ranges: none for `TRI_NONE`, `undefined` where the labels cannot name the
|
|
116
|
+
* trivia or its first set is unbounded.
|
|
117
|
+
*/
|
|
118
|
+
export declare function triviaLeadRanges(tri: number, trivia: readonly ({
|
|
119
|
+
_meta: {
|
|
120
|
+
firstSet: {
|
|
121
|
+
kind: string;
|
|
122
|
+
ranges?: readonly {
|
|
123
|
+
lo: number;
|
|
124
|
+
hi: number;
|
|
125
|
+
}[];
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
} | undefined)[]): readonly {
|
|
129
|
+
lo: number;
|
|
130
|
+
hi: number;
|
|
131
|
+
}[] | undefined;
|
|
66
132
|
//# sourceMappingURL=site-labels.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-labels.d.ts","sourceRoot":"","sources":["../../src/table/site-labels.ts"],"names":[],"mappings":"AAoEA,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;AAEvB,0DAA0D;AAC1D,eAAO,MAAM,WAAW,IAAI,CAAA;AAC5B,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;
|
|
1
|
+
{"version":3,"file":"site-labels.d.ts","sourceRoot":"","sources":["../../src/table/site-labels.ts"],"names":[],"mappings":"AAoEA,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;AAEvB,0DAA0D;AAC1D,eAAO,MAAM,WAAW,IAAI,CAAA;AAC5B,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;IAAE,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,SAAS,CAAA;CAAE,CAAA;AAE1D;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,EACvB,OAAO,EAAE,OAAO,GACf,UAAU,CA6BZ;AAED;;;;;;;;;;;;;GAaG;AACH;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAKpF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAqB3F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;IAAE,KAAK,EAAE;QAAE,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,SAAS;gBAAE,EAAE,EAAE,MAAM,CAAC;gBAAC,EAAE,EAAE,MAAM,CAAA;aAAE,EAAE,CAAA;SAAE,CAAA;KAAE,CAAA;CAAE,GAAG,SAAS,CAAC,EAAE,GACtI,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,SAAS,CAOnD"}
|
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.
|
|
16
|
+
export declare const PARSEMAN_VERSION = "0.58.1";
|
|
17
17
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -105,10 +105,19 @@ export function branchUsesRouted(branch: { parser: Combinator<unknown>; usesRout
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
export function asciiFoldKey(key: string): string {
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
// A key with no ASCII capital is its own fold: every dispatch on a lowercase
|
|
109
|
+
// word asks, and building the same string again a character at a time cost an
|
|
110
|
+
// allocation per character.
|
|
111
|
+
let i = 0
|
|
112
|
+
for (; i < key.length; i++) {
|
|
110
113
|
const c = key.charCodeAt(i)
|
|
111
|
-
|
|
114
|
+
if (c >= 65 && c <= 90) break
|
|
115
|
+
}
|
|
116
|
+
if (i === key.length) return key
|
|
117
|
+
let out = key.slice(0, i)
|
|
118
|
+
for (; i < key.length; i++) {
|
|
119
|
+
const c = key.charCodeAt(i)
|
|
120
|
+
out += c >= 65 && c <= 90 ? String.fromCharCode(c + 32) : key[i]!
|
|
112
121
|
}
|
|
113
122
|
return out
|
|
114
123
|
}
|
|
@@ -37,6 +37,7 @@ import type { BalancedSpec } from '../combinators/scanTo.ts'
|
|
|
37
37
|
import { deriveExpected } from '../combinators/expect.ts'
|
|
38
38
|
import { assertionFailureExpected, directTerminalFailureExpected } from '../combinators/expected.ts'
|
|
39
39
|
import { keywordsRegExp } from '../combinators/keywords.ts'
|
|
40
|
+
import { hasOwnTriviaBoundary } from '../combinators/trivia-boundary.ts'
|
|
40
41
|
|
|
41
42
|
/** A terminal in the derived alphabet, with its globally assigned id. */
|
|
42
43
|
export type TokenTerminal =
|
|
@@ -135,12 +136,17 @@ export type ExecutableLexNode =
|
|
|
135
136
|
| {
|
|
136
137
|
readonly kind: 'choice'
|
|
137
138
|
readonly arms: readonly ExecutableLexNode[]
|
|
138
|
-
|
|
139
|
+
/** The authored arms: the encoder classifies them as the character choice would. */
|
|
140
|
+
readonly parsers: readonly Combinator<unknown>[]
|
|
141
|
+
/** Inside a no-trivia scope of the token, where the encoder's trivia is none. */
|
|
142
|
+
readonly cleared: boolean
|
|
139
143
|
readonly armExpected: readonly (readonly string[])[]
|
|
140
144
|
readonly expected: readonly string[]
|
|
141
145
|
}
|
|
142
146
|
| { readonly kind: 'not'; readonly body: ExecutableLexNode; readonly expected: readonly string[] }
|
|
143
147
|
| { readonly kind: 'optional'; readonly body: ExecutableLexNode }
|
|
148
|
+
/** A separator-less `many`/`oneOrMore`; `max` −1 is unbounded. */
|
|
149
|
+
| { readonly kind: 'repeat'; readonly body: ExecutableLexNode; readonly min: number; readonly max: number }
|
|
144
150
|
|
|
145
151
|
export type ExecutableFixedLexBody = {
|
|
146
152
|
readonly kind: 'fixed-tree'
|
|
@@ -204,9 +210,22 @@ export function selectOptionalSuffixLexBody(ir: LexicalIr): LexBodyCandidate {
|
|
|
204
210
|
/** Unwrap only scopes that token() has already installed identically. The
|
|
205
211
|
* returned parser is still the authored terminal/sequence; no effectful wrapper
|
|
206
212
|
* or final named winner is guessed from construction metadata. */
|
|
213
|
+
/**
|
|
214
|
+
* A rule reference made with no trivia in force reinstalls the rule's own
|
|
215
|
+
* ambient trivia when the rule has a position that reads it (`ref.ts`, the
|
|
216
|
+
* encoder's `scopedRef`), and inside a token none is in force. Such a rule's
|
|
217
|
+
* terms are then trivia-separated, which a lexical body does not model, so the
|
|
218
|
+
* reference is not lowered.
|
|
219
|
+
*/
|
|
220
|
+
function reinstallsRuleTrivia(reference: Combinator<unknown>, target: Combinator<unknown>): boolean {
|
|
221
|
+
return (reference._meta.grammarTrivia ?? target._meta.grammarTrivia) !== undefined
|
|
222
|
+
&& hasOwnTriviaBoundary(target)
|
|
223
|
+
}
|
|
224
|
+
|
|
207
225
|
function directTokenBodyParser(
|
|
208
226
|
parser: Combinator<unknown>,
|
|
209
227
|
resolve?: (name: string) => Combinator<unknown> | undefined,
|
|
228
|
+
scope?: { cleared: boolean },
|
|
210
229
|
): Combinator<unknown> | undefined {
|
|
211
230
|
const outer = parser._def
|
|
212
231
|
if (outer.tag !== 'token') return undefined
|
|
@@ -220,12 +239,13 @@ function directTokenBodyParser(
|
|
|
220
239
|
|| wrapper.captureTrivia === true || wrapper.rootCapture === 'opaque'
|
|
221
240
|
|| wrapper.constructionTrackLines !== 'inherit'
|
|
222
241
|
|| wrapper.constructionCaptureTriviaKinds !== undefined) return undefined
|
|
242
|
+
if (scope !== undefined) scope.cleared = true
|
|
223
243
|
body = wrapper.parser
|
|
224
244
|
continue
|
|
225
245
|
}
|
|
226
246
|
if (wrapper.tag === 'lazy') {
|
|
227
247
|
const target = resolvedLazyTarget(body, resolve)
|
|
228
|
-
if (target === undefined) return undefined
|
|
248
|
+
if (target === undefined || reinstallsRuleTrivia(body, target)) return undefined
|
|
229
249
|
body = target
|
|
230
250
|
continue
|
|
231
251
|
}
|
|
@@ -436,6 +456,7 @@ function directFixedLexNode(
|
|
|
436
456
|
resolve: ((name: string) => Combinator<unknown> | undefined) | undefined,
|
|
437
457
|
active: Set<Combinator<unknown>>,
|
|
438
458
|
pureOnly = false,
|
|
459
|
+
cleared = false,
|
|
439
460
|
): ExecutableLexNode | undefined {
|
|
440
461
|
let current = parser
|
|
441
462
|
const wrappers = new Set<Combinator<unknown>>()
|
|
@@ -444,7 +465,7 @@ function directFixedLexNode(
|
|
|
444
465
|
const def = current._def
|
|
445
466
|
if (def.tag === 'lazy') {
|
|
446
467
|
const target = resolvedLazyTarget(current, resolve)
|
|
447
|
-
if (target === undefined) return undefined
|
|
468
|
+
if (target === undefined || reinstallsRuleTrivia(current, target)) return undefined
|
|
448
469
|
current = target
|
|
449
470
|
continue
|
|
450
471
|
}
|
|
@@ -459,43 +480,57 @@ function directFixedLexNode(
|
|
|
459
480
|
if (terminal !== undefined) return { kind: 'terminal', terminal }
|
|
460
481
|
const def = current._def
|
|
461
482
|
if (def.tag === 'grammar') {
|
|
483
|
+
// A scope with no trivia of its own writes nothing under a token that is
|
|
484
|
+
// not already in force: a cleared one runs as its child in the table
|
|
485
|
+
// (`scopeIsIdentity`) and an inheriting one encodes no row. Its line
|
|
486
|
+
// policy is the table's own (`hasScopedTrackLines`). So it is its child
|
|
487
|
+
// at any position.
|
|
488
|
+
if (def.triviaParser === undefined && def.captureTrivia !== true
|
|
489
|
+
&& def.rootCapture !== 'opaque' && def.constructionCaptureTriviaKinds === undefined) {
|
|
490
|
+
return directFixedLexNode(def.parser, resolve, active, pureOnly, cleared || def.clearTrivia === true)
|
|
491
|
+
}
|
|
462
492
|
if (!pureOnly || (def.parser._def.tag !== 'token'
|
|
463
493
|
&& (def.clearTrivia !== true || def.triviaParser !== undefined
|
|
464
494
|
|| def.captureTrivia === true || def.rootCapture === 'opaque'))) return undefined
|
|
465
|
-
return directFixedLexNode(def.parser, resolve, active, true)
|
|
495
|
+
return directFixedLexNode(def.parser, resolve, active, true, cleared)
|
|
466
496
|
}
|
|
467
497
|
if (def.tag === 'sequence') {
|
|
468
498
|
if (def.parsers.length < 2 || def.parsers.length > 5) return undefined
|
|
469
|
-
const parts = def.parsers.map(part => directFixedLexNode(part, resolve, active, pureOnly))
|
|
499
|
+
const parts = def.parsers.map(part => directFixedLexNode(part, resolve, active, pureOnly, cleared))
|
|
470
500
|
if (parts.some(part => part === undefined)) return undefined
|
|
471
501
|
return { kind: 'sequence', parts: parts as ExecutableLexNode[] }
|
|
472
502
|
}
|
|
473
503
|
if (def.tag === 'choice') {
|
|
474
|
-
if (
|
|
504
|
+
if (def.parsers.length < 2
|
|
475
505
|
|| def.strategy.tag !== 'firstMatch'
|
|
476
506
|
|| def.gates.some(gate => gate !== null)
|
|
477
507
|
|| def.autoNot.some(check => check !== null)) return undefined
|
|
478
|
-
const arms = def.parsers.map(arm => directFixedLexNode(arm, resolve, active, pureOnly))
|
|
508
|
+
const arms = def.parsers.map(arm => directFixedLexNode(arm, resolve, active, pureOnly, cleared))
|
|
479
509
|
if (arms.some(arm => arm === undefined)) return undefined
|
|
480
|
-
const final = classifyFinalChoice(def.parsers, resolve)
|
|
481
510
|
return {
|
|
482
511
|
kind: 'choice', arms: arms as ExecutableLexNode[],
|
|
483
|
-
|
|
512
|
+
parsers: def.parsers, cleared,
|
|
484
513
|
armExpected: def.parsers.map(deriveExpected),
|
|
485
514
|
expected: def.parsers.flatMap(deriveExpected),
|
|
486
515
|
}
|
|
487
516
|
}
|
|
488
517
|
if (def.tag === 'not') {
|
|
489
|
-
const body = directFixedLexNode(def.parser, resolve, active, true)
|
|
518
|
+
const body = directFixedLexNode(def.parser, resolve, active, true, cleared)
|
|
490
519
|
return body === undefined ? undefined : {
|
|
491
520
|
kind: 'not', body,
|
|
492
521
|
expected: assertionFailureExpected(false, def.parser._tag),
|
|
493
522
|
}
|
|
494
523
|
}
|
|
495
524
|
if (def.tag === 'optional') {
|
|
496
|
-
const body = directFixedLexNode(def.parser, resolve, active, pureOnly)
|
|
525
|
+
const body = directFixedLexNode(def.parser, resolve, active, pureOnly, cleared)
|
|
497
526
|
return body === undefined ? undefined : { kind: 'optional', body }
|
|
498
527
|
}
|
|
528
|
+
if (def.tag === 'many' || def.tag === 'oneOrMore') {
|
|
529
|
+
const body = directFixedLexNode(def.parser, resolve, active, pureOnly, cleared)
|
|
530
|
+
return body === undefined ? undefined : {
|
|
531
|
+
kind: 'repeat', body, min: def.tag === 'many' ? 0 : def.min, max: def.max ?? -1,
|
|
532
|
+
}
|
|
533
|
+
}
|
|
499
534
|
return undefined
|
|
500
535
|
} finally {
|
|
501
536
|
active.delete(current)
|
|
@@ -506,9 +541,10 @@ export function directFixedTokenBody(
|
|
|
506
541
|
parser: Combinator<unknown>,
|
|
507
542
|
resolve?: (name: string) => Combinator<unknown> | undefined,
|
|
508
543
|
): ExecutableFixedLexBody | undefined {
|
|
509
|
-
const
|
|
544
|
+
const scope = { cleared: false }
|
|
545
|
+
const body = directTokenBodyParser(parser, resolve, scope)
|
|
510
546
|
if (body === undefined) return undefined
|
|
511
|
-
const root = directFixedLexNode(body, resolve, new Set())
|
|
547
|
+
const root = directFixedLexNode(body, resolve, new Set(), false, scope.cleared)
|
|
512
548
|
return root === undefined ? undefined : { kind: 'fixed-tree', root }
|
|
513
549
|
}
|
|
514
550
|
|
|
@@ -1556,8 +1592,11 @@ function normalizeLexical(
|
|
|
1556
1592
|
if (stack.has(parser)) return { refusal: 'recursive token body' }
|
|
1557
1593
|
stack.add(parser)
|
|
1558
1594
|
try {
|
|
1559
|
-
|
|
1560
|
-
|
|
1595
|
+
// A nested `balanced()` is its scanner machine, not the transform that
|
|
1596
|
+
// builds its value — `sequence('@', balanced('{', '}'))` as a skipper.
|
|
1597
|
+
return normalizeBalancedLexical(parser, resolve, session)
|
|
1598
|
+
?? withLexicalControl(session, parser._def.tag, () =>
|
|
1599
|
+
normalizeLexicalBody(parser, resolve, stack, session))
|
|
1561
1600
|
} finally {
|
|
1562
1601
|
stack.delete(parser)
|
|
1563
1602
|
}
|
|
@@ -1841,8 +1880,9 @@ function fixedBindingProjection(
|
|
|
1841
1880
|
// and the emitted adapter captures that site's named body after linking every
|
|
1842
1881
|
// scan root. Only ambient trivia/scanSkip remain live runtime callbacks; they
|
|
1843
1882
|
// are scanner POLICY, never binding authority for these authored own children.
|
|
1844
|
-
// Recovery
|
|
1845
|
-
|
|
1883
|
+
// Recovery still has no equivalent named template. `withCtx` has one: the
|
|
1884
|
+
// emitter's OP_WITHCTX body calls its child by the name `link()` minted.
|
|
1885
|
+
if (edge.parentTag === 'recover') readerMask = 0b011
|
|
1846
1886
|
// Sequence strict, adjacency, and recovery bodies now all use scalar block
|
|
1847
1887
|
// chains, so no supported variant is withheld here.
|
|
1848
1888
|
const words = [
|
|
@@ -111,6 +111,31 @@ export function pushCstChild(ctx: ParseContext, built: unknown, rawEntry: unknow
|
|
|
111
111
|
if (ctx._cstRawChildren) ctx._cstRawChildren.push(rawEntry)
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Undo the LAST `pushCstChild` into the active collector, whichever form it took:
|
|
116
|
+
* a child the lazy buffer's empty sentinel dropped (`undefined` first) leaves no
|
|
117
|
+
* semantic entry to remove, only its raw one.
|
|
118
|
+
*/
|
|
119
|
+
export function popCstChild(ctx: ParseContext): void {
|
|
120
|
+
const b = ctx._cstBuf
|
|
121
|
+
if (b) {
|
|
122
|
+
const ch = b.ch
|
|
123
|
+
if (b.rawOnly !== true && ch) {
|
|
124
|
+
ch.pop()
|
|
125
|
+
if (ch.length === 1) { b.single = ch[0]; b.ch = undefined }
|
|
126
|
+
}
|
|
127
|
+
if (b.noRaw === true) b.rawLen = (b.rawLen ?? 1) - 1
|
|
128
|
+
else if (b.raw) {
|
|
129
|
+
b.raw.pop()
|
|
130
|
+
if (b.raw.length === 1) { b.rawSingle = b.raw[0]; b.raw = undefined }
|
|
131
|
+
} else b.rawSingle = undefined
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
if (ctx._cstChildren) ctx._cstChildren.pop()
|
|
135
|
+
else if (ctx._cstLeaves) ctx._cstLeaves.pop()
|
|
136
|
+
if (ctx._cstRawChildren) ctx._cstRawChildren.pop()
|
|
137
|
+
}
|
|
138
|
+
|
|
114
139
|
export function cstRawLen(ctx: ParseContext): number {
|
|
115
140
|
const b = ctx._cstBuf
|
|
116
141
|
if (b) {
|