parseman 0.17.0 → 0.18.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/README.md +1 -1
- package/dist/combinators/expect.d.ts +2 -2
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/token.d.ts +10 -0
- package/dist/combinators/token.d.ts.map +1 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/value-usage.d.ts.map +1 -1
- package/dist/index.cjs +205 -18
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +205 -18
- package/dist/index.js.map +3 -3
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +207 -16
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.js +207 -16
- package/dist/plugin/index.js.map +3 -3
- package/dist/types.d.ts +3 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,7 +71,7 @@ See **[The three modes](https://matthew-dean.github.io/parseman/guide/modes)** f
|
|
|
71
71
|
|
|
72
72
|
## What's in the box
|
|
73
73
|
|
|
74
|
-
- **[Combinators](https://matthew-dean.github.io/parseman/guide/combinators)** — `literal`, `regex`, `sequence`, `choice`, `many`, `sepBy`, `not`, and more.
|
|
74
|
+
- **[Combinators](https://matthew-dean.github.io/parseman/guide/combinators)** — `literal`, `regex`, `sequence`, `choice`, `many`, `sepBy`, `token`, `not`, and more.
|
|
75
75
|
- **[Whitespace & trivia](https://matthew-dean.github.io/parseman/guide/trivia)** — grammar-defined filler skipping, with per-chunk kind capture.
|
|
76
76
|
- **[Recursive rules](https://matthew-dean.github.io/parseman/guide/recursive-rules)** — `rules()` for mutually recursive grammars; fully macro-compilable.
|
|
77
77
|
- **[CST / AST nodes](https://matthew-dean.github.io/parseman/guide/ast)** — `node()` captures terminals and trivia for you, with a `collapse` option for transparent wrapper rules.
|
|
@@ -14,7 +14,7 @@ export type { ParseError };
|
|
|
14
14
|
* the interpreter and the compiled output (the compiled path does not rebuild the
|
|
15
15
|
* runtime `expected` array, so it reads this precomputed set instead).
|
|
16
16
|
*/
|
|
17
|
-
export declare function
|
|
17
|
+
export declare function deriveExpected(c: Combinator<unknown>): string[];
|
|
18
18
|
/**
|
|
19
19
|
* Required-token combinator. Tries `combinator`; on success returns it verbatim.
|
|
20
20
|
* On failure it does NOT fail — it records a {@link ParseError} (the statically
|
|
@@ -26,7 +26,7 @@ export declare function staticExpected(c: Combinator<unknown>): string[];
|
|
|
26
26
|
* block) so a missing one is reported with position + expectation rather than
|
|
27
27
|
* aborting the whole parse or being silently swallowed by a catch-all.
|
|
28
28
|
*
|
|
29
|
-
* sequence(literal('{'), declList, expect(literal('}')
|
|
29
|
+
* sequence(literal('{'), declList, expect(literal('}')))
|
|
30
30
|
*
|
|
31
31
|
* Errors are only collected when the parse runs with `{ recover: true }`; without
|
|
32
32
|
* it, expect() still recovers in place but records nothing (zero overhead beyond
|
|
@@ -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;AAEhG,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;AAEhG,YAAY,EAAE,UAAU,EAAE,CAAA;AAE1B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,MAAM,EAAE,CA4B/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,CAmB/F"}
|
|
@@ -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,
|
|
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,CAoCxG;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,CAqCvG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/combinators/map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,aAAa,CAAA;AAGxE,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,EAC5B,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KAAK,CAAC,GACxD,UAAU,CAAC,CAAC,CAAC,CAWf;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAarF;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAYlE;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/combinators/map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,aAAa,CAAA;AAGxE,wBAAgB,SAAS,CAAC,CAAC,EAAE,CAAC,EAC5B,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KAAK,CAAC,GACxD,UAAU,CAAC,CAAC,CAAC,CAWf;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAarF;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAYlE;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAW/E"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Combinator } from '../types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Treat a parser as one source token.
|
|
4
|
+
*
|
|
5
|
+
* The wrapped parser runs with trivia cleared, so its parts must be contiguous.
|
|
6
|
+
* On success the token returns the matched source text and captures one CST leaf
|
|
7
|
+
* for the full span, suppressing any internal terminal leaves.
|
|
8
|
+
*/
|
|
9
|
+
export declare function token(root: Combinator<unknown>): Combinator<string>;
|
|
10
|
+
//# sourceMappingURL=token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/combinators/token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAyC,MAAM,aAAa,CAAA;AAGpF;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAqDnE"}
|
|
@@ -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,EAAkB,MAAM,aAAa,CAAA;AAyBzH;;;;;;;;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;AA6bD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,GAAG,MAAM,CAQlE;AAcD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,OAAO,GAAG,IAAI,CAA0B;
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/compiler/codegen.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ir-serialize.d.ts","sourceRoot":"","sources":["../../src/compiler/ir-serialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"ir-serialize.d.ts","sourceRoot":"","sources":["../../src/compiler/ir-serialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;AAiBxD,KAAK,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAA;AA2C/B,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,GAC9C,MAAM,GAAG,IAAI,CAUf;AAED;;oFAEoF;AACpF,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAgC/D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"value-usage.d.ts","sourceRoot":"","sources":["../../src/compiler/value-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;AAExD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"value-usage.d.ts","sourceRoot":"","sources":["../../src/compiler/value-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;AAExD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAwGhE"}
|
package/dist/index.cjs
CHANGED
|
@@ -85,7 +85,7 @@ __export(index_exports, {
|
|
|
85
85
|
sequence: () => sequence,
|
|
86
86
|
shiftAbsolute: () => shiftAbsolute,
|
|
87
87
|
skip: () => skip,
|
|
88
|
-
|
|
88
|
+
token: () => token,
|
|
89
89
|
transform: () => transform,
|
|
90
90
|
trivia: () => trivia,
|
|
91
91
|
triviaEntries: () => triviaEntries,
|
|
@@ -155,6 +155,7 @@ function matchesEmpty(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
155
155
|
case "transform":
|
|
156
156
|
case "label":
|
|
157
157
|
case "trivia":
|
|
158
|
+
case "token":
|
|
158
159
|
case "expect":
|
|
159
160
|
case "withCtx":
|
|
160
161
|
case "node":
|
|
@@ -217,6 +218,7 @@ function firstSetOf(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
217
218
|
case "transform":
|
|
218
219
|
case "label":
|
|
219
220
|
case "trivia":
|
|
221
|
+
case "token":
|
|
220
222
|
case "node":
|
|
221
223
|
case "grammar":
|
|
222
224
|
case "expect":
|
|
@@ -1343,6 +1345,7 @@ function markUnusedValues(root) {
|
|
|
1343
1345
|
return;
|
|
1344
1346
|
case "label":
|
|
1345
1347
|
case "trivia":
|
|
1348
|
+
case "token":
|
|
1346
1349
|
case "withCtx":
|
|
1347
1350
|
case "expect":
|
|
1348
1351
|
visit(def.parser, consumed);
|
|
@@ -1544,7 +1547,11 @@ function label(name, combinator) {
|
|
|
1544
1547
|
_tag: combinator._tag,
|
|
1545
1548
|
_meta: combinator._meta,
|
|
1546
1549
|
_def: { tag: "label", label: name, parser: combinator },
|
|
1547
|
-
parse
|
|
1550
|
+
parse(input, pos, ctx) {
|
|
1551
|
+
const result = combinator.parse(input, pos, ctx);
|
|
1552
|
+
if (!result.ok) return { ...result, expected: [name] };
|
|
1553
|
+
return result;
|
|
1554
|
+
}
|
|
1548
1555
|
};
|
|
1549
1556
|
}
|
|
1550
1557
|
|
|
@@ -1643,8 +1650,60 @@ function parse(combinator, input, opts = {}) {
|
|
|
1643
1650
|
return withErrors;
|
|
1644
1651
|
}
|
|
1645
1652
|
|
|
1653
|
+
// src/combinators/token.ts
|
|
1654
|
+
function token(root) {
|
|
1655
|
+
const meta = {
|
|
1656
|
+
firstSet: root._meta.firstSet,
|
|
1657
|
+
canMatchNewline: root._meta.canMatchNewline,
|
|
1658
|
+
isTrivia: false
|
|
1659
|
+
};
|
|
1660
|
+
return {
|
|
1661
|
+
_tag: "token",
|
|
1662
|
+
_meta: meta,
|
|
1663
|
+
_def: { tag: "token", parser: root },
|
|
1664
|
+
parse(input, pos, ctx) {
|
|
1665
|
+
const savedTrivia = ctx.trivia;
|
|
1666
|
+
const savedKinds = ctx.triviaKindLabels;
|
|
1667
|
+
const savedBuf = ctx._cstBuf;
|
|
1668
|
+
const savedChildren = ctx._cstChildren;
|
|
1669
|
+
const savedLeaves = ctx._cstLeaves;
|
|
1670
|
+
const savedRaw = ctx._cstRawChildren;
|
|
1671
|
+
const savedTriviaLog = ctx._cstTriviaLog;
|
|
1672
|
+
const savedOuterTriviaLog = ctx._triviaLog;
|
|
1673
|
+
const wasCapturing = cstCaptureActive(ctx);
|
|
1674
|
+
ctx.trivia = void 0;
|
|
1675
|
+
ctx.triviaKindLabels = void 0;
|
|
1676
|
+
ctx._cstBuf = void 0;
|
|
1677
|
+
ctx._cstChildren = void 0;
|
|
1678
|
+
ctx._cstLeaves = void 0;
|
|
1679
|
+
ctx._cstRawChildren = void 0;
|
|
1680
|
+
ctx._cstTriviaLog = void 0;
|
|
1681
|
+
delete ctx._triviaLog;
|
|
1682
|
+
let result;
|
|
1683
|
+
try {
|
|
1684
|
+
result = root.parse(input, pos, ctx);
|
|
1685
|
+
} finally {
|
|
1686
|
+
ctx.trivia = savedTrivia;
|
|
1687
|
+
ctx.triviaKindLabels = savedKinds;
|
|
1688
|
+
ctx._cstBuf = savedBuf;
|
|
1689
|
+
ctx._cstChildren = savedChildren;
|
|
1690
|
+
ctx._cstLeaves = savedLeaves;
|
|
1691
|
+
ctx._cstRawChildren = savedRaw;
|
|
1692
|
+
ctx._cstTriviaLog = savedTriviaLog;
|
|
1693
|
+
if (savedOuterTriviaLog === void 0) delete ctx._triviaLog;
|
|
1694
|
+
else ctx._triviaLog = savedOuterTriviaLog;
|
|
1695
|
+
}
|
|
1696
|
+
if (!result.ok) return result;
|
|
1697
|
+
const span = result.span;
|
|
1698
|
+
const value = input.slice(pos, span.end);
|
|
1699
|
+
if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
1700
|
+
return { ok: true, value, span };
|
|
1701
|
+
}
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1646
1705
|
// src/combinators/expect.ts
|
|
1647
|
-
function
|
|
1706
|
+
function deriveExpected(c) {
|
|
1648
1707
|
const def = c._def;
|
|
1649
1708
|
switch (def.tag) {
|
|
1650
1709
|
case "literal":
|
|
@@ -1656,22 +1715,23 @@ function staticExpected(c) {
|
|
|
1656
1715
|
case "label":
|
|
1657
1716
|
return [def.label];
|
|
1658
1717
|
case "choice":
|
|
1659
|
-
return def.parsers.flatMap(
|
|
1718
|
+
return def.parsers.flatMap(deriveExpected);
|
|
1660
1719
|
case "sequence":
|
|
1661
|
-
return def.parsers.length > 0 ?
|
|
1720
|
+
return def.parsers.length > 0 ? deriveExpected(def.parsers[0]) : [];
|
|
1662
1721
|
case "node":
|
|
1663
1722
|
case "grammar":
|
|
1664
1723
|
case "trivia":
|
|
1724
|
+
case "token":
|
|
1665
1725
|
case "optional":
|
|
1666
1726
|
case "many":
|
|
1667
1727
|
case "oneOrMore":
|
|
1668
1728
|
case "transform":
|
|
1669
1729
|
case "not":
|
|
1670
|
-
return
|
|
1730
|
+
return deriveExpected(def.parser);
|
|
1671
1731
|
case "lazy": {
|
|
1672
1732
|
const name = c._ruleName;
|
|
1673
1733
|
try {
|
|
1674
|
-
return
|
|
1734
|
+
return deriveExpected(def.thunk());
|
|
1675
1735
|
} catch {
|
|
1676
1736
|
return name ? [name] : [];
|
|
1677
1737
|
}
|
|
@@ -1681,7 +1741,7 @@ function staticExpected(c) {
|
|
|
1681
1741
|
}
|
|
1682
1742
|
}
|
|
1683
1743
|
function expect(combinator, label2) {
|
|
1684
|
-
const expected = label2 !== void 0 ? [label2] :
|
|
1744
|
+
const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
|
|
1685
1745
|
const meta = {
|
|
1686
1746
|
firstSet: combinator._meta.firstSet,
|
|
1687
1747
|
canMatchNewline: combinator._meta.canMatchNewline,
|
|
@@ -3333,6 +3393,7 @@ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3333
3393
|
case "guard":
|
|
3334
3394
|
case "not":
|
|
3335
3395
|
case "trivia":
|
|
3396
|
+
case "token":
|
|
3336
3397
|
case "scanTo":
|
|
3337
3398
|
case "unknown":
|
|
3338
3399
|
return false;
|
|
@@ -3394,6 +3455,7 @@ function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
3394
3455
|
case "regex":
|
|
3395
3456
|
case "keywords":
|
|
3396
3457
|
case "node":
|
|
3458
|
+
case "token":
|
|
3397
3459
|
return true;
|
|
3398
3460
|
case "not":
|
|
3399
3461
|
case "guard":
|
|
@@ -3672,9 +3734,9 @@ function emitSeq(def, ctx, pos) {
|
|
|
3672
3734
|
stmts.push(`${ind(ctx)}const ${arrV} = [${valueVars.join(", ")}]`);
|
|
3673
3735
|
return { stmts, valueVar: arrV, endVar };
|
|
3674
3736
|
}
|
|
3675
|
-
function
|
|
3737
|
+
function deriveExpectedArr(parsers) {
|
|
3676
3738
|
return JSON.stringify(parsers.flatMap((p) => {
|
|
3677
|
-
const e =
|
|
3739
|
+
const e = deriveExpected(p);
|
|
3678
3740
|
return e.length > 0 ? e : [p._tag];
|
|
3679
3741
|
}));
|
|
3680
3742
|
}
|
|
@@ -3695,7 +3757,7 @@ function failsAtStart(p) {
|
|
|
3695
3757
|
}
|
|
3696
3758
|
}
|
|
3697
3759
|
function armStaticExpected(ctx, p) {
|
|
3698
|
-
return hoistExpected(ctx,
|
|
3760
|
+
return hoistExpected(ctx, deriveExpectedArr([p]));
|
|
3699
3761
|
}
|
|
3700
3762
|
function canMatchEmptyAtStart(p) {
|
|
3701
3763
|
const d = p._def;
|
|
@@ -3733,7 +3795,7 @@ function emitDisjointArm(p, ctx, pos, valV, endV) {
|
|
|
3733
3795
|
];
|
|
3734
3796
|
}
|
|
3735
3797
|
function emitChoice(def, ctx, pos) {
|
|
3736
|
-
const allExpected =
|
|
3798
|
+
const allExpected = deriveExpectedArr(def.parsers);
|
|
3737
3799
|
if (def.disjoint) {
|
|
3738
3800
|
const codeV = v(ctx, "_code");
|
|
3739
3801
|
const valV = v(ctx, "_chv");
|
|
@@ -3794,7 +3856,7 @@ function emitGreedyClassify(def, superIndex, ctx, pos) {
|
|
|
3794
3856
|
const wordV = v(ctx, "_gw");
|
|
3795
3857
|
const endV = v(ctx, "_ge");
|
|
3796
3858
|
const valV = v(ctx, "_gcv");
|
|
3797
|
-
const regexExpected = JSON.stringify(
|
|
3859
|
+
const regexExpected = JSON.stringify(deriveExpected(superParser));
|
|
3798
3860
|
const stmts = [
|
|
3799
3861
|
`${ind(ctx)}${reVar}.lastIndex = ${pos}`,
|
|
3800
3862
|
`${ind(ctx)}const ${matchV} = ${reVar}.exec(input)`,
|
|
@@ -4186,6 +4248,116 @@ function emitNot(def, ctx, pos) {
|
|
|
4186
4248
|
endVar: pos
|
|
4187
4249
|
};
|
|
4188
4250
|
}
|
|
4251
|
+
function escapeTokenLiteral(value) {
|
|
4252
|
+
return value.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
|
|
4253
|
+
}
|
|
4254
|
+
function regexMatchesEmpty(source, flags) {
|
|
4255
|
+
try {
|
|
4256
|
+
return new RegExp(`^(?:${source})$`, flags).test("");
|
|
4257
|
+
} catch {
|
|
4258
|
+
return true;
|
|
4259
|
+
}
|
|
4260
|
+
}
|
|
4261
|
+
function tokenTerminalSource(p) {
|
|
4262
|
+
const def = p._def;
|
|
4263
|
+
switch (def.tag) {
|
|
4264
|
+
case "literal":
|
|
4265
|
+
if (def.value.length === 0) return null;
|
|
4266
|
+
return {
|
|
4267
|
+
source: escapeTokenLiteral(def.value),
|
|
4268
|
+
caseInsensitive: def.caseInsensitive,
|
|
4269
|
+
rawCaseSensitive: def.caseInsensitive ? "" : def.value
|
|
4270
|
+
};
|
|
4271
|
+
case "regex": {
|
|
4272
|
+
if (def.flags.replace(/i/g, "") !== "") return null;
|
|
4273
|
+
if (regexMatchesEmpty(def.source, def.flags)) return null;
|
|
4274
|
+
return {
|
|
4275
|
+
source: `(?:${def.source})`,
|
|
4276
|
+
caseInsensitive: def.flags.includes("i"),
|
|
4277
|
+
rawCaseSensitive: def.flags.includes("i") ? "" : def.source
|
|
4278
|
+
};
|
|
4279
|
+
}
|
|
4280
|
+
default:
|
|
4281
|
+
return null;
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
function tokenSequenceSource(p) {
|
|
4285
|
+
const def = p._def;
|
|
4286
|
+
const parts = def.tag === "sequence" ? def.parsers.map(tokenTerminalSource) : [tokenTerminalSource(p)];
|
|
4287
|
+
if (parts.some((part) => part === null)) return null;
|
|
4288
|
+
const typed = parts;
|
|
4289
|
+
const flags = typed.some((part) => part.caseInsensitive) ? "i" : "";
|
|
4290
|
+
if (flags.includes("i") && typed.some((part) => /[A-Za-z]/.test(part.rawCaseSensitive))) return null;
|
|
4291
|
+
return {
|
|
4292
|
+
source: typed.map((part) => part.source).join(""),
|
|
4293
|
+
flags,
|
|
4294
|
+
hasCaseSensitiveLetters: typed.some((part) => /[A-Za-z]/.test(part.rawCaseSensitive))
|
|
4295
|
+
};
|
|
4296
|
+
}
|
|
4297
|
+
function combineTokenRegexSources(parts) {
|
|
4298
|
+
const flags = parts.some((part) => part.flags.includes("i")) ? "i" : "";
|
|
4299
|
+
if (flags.includes("i") && parts.some((part) => part.flags === "" && part.hasCaseSensitiveLetters)) return null;
|
|
4300
|
+
return { source: parts.map((part) => part.source).join(""), flags };
|
|
4301
|
+
}
|
|
4302
|
+
function tokenNullableRegex(def) {
|
|
4303
|
+
const inner = def.parser._def;
|
|
4304
|
+
if (inner.tag === "many") {
|
|
4305
|
+
const seq = tokenSequenceSource(inner.parser);
|
|
4306
|
+
if (!seq) return null;
|
|
4307
|
+
return { tag: "regex", source: `(?:${seq.source})*`, flags: seq.flags };
|
|
4308
|
+
}
|
|
4309
|
+
if (inner.tag === "optional") {
|
|
4310
|
+
const seq = tokenSequenceSource(inner.parser);
|
|
4311
|
+
if (!seq) return null;
|
|
4312
|
+
return { tag: "regex", source: `(?:${seq.source})?`, flags: seq.flags };
|
|
4313
|
+
}
|
|
4314
|
+
if (inner.tag === "sepBy") {
|
|
4315
|
+
const item = tokenSequenceSource(inner.parser);
|
|
4316
|
+
const sep = tokenSequenceSource(inner.separator);
|
|
4317
|
+
if (!item || !sep) return null;
|
|
4318
|
+
const combined = combineTokenRegexSources([item, sep]);
|
|
4319
|
+
if (!combined) return null;
|
|
4320
|
+
return { tag: "regex", source: `(?:${item.source}(?:${sep.source}${item.source})*)?`, flags: combined.flags };
|
|
4321
|
+
}
|
|
4322
|
+
return null;
|
|
4323
|
+
}
|
|
4324
|
+
function emitToken(def, ctx, pos) {
|
|
4325
|
+
const lowered = tokenNullableRegex(def);
|
|
4326
|
+
if (lowered) return emitRegex(lowered, ctx, pos);
|
|
4327
|
+
const savedTrivia = ctx.activeTrivia;
|
|
4328
|
+
const savedKindLabels = ctx.triviaKindLabels;
|
|
4329
|
+
ctx.activeTrivia = void 0;
|
|
4330
|
+
ctx.triviaKindLabels = void 0;
|
|
4331
|
+
const inner = emitFallible(def.parser, ctx, pos);
|
|
4332
|
+
ctx.activeTrivia = savedTrivia;
|
|
4333
|
+
ctx.triviaKindLabels = savedKindLabels;
|
|
4334
|
+
const i = ind(ctx);
|
|
4335
|
+
const sc = v(ctx, "_tokCh");
|
|
4336
|
+
const sl = v(ctx, "_tokLv");
|
|
4337
|
+
const sr = v(ctx, "_tokRaw");
|
|
4338
|
+
const sv = v(ctx, "_tokTr");
|
|
4339
|
+
const sk = v(ctx, "_tokKinds");
|
|
4340
|
+
const stl = v(ctx, "_tokTl");
|
|
4341
|
+
const sol = v(ctx, "_tokLog");
|
|
4342
|
+
const sb = v(ctx, "_tokBuf");
|
|
4343
|
+
const valV = v(ctx, "_tok");
|
|
4344
|
+
return {
|
|
4345
|
+
stmts: [
|
|
4346
|
+
`${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${sv} = _ctx.trivia, ${sk} = _ctx.triviaKindLabels, ${stl} = _ctx._cstTriviaLog, ${sol} = _ctx._triviaLog, ${sb} = _ctx._cstBuf`,
|
|
4347
|
+
`${i}_ctx.trivia = undefined; _ctx.triviaKindLabels = undefined; _ctx._cstChildren = undefined; _ctx._cstLeaves = undefined; _ctx._cstRawChildren = undefined; _ctx._cstTriviaLog = undefined; _ctx._triviaLog = undefined; _ctx._cstBuf = undefined`,
|
|
4348
|
+
`${i}try {`,
|
|
4349
|
+
...reindentStmts(inner.stmts, ctx.indent + 1).map((stmt) => stmt.replace(/^(\s*)(?:const|let)\s+/, "$1var ")),
|
|
4350
|
+
`${i}} finally {`,
|
|
4351
|
+
`${i} _ctx.trivia = ${sv}; _ctx.triviaKindLabels = ${sk}; _ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx._cstTriviaLog = ${stl}; _ctx._triviaLog = ${sol}; _ctx._cstBuf = ${sb}`,
|
|
4352
|
+
`${i}}`,
|
|
4353
|
+
...emitIfFail(ctx, `!${inner.okVar}`, propagateFailBody(ctx)),
|
|
4354
|
+
`${i}const ${valV} = input.slice(${pos}, ${inner.endVar})`,
|
|
4355
|
+
...emitLeafCapture(ctx, valV, pos, inner.endVar)
|
|
4356
|
+
],
|
|
4357
|
+
valueVar: valV,
|
|
4358
|
+
endVar: inner.endVar
|
|
4359
|
+
};
|
|
4360
|
+
}
|
|
4189
4361
|
function emitNode(def, ctx, pos) {
|
|
4190
4362
|
const structural = def.build === void 0;
|
|
4191
4363
|
const mkType = structural ? null : analyzeMkInlineBuild(def);
|
|
@@ -4305,7 +4477,7 @@ function emitRecover(def, ctx, pos) {
|
|
|
4305
4477
|
`${ind0} if (${sentOk}) break`,
|
|
4306
4478
|
`${ind0} ${scanV}++`,
|
|
4307
4479
|
`${ind0} }`,
|
|
4308
|
-
`${ind0} const ${errV} = { _tag: 'parseError', span: { start: ${pos}, end: ${scanV} }, expected: ${JSON.stringify(
|
|
4480
|
+
`${ind0} const ${errV} = { _tag: 'parseError', span: { start: ${pos}, end: ${scanV} }, expected: ${JSON.stringify(deriveExpected(def.parser))} }`,
|
|
4309
4481
|
`${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
|
|
4310
4482
|
`${ind0} ${valVar} = ${errV}`,
|
|
4311
4483
|
`${ind0} ${endVar} = ${scanV}`,
|
|
@@ -4435,8 +4607,19 @@ function emitDispatch(p, ctx, pos) {
|
|
|
4435
4607
|
return emitLazy(p, def, ctx, pos);
|
|
4436
4608
|
case "trivia":
|
|
4437
4609
|
return emit(def.parser, ctx, pos);
|
|
4438
|
-
case "
|
|
4439
|
-
return
|
|
4610
|
+
case "token":
|
|
4611
|
+
return emitToken(def, ctx, pos);
|
|
4612
|
+
case "label": {
|
|
4613
|
+
const inner = emitFallible(def.parser, ctx, pos);
|
|
4614
|
+
return {
|
|
4615
|
+
stmts: [
|
|
4616
|
+
...inner.stmts,
|
|
4617
|
+
...emitIfFail(ctx, `!${inner.okVar}`, failBody(ctx, JSON.stringify(def.label), "_ctx._fe"))
|
|
4618
|
+
],
|
|
4619
|
+
valueVar: inner.valVar,
|
|
4620
|
+
endVar: inner.endVar
|
|
4621
|
+
};
|
|
4622
|
+
}
|
|
4440
4623
|
case "grammar": {
|
|
4441
4624
|
const savedTrivia = ctx.activeTrivia;
|
|
4442
4625
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
@@ -4536,6 +4719,7 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4536
4719
|
}
|
|
4537
4720
|
case "grammar":
|
|
4538
4721
|
case "trivia":
|
|
4722
|
+
case "token":
|
|
4539
4723
|
case "label":
|
|
4540
4724
|
case "optional":
|
|
4541
4725
|
case "many":
|
|
@@ -4571,6 +4755,7 @@ function childrenOf(def) {
|
|
|
4571
4755
|
case "optional":
|
|
4572
4756
|
case "transform":
|
|
4573
4757
|
case "trivia":
|
|
4758
|
+
case "token":
|
|
4574
4759
|
case "label":
|
|
4575
4760
|
case "grammar":
|
|
4576
4761
|
case "not":
|
|
@@ -5081,7 +5266,7 @@ function balanced(open, close, options = {}) {
|
|
|
5081
5266
|
const content = bounded ? regex(new RegExp(`[^${cls}]+`)) : regex(new RegExp(`[^${escapeClassChar(open)}${escapeClassChar(close)}]`));
|
|
5082
5267
|
const inner = many(choice(self, ...skips, content));
|
|
5083
5268
|
const combi = transform(
|
|
5084
|
-
sequence(literal(open), inner, expect(literal(close)
|
|
5269
|
+
sequence(literal(open), inner, expect(literal(close))),
|
|
5085
5270
|
// parts: strings (content/self) or arrays (a sequence-shaped skip) or a
|
|
5086
5271
|
// ParseError (recovered close). `c` is the close string or a ParseError.
|
|
5087
5272
|
([o, parts, c]) => o + parts.map((p) => typeof p === "string" ? p : Array.isArray(p) ? p.join("") : "").join("") + (typeof c === "string" ? c : "")
|
|
@@ -5143,6 +5328,7 @@ function evalRuleMapIR(ir) {
|
|
|
5143
5328
|
"node",
|
|
5144
5329
|
"parser",
|
|
5145
5330
|
"scanTo",
|
|
5331
|
+
"token",
|
|
5146
5332
|
"transform",
|
|
5147
5333
|
"skip",
|
|
5148
5334
|
"trivia",
|
|
@@ -5168,6 +5354,7 @@ function evalRuleMapIR(ir) {
|
|
|
5168
5354
|
node,
|
|
5169
5355
|
parser,
|
|
5170
5356
|
scanTo,
|
|
5357
|
+
token,
|
|
5171
5358
|
transform,
|
|
5172
5359
|
skip,
|
|
5173
5360
|
trivia,
|
|
@@ -5328,7 +5515,7 @@ function recover(combinator, sentinel) {
|
|
|
5328
5515
|
canMatchNewline: true,
|
|
5329
5516
|
isTrivia: false
|
|
5330
5517
|
};
|
|
5331
|
-
const expected =
|
|
5518
|
+
const expected = deriveExpected(combinator);
|
|
5332
5519
|
return {
|
|
5333
5520
|
_tag: "recover",
|
|
5334
5521
|
_meta: meta,
|