parseman 0.28.1 → 0.30.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/combinators/attempt.d.ts.map +1 -1
- package/dist/combinators/choice.d.ts +11 -0
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/first-set.d.ts +7 -0
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/repeat.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +24 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +10 -0
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/index.cjs +256 -17
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +256 -17
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.cjs.map +2 -2
- package/dist/language-service/index.js.map +2 -2
- package/dist/plugin/index.cjs +257 -18
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +257 -18
- package/dist/plugin/index.js.map +3 -3
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attempt.d.ts","sourceRoot":"","sources":["../../src/combinators/attempt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"attempt.d.ts","sourceRoot":"","sources":["../../src/combinators/attempt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,aAAa,CAAA;AAKxE;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CA2B/D"}
|
|
@@ -4,6 +4,17 @@ type UnionArms<T extends (Combinator<unknown> | GatedArm<unknown>)[]> = {
|
|
|
4
4
|
[K in keyof T]: ArmParser<T[K]>;
|
|
5
5
|
}[number] extends Combinator<infer U> ? U : never;
|
|
6
6
|
export declare function choice<T extends [Combinator<unknown> | GatedArm<unknown>, ...(Combinator<unknown> | GatedArm<unknown>)[]]>(...args: T): Combinator<UnionArms<T>>;
|
|
7
|
+
/**
|
|
8
|
+
* Peel wrappers that neither consume input nor skip trivia before their inner
|
|
9
|
+
* sequence -- `node`, `parser`/`grammar`, `transform`, `label` -- down to the core
|
|
10
|
+
* `sequence` and return its FIRST term (the candidate shared prefix), or null when
|
|
11
|
+
* the arm is not a wrapped-or-bare sequence with >=2 terms. Because none of these
|
|
12
|
+
* wrappers advance the position before the sequence's first term, the term is parsed
|
|
13
|
+
* at the arm's entry position in every arm, so the once-recognized prefix can be
|
|
14
|
+
* replayed there. `attempt`/`optional`/`many`/`choice`/etc. are NOT peeled, so such
|
|
15
|
+
* arms are conservatively excluded.
|
|
16
|
+
*/
|
|
17
|
+
export declare function leadingTermOfArm(arm: Combinator<unknown>): Combinator<unknown> | null;
|
|
7
18
|
/** Walk transform wrappers to find an inner literal's string value. */
|
|
8
19
|
export declare function getCoreLiteralValue(p: Combinator<unknown>): string | null;
|
|
9
20
|
/** Walk transform wrappers to find an inner regex's source/flags. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"choice.d.ts","sourceRoot":"","sources":["../../src/combinators/choice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAC+B,QAAQ,EAClD,MAAM,aAAa,CAAA;AAKpB,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;AACvH,KAAK,SAAS,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI;KACrE,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAChC,CAAC,MAAM,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAEjD,wBAAgB,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EACxH,GAAG,IAAI,EAAE,CAAC,GACT,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"choice.d.ts","sourceRoot":"","sources":["../../src/combinators/choice.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAC+B,QAAQ,EAClD,MAAM,aAAa,CAAA;AAKpB,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;AACvH,KAAK,SAAS,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI;KACrE,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAChC,CAAC,MAAM,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAEjD,wBAAgB,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EACxH,GAAG,IAAI,EAAE,CAAC,GACT,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CA2J1B;AA4FD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAWrF;AA6CD,uEAAuE;AACvE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAKzE;AAED,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMhG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../src/combinators/expect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAyC,UAAU,EAAE,MAAM,aAAa,CAAA;AAGhG,YAAY,EAAE,UAAU,EAAE,CAAA;AAE1B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../src/combinators/expect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAyC,UAAU,EAAE,MAAM,aAAa,CAAA;AAGhG,YAAY,EAAE,UAAU,EAAE,CAAA;AAE1B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE,CAsC/D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,GAAG,UAAU,CAAC,CA2B/F;AAED,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAEhE"}
|
|
@@ -2,6 +2,13 @@ import type { FirstSet, Combinator } from '../types.ts';
|
|
|
2
2
|
export declare function union(a: FirstSet, b: FirstSet): FirstSet;
|
|
3
3
|
export declare function intersects(a: FirstSet, b: FirstSet): boolean;
|
|
4
4
|
export declare function fromChar(code: number): FirstSet;
|
|
5
|
+
/**
|
|
6
|
+
* True when `combinator`'s first set admits the code point at `input[pos]` (or its
|
|
7
|
+
* first set is `any`). The runtime counterpart of codegen's `firstSetCond` guard —
|
|
8
|
+
* used by the interpreter's first-set fail-fast in `optional`/`many`/`attempt`/
|
|
9
|
+
* `node` to reject a doomed sub-parse before doing any setup. Returns `false` at EOF.
|
|
10
|
+
*/
|
|
11
|
+
export declare function startsFirstSet(combinator: Combinator<unknown>, input: string, pos: number): boolean;
|
|
5
12
|
export declare function fromRange(lo: number, hi: number): FirstSet;
|
|
6
13
|
export declare function any(): FirstSet;
|
|
7
14
|
export declare function empty(): FirstSet;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"first-set.d.ts","sourceRoot":"","sources":["../../src/combinators/first-set.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,QAAQ,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;AAE7E,wBAAgB,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAKxD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAS5D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAE/C;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,CAE1D;AAED,wBAAgB,GAAG,IAAI,QAAQ,CAE9B;AAED,wBAAgB,KAAK,IAAI,QAAQ,CAEhC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAqCxG;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,QAAQ,CAOlF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,QAAQ,CAsCvG"}
|
|
1
|
+
{"version":3,"file":"first-set.d.ts","sourceRoot":"","sources":["../../src/combinators/first-set.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,QAAQ,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;AAE7E,wBAAgB,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAKxD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAS5D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAE/C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAQnG;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,QAAQ,CAE1D;AAED,wBAAgB,GAAG,IAAI,QAAQ,CAE9B;AAED,wBAAgB,KAAK,IAAI,QAAQ,CAEhC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,OAAO,CAqCxG;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,QAAQ,CAOlF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,IAAI,GAAE,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAa,GAAG,QAAQ,CAsCvG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/combinators/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAoD,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/combinators/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAoD,MAAM,aAAa,CAAA;AAQzG;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CACzB,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,EAChC,MAAM,EAAE,QAAQ,GAAG,SAAS,EAC5B,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACpC,WAAW,EAAE,aAAa,CAAC,OAAO,CAAC,EACnC,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,KAAK,EAAE,OAAO,KACX,CAAC,CAAA;AAEN;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,CAAA;AAqBrH,wBAAgB,IAAI,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;AACjH,wBAAgB,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repeat.d.ts","sourceRoot":"","sources":["../../src/combinators/repeat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAyC,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"repeat.d.ts","sourceRoot":"","sources":["../../src/combinators/repeat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAyC,MAAM,aAAa,CAAA;AAqEpF,wBAAgB,IAAI,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CAkDlE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CA8CvE;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAwB3E;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CAwFhG"}
|
|
@@ -7,6 +7,21 @@
|
|
|
7
7
|
* object allocation per node.
|
|
8
8
|
*/
|
|
9
9
|
import type { Combinator, FirstSet, ParseResult, ParseContext, ParseError } from '../types.ts';
|
|
10
|
+
/**
|
|
11
|
+
* A rule's LEADING first-set as a fuse-resolvable recipe: the concrete leading
|
|
12
|
+
* chars (literals/regex reached through the nullable prefix) kept SEPARATE from the
|
|
13
|
+
* leading rule-REFERENCE names. `fusedBody()` resolves the ref names against the
|
|
14
|
+
* WINNING rules (a fixpoint) and unions the concrete part, so a composed grammar
|
|
15
|
+
* gets the same first-char dispatch a monolithic compile would — WITHOUT baking a
|
|
16
|
+
* referenced rule's first-set (which a compose override could later widen). Kept
|
|
17
|
+
* conservative: an unknown/opaque construct contributes its shallow `_meta.firstSet`
|
|
18
|
+
* (never an under-approximation, so dispatch never drops a valid parse).
|
|
19
|
+
*/
|
|
20
|
+
export type FirstSetRecipe = {
|
|
21
|
+
concrete: FirstSet;
|
|
22
|
+
refs: string[];
|
|
23
|
+
};
|
|
24
|
+
export declare function leadingFirstSetRecipe(p: Combinator<unknown>, seen?: Set<Combinator<unknown>>): FirstSetRecipe;
|
|
10
25
|
import { type GrammarCoveragePlan } from './grammar-coverage-ids.ts';
|
|
11
26
|
/**
|
|
12
27
|
* Runtime prelude helper for the structural-node capture gate. Answers "does the
|
|
@@ -24,6 +39,7 @@ export declare function beginLoweringCapture(): void;
|
|
|
24
39
|
export declare function endLoweringCapture(): string[];
|
|
25
40
|
export declare function firstSetCond(codeVar: string, fs: FirstSet): string;
|
|
26
41
|
export declare function __setForceDisjointIf(on: boolean): void;
|
|
42
|
+
export declare function __setForceNoSharedPrefix(on: boolean): void;
|
|
27
43
|
export type CompiledParser<T> = {
|
|
28
44
|
parse(input: string, pos?: number): ParseResult<T>;
|
|
29
45
|
/** Like parse(), but with a caller-supplied ParseContext (e.g. `_triviaLog` for CST grammars). */
|
|
@@ -110,6 +126,14 @@ export type LinkablePieces = {
|
|
|
110
126
|
* emitted for rule-ref choice arms — sound under compose override.
|
|
111
127
|
*/
|
|
112
128
|
firstSets: Map<string, FirstSet>;
|
|
129
|
+
/**
|
|
130
|
+
* Per-rule LEADING first-set recipe (concrete chars + leading ref names).
|
|
131
|
+
* `fusedBody()` fixpoint-resolves the ref names over the WINNING rules so a
|
|
132
|
+
* `sequence(ref, …)`-led arm/node dispatches on the ref's real first char —
|
|
133
|
+
* matching a monolithic compile — instead of degrading to always-try because
|
|
134
|
+
* the ref baked `any`. Optional for back-compat with hand-built pieces.
|
|
135
|
+
*/
|
|
136
|
+
firstSetRecipes?: Map<string, FirstSetRecipe>;
|
|
113
137
|
deps: Map<string, string[]>;
|
|
114
138
|
needsEmptyTl: boolean;
|
|
115
139
|
needsHostReads: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/compiler/codegen.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,UAAU,EAAa,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAA4B,MAAM,aAAa,CAAA;AAKnI,OAAO,EAAoB,KAAK,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAsBtF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,uTAC0R,CAAA;AActT,8EAA8E;AAC9E,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAI7C;
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/compiler/codegen.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,6 +50,16 @@ export declare function pick(grammar: LinkablePieces | Record<string, Combinator
|
|
|
50
50
|
* compose override order). Shared by `pick()` (runtime) and the macro's build-time
|
|
51
51
|
* `pick(...)` handling, so à-la-carte selection is identical on both paths. */
|
|
52
52
|
export declare function pickPieces(pieces: LinkablePieces[], names: string[]): LinkablePieces[];
|
|
53
|
+
/**
|
|
54
|
+
* Build the fused-closure body (shared by the runtime `fuseRules` and the
|
|
55
|
+
* build-time `emitFusedSource`). Returns the closure body (which reads `_env`
|
|
56
|
+
* for any non-inlined callbacks) and the `_env` to bind. In macro mode callbacks
|
|
57
|
+
* are inlined from source, so `_env` is empty and the body is fully static.
|
|
58
|
+
*/
|
|
59
|
+
export declare function fusedBody(pieces: LinkablePieces[]): {
|
|
60
|
+
body: string;
|
|
61
|
+
env: Record<string, unknown>;
|
|
62
|
+
};
|
|
53
63
|
/** Fuse at RUNTIME (via `new Function`) — used by `compose()` when not compiled
|
|
54
64
|
* by the macro (like `compile()`). The macro path uses `emitFusedSource` instead. */
|
|
55
65
|
export declare function fuseRules(pieces: LinkablePieces[]): Record<string, FusedRule>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linker.d.ts","sourceRoot":"","sources":["../../src/compiler/linker.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"linker.d.ts","sourceRoot":"","sources":["../../src/compiler/linker.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -117,6 +117,15 @@ function intersects(a, b) {
|
|
|
117
117
|
function fromChar(code) {
|
|
118
118
|
return { kind: "ranges", ranges: [{ lo: code, hi: code }] };
|
|
119
119
|
}
|
|
120
|
+
function startsFirstSet(combinator, input, pos) {
|
|
121
|
+
const fs = combinator._meta.firstSet;
|
|
122
|
+
if (fs.kind === "any") return true;
|
|
123
|
+
if (fs.kind === "empty") return false;
|
|
124
|
+
const code = input.codePointAt(pos);
|
|
125
|
+
if (code === void 0) return false;
|
|
126
|
+
for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
120
129
|
function fromRange(lo, hi) {
|
|
121
130
|
return { kind: "ranges", ranges: [{ lo, hi }] };
|
|
122
131
|
}
|
|
@@ -1043,6 +1052,17 @@ function deriveExpected(c) {
|
|
|
1043
1052
|
return def.parsers.length > 0 ? deriveExpected(def.parsers[0]) : [];
|
|
1044
1053
|
case "attempt":
|
|
1045
1054
|
return deriveExpected(def.parser);
|
|
1055
|
+
// Delegating wrappers whose first-token failure is their inner parser's — must
|
|
1056
|
+
// pass through so a start-failure (and the first-set-miss fast-path in attempt/
|
|
1057
|
+
// node, which reads this) names the real expected token, not the wrapper tag.
|
|
1058
|
+
case "field":
|
|
1059
|
+
case "withCtx":
|
|
1060
|
+
case "recover":
|
|
1061
|
+
return deriveExpected(def.parser);
|
|
1062
|
+
case "skip":
|
|
1063
|
+
return deriveExpected(def.main);
|
|
1064
|
+
case "expect":
|
|
1065
|
+
return def.expected;
|
|
1046
1066
|
case "node":
|
|
1047
1067
|
case "grammar":
|
|
1048
1068
|
case "trivia":
|
|
@@ -1106,7 +1126,7 @@ function choice(...args) {
|
|
|
1106
1126
|
disjoint
|
|
1107
1127
|
};
|
|
1108
1128
|
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
1109
|
-
const autoNot = !disjoint && !hasGates && strategy?.tag === "firstMatch" ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1129
|
+
const autoNot = !disjoint && !hasGates && (strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix") ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
1110
1130
|
let greedyLitMap = null;
|
|
1111
1131
|
let sortedParsers = null;
|
|
1112
1132
|
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
@@ -1232,8 +1252,47 @@ function detectStrategy(parsers) {
|
|
|
1232
1252
|
);
|
|
1233
1253
|
return { tag: "literalsLongestFirst", sortedIndices };
|
|
1234
1254
|
}
|
|
1255
|
+
const shared = detectSharedPrefix(parsers);
|
|
1256
|
+
if (shared !== null) return shared;
|
|
1235
1257
|
return { tag: "firstMatch" };
|
|
1236
1258
|
}
|
|
1259
|
+
function bareLeadingTermKey(term) {
|
|
1260
|
+
const d = term._def;
|
|
1261
|
+
if (d.tag === "literal" && !d.caseInsensitive) return `L:${d.value}`;
|
|
1262
|
+
if (d.tag === "regex") return `R:${d.source}\0${d.flags}`;
|
|
1263
|
+
return null;
|
|
1264
|
+
}
|
|
1265
|
+
function detectSharedPrefix(parsers) {
|
|
1266
|
+
if (parsers.length < 2) return null;
|
|
1267
|
+
let key = null;
|
|
1268
|
+
let prefix = null;
|
|
1269
|
+
const members = [];
|
|
1270
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
1271
|
+
const term0 = leadingTermOfArm(parsers[i]);
|
|
1272
|
+
if (term0 === null) return null;
|
|
1273
|
+
const k = bareLeadingTermKey(term0);
|
|
1274
|
+
if (k === null) return null;
|
|
1275
|
+
if (key === null) {
|
|
1276
|
+
key = k;
|
|
1277
|
+
prefix = term0;
|
|
1278
|
+
} else if (k !== key) return null;
|
|
1279
|
+
members.push(i);
|
|
1280
|
+
}
|
|
1281
|
+
if (prefix === null || members.length < 2) return null;
|
|
1282
|
+
return { tag: "sharedPrefix", prefix, members };
|
|
1283
|
+
}
|
|
1284
|
+
function leadingTermOfArm(arm) {
|
|
1285
|
+
let d = arm._def;
|
|
1286
|
+
for (; ; ) {
|
|
1287
|
+
if (d.tag === "node" || d.tag === "grammar" || d.tag === "transform" || d.tag === "label") {
|
|
1288
|
+
d = d.parser._def;
|
|
1289
|
+
continue;
|
|
1290
|
+
}
|
|
1291
|
+
break;
|
|
1292
|
+
}
|
|
1293
|
+
if (d.tag !== "sequence" || d.parsers.length < 2) return null;
|
|
1294
|
+
return d.parsers[0];
|
|
1295
|
+
}
|
|
1237
1296
|
function computeAutoNot(parsers) {
|
|
1238
1297
|
return parsers.map((p, i) => {
|
|
1239
1298
|
const litVal = getCoreLiteralValue(p);
|
|
@@ -1827,11 +1886,20 @@ function sequence(...parsers) {
|
|
|
1827
1886
|
|
|
1828
1887
|
// src/combinators/attempt.ts
|
|
1829
1888
|
function attempt(parser2) {
|
|
1889
|
+
const guardable = parser2._meta.firstSet.kind !== "any" && !matchesEmpty(parser2);
|
|
1890
|
+
let failExpected;
|
|
1830
1891
|
return {
|
|
1831
1892
|
_tag: "attempt",
|
|
1832
1893
|
_meta: parser2._meta,
|
|
1833
1894
|
_def: { tag: "attempt", parser: parser2 },
|
|
1834
1895
|
parse(input, pos, ctx) {
|
|
1896
|
+
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(parser2, input, pos)) {
|
|
1897
|
+
if (failExpected === void 0) {
|
|
1898
|
+
const e = deriveExpected(parser2);
|
|
1899
|
+
failExpected = e.length > 0 ? e : [parser2._tag];
|
|
1900
|
+
}
|
|
1901
|
+
return { ok: false, expected: failExpected, span: { start: pos, end: pos } };
|
|
1902
|
+
}
|
|
1835
1903
|
const mark = saveCstMark(ctx);
|
|
1836
1904
|
const log = ctx._triviaLog?.length;
|
|
1837
1905
|
const result = parser2.parse(input, pos, ctx);
|
|
@@ -1844,7 +1912,7 @@ function attempt(parser2) {
|
|
|
1844
1912
|
}
|
|
1845
1913
|
|
|
1846
1914
|
// src/combinators/repeat.ts
|
|
1847
|
-
function repItem(combinator, input, cur, ctx) {
|
|
1915
|
+
function repItem(combinator, input, cur, ctx, guardable) {
|
|
1848
1916
|
const mark = saveTriviaMark(ctx);
|
|
1849
1917
|
let pos = cur;
|
|
1850
1918
|
if (ctx.trivia) {
|
|
@@ -1860,6 +1928,10 @@ function repItem(combinator, input, cur, ctx) {
|
|
|
1860
1928
|
rollbackTrivia(ctx, mark);
|
|
1861
1929
|
return "stop";
|
|
1862
1930
|
}
|
|
1931
|
+
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
1932
|
+
rollbackTrivia(ctx, mark);
|
|
1933
|
+
return "stop";
|
|
1934
|
+
}
|
|
1863
1935
|
const result = combinator.parse(input, pos, ctx);
|
|
1864
1936
|
if (!result.ok) {
|
|
1865
1937
|
rollbackTrivia(ctx, mark);
|
|
@@ -1879,6 +1951,7 @@ function many(combinator) {
|
|
|
1879
1951
|
};
|
|
1880
1952
|
const def = { tag: "many", parser: combinator, min: 0 };
|
|
1881
1953
|
let expected;
|
|
1954
|
+
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
1882
1955
|
return {
|
|
1883
1956
|
_tag: "many",
|
|
1884
1957
|
_meta: meta,
|
|
@@ -1887,7 +1960,7 @@ function many(combinator) {
|
|
|
1887
1960
|
const values = def.valueUnused ? void 0 : [];
|
|
1888
1961
|
let cur = pos;
|
|
1889
1962
|
while (cur < input.length) {
|
|
1890
|
-
const item = repItem(combinator, input, cur, ctx);
|
|
1963
|
+
const item = repItem(combinator, input, cur, ctx, guardable);
|
|
1891
1964
|
if (item === "stop") break;
|
|
1892
1965
|
if ("fail" in item) {
|
|
1893
1966
|
const sync = ctx._tolerant ? ctx._sync : void 0;
|
|
@@ -1915,6 +1988,7 @@ function oneOrMore(combinator) {
|
|
|
1915
1988
|
};
|
|
1916
1989
|
const def = { tag: "oneOrMore", parser: combinator, min: 1 };
|
|
1917
1990
|
let expected;
|
|
1991
|
+
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
1918
1992
|
return {
|
|
1919
1993
|
_tag: "oneOrMore",
|
|
1920
1994
|
_meta: meta,
|
|
@@ -1925,7 +1999,7 @@ function oneOrMore(combinator) {
|
|
|
1925
1999
|
const values = def.valueUnused ? void 0 : [first.value];
|
|
1926
2000
|
let cur = first.span.end;
|
|
1927
2001
|
while (cur < input.length) {
|
|
1928
|
-
const item = repItem(combinator, input, cur, ctx);
|
|
2002
|
+
const item = repItem(combinator, input, cur, ctx, guardable);
|
|
1929
2003
|
if (item === "stop") break;
|
|
1930
2004
|
if ("fail" in item) {
|
|
1931
2005
|
const sync = ctx._tolerant ? ctx._sync : void 0;
|
|
@@ -1968,15 +2042,6 @@ function optional(combinator) {
|
|
|
1968
2042
|
}
|
|
1969
2043
|
};
|
|
1970
2044
|
}
|
|
1971
|
-
function startsFirstSet(combinator, input, pos) {
|
|
1972
|
-
const fs = combinator._meta.firstSet;
|
|
1973
|
-
if (fs.kind === "any") return true;
|
|
1974
|
-
if (fs.kind === "empty") return false;
|
|
1975
|
-
const code = input.codePointAt(pos);
|
|
1976
|
-
if (code === void 0) return false;
|
|
1977
|
-
for (const r of fs.ranges) if (code >= r.lo && code <= r.hi) return true;
|
|
1978
|
-
return false;
|
|
1979
|
-
}
|
|
1980
2045
|
function sepBy(combinator, separator) {
|
|
1981
2046
|
const meta = {
|
|
1982
2047
|
firstSet: combinator._meta.firstSet,
|
|
@@ -2510,11 +2575,20 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
2510
2575
|
const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : true);
|
|
2511
2576
|
const clonesState = build ? buildReadsState(def) : true;
|
|
2512
2577
|
const capturesFields = parserHasOwnFields(combinator) && (build ? buildReadsFields(def) : true);
|
|
2578
|
+
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
2579
|
+
let failExpected;
|
|
2513
2580
|
return {
|
|
2514
2581
|
_tag: "node",
|
|
2515
2582
|
_meta: meta,
|
|
2516
2583
|
_def: def,
|
|
2517
2584
|
parse(input, pos, ctx) {
|
|
2585
|
+
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
2586
|
+
if (failExpected === void 0) {
|
|
2587
|
+
const e = deriveExpected(combinator);
|
|
2588
|
+
failExpected = e.length > 0 ? e : [combinator._tag];
|
|
2589
|
+
}
|
|
2590
|
+
return { ok: false, expected: failExpected, span: { start: pos, end: pos } };
|
|
2591
|
+
}
|
|
2518
2592
|
const saved = beginCstNodeCapture(ctx);
|
|
2519
2593
|
const savedFields = ctx._fields;
|
|
2520
2594
|
ctx._fields = capturesFields ? [] : void 0;
|
|
@@ -4239,6 +4313,61 @@ function tryInlineDestructureTransform(src, valueVars) {
|
|
|
4239
4313
|
}
|
|
4240
4314
|
|
|
4241
4315
|
// src/compiler/codegen.ts
|
|
4316
|
+
function leadingFirstSetRecipe(p, seen = /* @__PURE__ */ new Set()) {
|
|
4317
|
+
if (seen.has(p)) return { concrete: empty(), refs: [] };
|
|
4318
|
+
seen.add(p);
|
|
4319
|
+
const d = p._def;
|
|
4320
|
+
const rec = (c) => leadingFirstSetRecipe(c, seen);
|
|
4321
|
+
const merge2 = (a, b) => ({ concrete: union(a.concrete, b.concrete), refs: [...a.refs, ...b.refs] });
|
|
4322
|
+
switch (d.tag) {
|
|
4323
|
+
case "lazy": {
|
|
4324
|
+
const name = p._ruleName;
|
|
4325
|
+
if (name !== void 0) return { concrete: empty(), refs: [name] };
|
|
4326
|
+
try {
|
|
4327
|
+
return rec(d.thunk());
|
|
4328
|
+
} catch {
|
|
4329
|
+
return { concrete: any(), refs: [] };
|
|
4330
|
+
}
|
|
4331
|
+
}
|
|
4332
|
+
case "literal":
|
|
4333
|
+
case "regex":
|
|
4334
|
+
case "keywords":
|
|
4335
|
+
return { concrete: p._meta.firstSet, refs: [] };
|
|
4336
|
+
case "choice": {
|
|
4337
|
+
let out = { concrete: empty(), refs: [] };
|
|
4338
|
+
for (const arm of d.parsers) out = merge2(out, rec(arm));
|
|
4339
|
+
return out;
|
|
4340
|
+
}
|
|
4341
|
+
case "sequence": {
|
|
4342
|
+
let out = { concrete: empty(), refs: [] };
|
|
4343
|
+
for (const term of d.parsers) {
|
|
4344
|
+
out = merge2(out, rec(term));
|
|
4345
|
+
if (!matchesEmpty(term)) return out;
|
|
4346
|
+
}
|
|
4347
|
+
return out;
|
|
4348
|
+
}
|
|
4349
|
+
case "oneOrMore":
|
|
4350
|
+
case "many":
|
|
4351
|
+
case "optional":
|
|
4352
|
+
case "transform":
|
|
4353
|
+
case "label":
|
|
4354
|
+
case "field":
|
|
4355
|
+
case "trivia":
|
|
4356
|
+
case "token":
|
|
4357
|
+
case "leaf":
|
|
4358
|
+
case "node":
|
|
4359
|
+
case "grammar":
|
|
4360
|
+
case "expect":
|
|
4361
|
+
return rec(d.parser);
|
|
4362
|
+
case "sepBy":
|
|
4363
|
+
return rec(d.parser);
|
|
4364
|
+
case "skip":
|
|
4365
|
+
return rec(d.main);
|
|
4366
|
+
// not / scanTo / guard / withCtx / recover / unknown → shallow set (safe).
|
|
4367
|
+
default:
|
|
4368
|
+
return { concrete: p._meta.firstSet, refs: [] };
|
|
4369
|
+
}
|
|
4370
|
+
}
|
|
4242
4371
|
var HOST_READS_DECL = "const _hostReads = (b, n) => { if (b === undefined) return false; let s; try { s = Function.prototype.toString.call(b) } catch (e) { return true } if (/\\barguments\\b/.test(s)) return true; const m = /^[^(]*\\(([\\s\\S]*?)\\)/.exec(s); if (m && /\\.\\.\\.|=/.test(m[1])) return true; return b.length > n }";
|
|
4243
4372
|
var _loweringSink = null;
|
|
4244
4373
|
function v(ctx, prefix = "_v") {
|
|
@@ -4472,6 +4601,7 @@ var SWITCH_RANGE_LIMIT = 4;
|
|
|
4472
4601
|
var SWITCH_MAX_CASES = 48;
|
|
4473
4602
|
var SWITCH_MIN_CASES = 3;
|
|
4474
4603
|
var _forceDisjointIf = false;
|
|
4604
|
+
var _forceNoSharedPrefix = false;
|
|
4475
4605
|
function planDisjointDispatch(parsers) {
|
|
4476
4606
|
const cases = [];
|
|
4477
4607
|
let total = 0;
|
|
@@ -5107,7 +5237,7 @@ function emitLiteralsLongestFirst(def, sortedIndices, allExpected, ctx, pos, cov
|
|
|
5107
5237
|
stmts.push(...emitElseFail(ctx, failArrBody(ctx, allExpected, pos)));
|
|
5108
5238
|
return { stmts, valueVar: valV, endVar: endV };
|
|
5109
5239
|
}
|
|
5110
|
-
function emitFirstMatch(def, ctx, pos, coverageBase) {
|
|
5240
|
+
function emitFirstMatch(def, ctx, pos, coverageBase, preStmts, armGuardPrefix) {
|
|
5111
5241
|
const resValV = v(ctx, "_crv");
|
|
5112
5242
|
const resEndV = v(ctx, "_cre");
|
|
5113
5243
|
const resOkV = v(ctx, "_crok");
|
|
@@ -5121,6 +5251,7 @@ function emitFirstMatch(def, ctx, pos, coverageBase) {
|
|
|
5121
5251
|
...autoRejectedV === void 0 ? [] : [`${ind0}const ${autoRejectedV} = []`],
|
|
5122
5252
|
`${ind0}const ${codeV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`
|
|
5123
5253
|
];
|
|
5254
|
+
if (preStmts) stmts.push(...preStmts);
|
|
5124
5255
|
for (let i = 0; i < def.parsers.length; i++) {
|
|
5125
5256
|
const p = def.parsers[i];
|
|
5126
5257
|
const gate = def.gates[i];
|
|
@@ -5128,11 +5259,12 @@ function emitFirstMatch(def, ctx, pos, coverageBase) {
|
|
|
5128
5259
|
const atStart = failsAtStart(p);
|
|
5129
5260
|
const staticFx = armStaticExpected(ctx, p);
|
|
5130
5261
|
const deferRuleName = ctx.deferFirstSetRefs ? p._ruleName : void 0;
|
|
5131
|
-
const
|
|
5262
|
+
const baseFsGuard = deferRuleName !== void 0 ? `/*@FS:${deferRuleName}:${codeV}@*/true` : needsFirstSetGuard(p) ? firstSetCond(codeV, p._meta.firstSet) : (() => {
|
|
5132
5263
|
if (p._meta.firstSet.kind !== "any" || matchesEmpty(p)) return null;
|
|
5133
5264
|
const deep = firstSetOf(p);
|
|
5134
5265
|
return deep.kind === "ranges" ? firstSetCond(codeV, deep) : null;
|
|
5135
5266
|
})();
|
|
5267
|
+
const fsGuard = armGuardPrefix === void 0 ? baseFsGuard : baseFsGuard === null ? armGuardPrefix : `${armGuardPrefix} && (${baseFsGuard})`;
|
|
5136
5268
|
let gateCond = null;
|
|
5137
5269
|
if (gate) {
|
|
5138
5270
|
const gateIdx = ctx.mapFns.length;
|
|
@@ -5201,11 +5333,64 @@ function emitFirstMatch(def, ctx, pos, coverageBase) {
|
|
|
5201
5333
|
stmts.push(...emitIfFail(ctx, `!${resOkV}`, failArrBody(ctx, concatExpr, pos, false)));
|
|
5202
5334
|
return { stmts, valueVar: resValV, endVar: resEndV };
|
|
5203
5335
|
}
|
|
5336
|
+
function emitsAsNamedFn(p, ctx) {
|
|
5337
|
+
if (p._def.tag === "lazy") return true;
|
|
5338
|
+
if (ctx.ruleNames?.has(p)) return true;
|
|
5339
|
+
if (ctx.namedParsers.has(p)) return true;
|
|
5340
|
+
const usage = ctx.lazyUsage;
|
|
5341
|
+
return !!usage && !ctx.noHoist && !ctx.capAsTrivia && isHoistableTag(p._def.tag) && (usage.counts.get(p) ?? 0) > 1 && (usage.sizes.get(p) ?? 0) >= HOIST_MIN_SUBTREE;
|
|
5342
|
+
}
|
|
5343
|
+
function armReplayInScope(arm, ctx) {
|
|
5344
|
+
let p = arm;
|
|
5345
|
+
for (; ; ) {
|
|
5346
|
+
if (emitsAsNamedFn(p, ctx)) return false;
|
|
5347
|
+
const d = p._def;
|
|
5348
|
+
if (d.tag === "node" || d.tag === "grammar" || d.tag === "transform" || d.tag === "label") {
|
|
5349
|
+
p = d.parser;
|
|
5350
|
+
continue;
|
|
5351
|
+
}
|
|
5352
|
+
return d.tag === "sequence";
|
|
5353
|
+
}
|
|
5354
|
+
}
|
|
5355
|
+
function emitSharedPrefix(def, strategy, ctx, pos) {
|
|
5356
|
+
const { prefix, members } = strategy;
|
|
5357
|
+
const savedCapturing = ctx.capturing;
|
|
5358
|
+
ctx.capturing = false;
|
|
5359
|
+
const pfx = emitFallible(prefix, ctx, pos, false);
|
|
5360
|
+
ctx.capturing = savedCapturing;
|
|
5361
|
+
const map = ctx.replayPrefix ??= /* @__PURE__ */ new Map();
|
|
5362
|
+
const keys = [];
|
|
5363
|
+
for (const i of members) {
|
|
5364
|
+
const term0 = leadingTermOfArm(def.parsers[i]);
|
|
5365
|
+
if (term0 === null) continue;
|
|
5366
|
+
map.set(term0, { valVar: pfx.valVar, endVar: pfx.endVar });
|
|
5367
|
+
keys.push(term0);
|
|
5368
|
+
}
|
|
5369
|
+
const r = emitFirstMatch(def, ctx, pos, void 0, pfx.stmts, pfx.okVar);
|
|
5370
|
+
for (const k of keys) map.delete(k);
|
|
5371
|
+
return r;
|
|
5372
|
+
}
|
|
5373
|
+
function emitReplayPrefixLeaf(ctx, pos, replay) {
|
|
5374
|
+
const vv = v(ctx);
|
|
5375
|
+
return {
|
|
5376
|
+
stmts: [
|
|
5377
|
+
`${ind(ctx)}const ${vv} = ${replay.valVar}`,
|
|
5378
|
+
...emitLeafCapture(ctx, vv, pos, replay.endVar)
|
|
5379
|
+
],
|
|
5380
|
+
valueVar: vv,
|
|
5381
|
+
endVar: replay.endVar
|
|
5382
|
+
};
|
|
5383
|
+
}
|
|
5204
5384
|
function emitNonDisjoint(def, strategy, allExpected, ctx, pos, coverageBase) {
|
|
5205
5385
|
if (strategy.tag === "greedyClassify")
|
|
5206
5386
|
return emitGreedyClassify(def, strategy.superIndex, ctx, pos, coverageBase);
|
|
5207
5387
|
if (strategy.tag === "literalsLongestFirst")
|
|
5208
5388
|
return emitLiteralsLongestFirst(def, strategy.sortedIndices, allExpected, ctx, pos, coverageBase);
|
|
5389
|
+
if (strategy.tag === "sharedPrefix") {
|
|
5390
|
+
if (!_forceNoSharedPrefix && coverageBase === void 0 && !ctx.recovery && strategy.members.every((i) => armReplayInScope(def.parsers[i], ctx)))
|
|
5391
|
+
return emitSharedPrefix(def, strategy, ctx, pos);
|
|
5392
|
+
return emitFirstMatch(def, ctx, pos, coverageBase);
|
|
5393
|
+
}
|
|
5209
5394
|
return emitFirstMatch(def, ctx, pos, coverageBase);
|
|
5210
5395
|
}
|
|
5211
5396
|
function pushMapFn(ctx, fn, src) {
|
|
@@ -5285,6 +5470,13 @@ function emitMany(def, ctx, pos) {
|
|
|
5285
5470
|
itemPos = npV;
|
|
5286
5471
|
}
|
|
5287
5472
|
}
|
|
5473
|
+
if (!ctx.recovery && !ctx.coverage && !failsAtStart(def.parser) && needsFirstSetGuard(def.parser)) {
|
|
5474
|
+
const lcV = v(ctx, "_lc");
|
|
5475
|
+
stmts.push(
|
|
5476
|
+
`${ind(ctx)}const ${lcV} = ${itemPos} < input.length ? (input.codePointAt(${itemPos}) ?? -1) : -1`,
|
|
5477
|
+
`${ind(ctx)}if (!(${firstSetCond(lcV, def.parser._meta.firstSet)})) { ${rollback}break }`
|
|
5478
|
+
);
|
|
5479
|
+
}
|
|
5288
5480
|
const { stmts: iterStmts, okVar: iterOk, valVar: iterVal, endVar: iterEnd } = emitFallible(def.parser, ctx, itemPos, true);
|
|
5289
5481
|
stmts.push(...iterStmts);
|
|
5290
5482
|
if (ctx.recovery) {
|
|
@@ -5335,8 +5527,19 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
5335
5527
|
const rollback = `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${leaves}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${raw}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${trivia2}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${log}; if (_ctx._fields) _ctx._fields.length = ${fields}; if (_ctx._errors) _ctx._errors.length = ${errors}`;
|
|
5336
5528
|
const traceId = ctx.coverage?.plan.attempts.get(p);
|
|
5337
5529
|
const traceRollback = traceId === void 0 ? "" : ` _ctx._grammarTrace?.write({ id: ${JSON.stringify(traceId)}, phase: 'rollback', offset: ${pos} });`;
|
|
5530
|
+
const preGuard = [];
|
|
5531
|
+
if (!ctx.recovery && !ctx.coverage && needsFirstSetGuard(def.parser)) {
|
|
5532
|
+
const gcV = v(ctx, "_agc");
|
|
5533
|
+
const gExp = armStaticExpected(ctx, def.parser);
|
|
5534
|
+
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(gExp, pos)} }`;
|
|
5535
|
+
preGuard.push(
|
|
5536
|
+
`${ind(ctx)}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
5537
|
+
`${ind(ctx)}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
5538
|
+
);
|
|
5539
|
+
}
|
|
5338
5540
|
return {
|
|
5339
5541
|
stmts: [
|
|
5542
|
+
...preGuard,
|
|
5340
5543
|
`${ind(ctx)}const ${leaves} = _ctx._cstLeaves?.length ?? 0, ${raw} = _ctx._cstRawChildren?.length ?? 0, ${trivia2} = _ctx._cstTriviaLog?.length ?? 0, ${log} = _ctx._triviaLog?.length ?? 0, ${fields} = _ctx._fields?.length ?? 0, ${errors} = _ctx._errors?.length ?? 0`,
|
|
5341
5544
|
...inner.stmts,
|
|
5342
5545
|
...emitIfFail(ctx, `!${inner.okVar}`, `{ ${rollback};${traceRollback} _ctx._fe = ${pos}; ${propagateFailBody(ctx)} }`)
|
|
@@ -5716,7 +5919,18 @@ ${i}const ${chV} = ${profileRecognizer} ? undefined : [], ${rawV} = ${profileRec
|
|
|
5716
5919
|
const saveTrivia = needsTriviaFrame ? `, ${st} = _ctx.captureTrivia, ${stl} = _ctx._cstTriviaLog${smk ? `, ${smk} = _ctx._triviaCaptureMask` : ""}` : "";
|
|
5717
5920
|
const installTrivia = needsTriviaFrame ? `; _ctx.captureTrivia = ${capTLv ?? "false"}; _ctx._cstTriviaLog = ${innerTl}${smk ? `; _ctx._triviaCaptureMask = ${capTLv} && _ctx.build !== undefined && _ctx.build._parsemanTriviaKinds !== undefined ? _ctx.build._parsemanTriviaKinds(${JSON.stringify(def.type)}) : ${smk}` : ""}` : "";
|
|
5718
5921
|
const restoreTrivia = needsTriviaFrame ? `; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}${smk ? `; _ctx._triviaCaptureMask = ${smk}` : ""}` : "";
|
|
5922
|
+
const preGuard = [];
|
|
5923
|
+
if (!ctx.recovery && !ctx.coverage && (capturesChildren || structural) && needsFirstSetGuard(def.parser)) {
|
|
5924
|
+
const gcV = v(ctx, "_ngc");
|
|
5925
|
+
const gExp = armStaticExpected(ctx, def.parser);
|
|
5926
|
+
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(gExp, pos);
|
|
5927
|
+
preGuard.push(
|
|
5928
|
+
`${i}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
5929
|
+
`${i}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
5930
|
+
);
|
|
5931
|
+
}
|
|
5719
5932
|
const stmts = [
|
|
5933
|
+
...preGuard,
|
|
5720
5934
|
profHoist,
|
|
5721
5935
|
allocStmt,
|
|
5722
5936
|
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren${saveTrivia}${sf ? `, ${sf} = _ctx._fields` : ""}`,
|
|
@@ -5890,6 +6104,8 @@ function emitExpect(def, ctx, pos) {
|
|
|
5890
6104
|
return { stmts, valueVar: valVar, endVar };
|
|
5891
6105
|
}
|
|
5892
6106
|
function emit(p, ctx, pos) {
|
|
6107
|
+
const replay = ctx.replayPrefix?.get(p);
|
|
6108
|
+
if (replay !== void 0) return emitReplayPrefixLeaf(ctx, pos, replay);
|
|
5893
6109
|
const dispatch = (emissionPos = pos) => {
|
|
5894
6110
|
const savedRule = ctx.activeCoverageRuleId;
|
|
5895
6111
|
const rule = ctx.coverage?.plan.rules.get(p);
|
|
@@ -6633,6 +6849,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
6633
6849
|
].join("\n")));
|
|
6634
6850
|
}
|
|
6635
6851
|
const firstSets = /* @__PURE__ */ new Map();
|
|
6852
|
+
const firstSetRecipes = /* @__PURE__ */ new Map();
|
|
6636
6853
|
for (const [key, rule] of ruleMap) {
|
|
6637
6854
|
let resolved = rule;
|
|
6638
6855
|
const d = rule._def;
|
|
@@ -6644,6 +6861,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
6644
6861
|
}
|
|
6645
6862
|
}
|
|
6646
6863
|
firstSets.set(key, canMatchEmptyAtStart(resolved) ? { kind: "any" } : resolved._meta.firstSet);
|
|
6864
|
+
firstSetRecipes.set(key, canMatchEmptyAtStart(resolved) ? { concrete: any(), refs: [] } : leadingFirstSetRecipe(resolved));
|
|
6647
6865
|
}
|
|
6648
6866
|
return {
|
|
6649
6867
|
ns,
|
|
@@ -6652,6 +6870,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
6652
6870
|
ruleFns,
|
|
6653
6871
|
wrappers,
|
|
6654
6872
|
firstSets,
|
|
6873
|
+
firstSetRecipes,
|
|
6655
6874
|
deps: ruleDependencies(ruleMap),
|
|
6656
6875
|
needsEmptyTl: !!ctx.needsEmptyTl,
|
|
6657
6876
|
needsHostReads: !!ctx.needsHostReads,
|
|
@@ -7287,10 +7506,30 @@ function fusedBody(pieces) {
|
|
|
7287
7506
|
];
|
|
7288
7507
|
const wrapperEntries = [...winner].map(([k, p]) => `${JSON.stringify(k)}: ${p.wrappers.get(k)}`);
|
|
7289
7508
|
const rawBody = [...lines, "return {", wrapperEntries.join(",\n"), "}"].join("\n");
|
|
7290
|
-
const
|
|
7509
|
+
const ANY2 = { kind: "any" };
|
|
7510
|
+
const recipes = /* @__PURE__ */ new Map();
|
|
7511
|
+
const shallow = /* @__PURE__ */ new Map();
|
|
7291
7512
|
for (const [k, p] of winner) {
|
|
7513
|
+
const r = p.firstSetRecipes?.get(k);
|
|
7514
|
+
if (r) recipes.set(k, r);
|
|
7292
7515
|
const fs = p.firstSets?.get(k);
|
|
7293
|
-
if (fs)
|
|
7516
|
+
if (fs) shallow.set(k, fs);
|
|
7517
|
+
}
|
|
7518
|
+
const finalFS = /* @__PURE__ */ new Map();
|
|
7519
|
+
for (const [k] of winner) finalFS.set(k, recipes.get(k)?.concrete ?? shallow.get(k) ?? ANY2);
|
|
7520
|
+
for (let iter = 0; iter <= recipes.size; iter++) {
|
|
7521
|
+
let changed = false;
|
|
7522
|
+
for (const [k, r] of recipes) {
|
|
7523
|
+
let fs = r.concrete;
|
|
7524
|
+
for (const ref2 of r.refs) {
|
|
7525
|
+
fs = union(fs, recipes.has(ref2) || shallow.has(ref2) ? finalFS.get(ref2) ?? ANY2 : ANY2);
|
|
7526
|
+
}
|
|
7527
|
+
if (JSON.stringify(finalFS.get(k)) !== JSON.stringify(fs)) {
|
|
7528
|
+
finalFS.set(k, fs);
|
|
7529
|
+
changed = true;
|
|
7530
|
+
}
|
|
7531
|
+
}
|
|
7532
|
+
if (!changed) break;
|
|
7294
7533
|
}
|
|
7295
7534
|
const body = rawBody.replace(
|
|
7296
7535
|
// Rule name + code-point var are both JS identifiers (rule names are validated
|