parseman 0.22.0 → 0.24.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/keywords.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +6 -0
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +3 -1
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +7 -2
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/index.cjs +429 -75
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +429 -75
- package/dist/index.js.map +3 -3
- package/dist/plugin/index.cjs +284 -66
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +284 -66
- package/dist/plugin/index.js.map +3 -3
- package/dist/spec/ebnf.d.ts +13 -0
- package/dist/spec/ebnf.d.ts.map +1 -0
- package/dist/spec/index.cjs +977 -0
- package/dist/spec/index.cjs.map +7 -0
- package/dist/spec/index.d.ts +15 -0
- package/dist/spec/index.d.ts.map +1 -0
- package/dist/spec/index.js +954 -0
- package/dist/spec/index.js.map +7 -0
- package/dist/spec/model.d.ts +117 -0
- package/dist/spec/model.d.ts.map +1 -0
- package/dist/spec/railroad-lib.d.ts +11 -0
- package/dist/spec/railroad-lib.d.ts.map +1 -0
- package/dist/spec/railroad.d.ts +18 -0
- package/dist/spec/railroad.d.ts.map +1 -0
- package/package.json +6 -1
package/dist/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type { ParseOptions, ParserOptions, ParsemanParser } from './combinators/
|
|
|
18
18
|
export { token } from './combinators/token.ts';
|
|
19
19
|
export { compile } from './compiler/codegen.ts';
|
|
20
20
|
export type { CompiledParser, LinkablePieces } from './compiler/codegen.ts';
|
|
21
|
-
export { compose,
|
|
21
|
+
export { compose, cstBuildHost } from './compiler/linker.ts';
|
|
22
22
|
export type { CstBuildHostOptions, FusedRule } from './compiler/linker.ts';
|
|
23
23
|
export { buildLineIndex, offsetToLineCol, annotateSpan } from './compiler/line-index.ts';
|
|
24
24
|
export type { LineIndex } from './compiler/line-index.ts';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,oBAAoB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1P,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAU9C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpE,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAC5C,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAEnE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5E,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAClE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC3F,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAE9C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,oBAAoB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1P,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAU9C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpE,YAAY,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAEhE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAC5C,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAEnE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAC5E,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAClE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC3F,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAE9C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAC/C,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAK3E,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAC5D,YAAY,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAE1E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACxF,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEzD,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAC1D,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAEzE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAE5G,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACtF,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AACzC,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AACzF,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AACnD,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,OAAO,EACP,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,WAAW,EACX,WAAW,EACX,UAAU,EACV,gBAAgB,GACjB,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EACL,UAAU,EACV,UAAU,EACV,cAAc,EACd,aAAa,EACb,SAAS,GACV,MAAM,yBAAyB,CAAA;AAChC,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -343,24 +343,35 @@ function literal(value, opts = {}) {
|
|
|
343
343
|
{ lo: firstUpper, hi: firstUpper }
|
|
344
344
|
] } : firstSet2;
|
|
345
345
|
}
|
|
346
|
+
const expected = [JSON.stringify(value)];
|
|
347
|
+
const parse2 = !caseInsensitive && value.length === 1 ? (() => {
|
|
348
|
+
const code = value.charCodeAt(0);
|
|
349
|
+
return function parse3(input, pos, ctx) {
|
|
350
|
+
if (input.charCodeAt(pos) === code) {
|
|
351
|
+
const span = { start: pos, end: pos + 1 };
|
|
352
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
353
|
+
return { ok: true, value, span };
|
|
354
|
+
}
|
|
355
|
+
return failAt(ctx, expected, pos);
|
|
356
|
+
};
|
|
357
|
+
})() : function parse3(input, pos, ctx) {
|
|
358
|
+
const end = pos + value.length;
|
|
359
|
+
if (end > input.length) {
|
|
360
|
+
return failAt(ctx, expected, pos);
|
|
361
|
+
}
|
|
362
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
363
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
364
|
+
const span = { start: pos, end };
|
|
365
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
366
|
+
return { ok: true, value: matchedValue, span };
|
|
367
|
+
}
|
|
368
|
+
return failAt(ctx, expected, pos);
|
|
369
|
+
};
|
|
346
370
|
return {
|
|
347
371
|
_tag: "literal",
|
|
348
372
|
_meta: meta,
|
|
349
373
|
_def: { tag: "literal", value, caseInsensitive },
|
|
350
|
-
parse
|
|
351
|
-
const end = pos + value.length;
|
|
352
|
-
if (end > input.length) {
|
|
353
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
354
|
-
}
|
|
355
|
-
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
356
|
-
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
357
|
-
const span = { start: pos, end };
|
|
358
|
-
const leaf = { _tag: "leaf", value: matchedValue, span };
|
|
359
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
360
|
-
return { ok: true, value: matchedValue, span };
|
|
361
|
-
}
|
|
362
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
363
|
-
}
|
|
374
|
+
parse: parse2
|
|
364
375
|
};
|
|
365
376
|
}
|
|
366
377
|
|
|
@@ -495,8 +506,7 @@ function regex(pattern, flags = "") {
|
|
|
495
506
|
if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
|
|
496
507
|
const value = input.slice(pos, scanEnd);
|
|
497
508
|
const span2 = { start: pos, end: scanEnd };
|
|
498
|
-
|
|
499
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf2);
|
|
509
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
500
510
|
return { ok: true, value, span: span2 };
|
|
501
511
|
}
|
|
502
512
|
anchored.lastIndex = pos;
|
|
@@ -505,8 +515,7 @@ function regex(pattern, flags = "") {
|
|
|
505
515
|
return failAt(ctx, [`/${source}/`], pos);
|
|
506
516
|
}
|
|
507
517
|
const span = { start: pos, end: pos + m[0].length };
|
|
508
|
-
|
|
509
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
518
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
510
519
|
return { ok: true, value: m[0], span };
|
|
511
520
|
}
|
|
512
521
|
};
|
|
@@ -814,8 +823,7 @@ function keywords(words, opts = {}) {
|
|
|
814
823
|
}
|
|
815
824
|
const value = m[0];
|
|
816
825
|
const span = { start: pos, end: pos + value.length };
|
|
817
|
-
|
|
818
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
826
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
819
827
|
return { ok: true, value, span };
|
|
820
828
|
}
|
|
821
829
|
};
|
|
@@ -1305,33 +1313,136 @@ function loopScanner(arms) {
|
|
|
1305
1313
|
}
|
|
1306
1314
|
function regexTriviaScanner(parser2) {
|
|
1307
1315
|
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1308
|
-
const
|
|
1309
|
-
|
|
1310
|
-
return blockCommentSource(parser2._def.source) ? scanBlockComment : null;
|
|
1316
|
+
const source = parser2._def.source;
|
|
1317
|
+
return classRunSource(source) ?? altStarSource(source) ?? (blockCommentSource(source) ? scanBlockComment : null);
|
|
1311
1318
|
}
|
|
1312
|
-
function
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1319
|
+
function inRanges2(cp, ranges) {
|
|
1320
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
1321
|
+
const r = ranges[i];
|
|
1322
|
+
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1323
|
+
}
|
|
1324
|
+
return false;
|
|
1325
|
+
}
|
|
1326
|
+
function classScanner(classBody) {
|
|
1327
|
+
const ranges = parseClassRanges(classBody);
|
|
1328
|
+
if (!ranges) return null;
|
|
1329
|
+
return (input, cur) => {
|
|
1330
|
+
let pos = cur;
|
|
1331
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1332
|
+
return pos;
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
function lineCommentScanner(commentCode) {
|
|
1336
|
+
return (input, cur) => {
|
|
1337
|
+
if (input.charCodeAt(cur) !== commentCode) return cur;
|
|
1338
|
+
let pos = cur + 1;
|
|
1339
|
+
while (pos < input.length) {
|
|
1340
|
+
const cc = input.charCodeAt(pos);
|
|
1341
|
+
if (cc === 10 || cc === 13) break;
|
|
1342
|
+
pos++;
|
|
1321
1343
|
}
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1344
|
+
return pos;
|
|
1345
|
+
};
|
|
1346
|
+
}
|
|
1347
|
+
function classRunSource(source) {
|
|
1348
|
+
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1349
|
+
return m ? classScanner(m[1]) : null;
|
|
1350
|
+
}
|
|
1351
|
+
function classifyTriviaArm(arm) {
|
|
1352
|
+
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1353
|
+
if (cls) {
|
|
1354
|
+
const ranges = parseClassRanges(cls[1]);
|
|
1355
|
+
return ranges ? { kind: "class", ranges } : null;
|
|
1356
|
+
}
|
|
1357
|
+
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1358
|
+
if (lc) {
|
|
1359
|
+
const marker = lc[1];
|
|
1360
|
+
return { kind: "comment", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1328
1361
|
}
|
|
1362
|
+
return null;
|
|
1363
|
+
}
|
|
1364
|
+
function armScanner(arm) {
|
|
1365
|
+
if (arm.kind === "comment") return lineCommentScanner(arm.code);
|
|
1366
|
+
const ranges = arm.ranges;
|
|
1329
1367
|
return (input, cur) => {
|
|
1330
1368
|
let pos = cur;
|
|
1331
|
-
while (pos < input.length &&
|
|
1369
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1370
|
+
return pos;
|
|
1371
|
+
};
|
|
1372
|
+
}
|
|
1373
|
+
function fusedTriviaScanner(ranges, commentCodes) {
|
|
1374
|
+
const c0 = commentCodes[0];
|
|
1375
|
+
const single = commentCodes.length === 1;
|
|
1376
|
+
return (input, cur) => {
|
|
1377
|
+
let pos = cur;
|
|
1378
|
+
const len = input.length;
|
|
1379
|
+
for (; ; ) {
|
|
1380
|
+
const c = input.charCodeAt(pos);
|
|
1381
|
+
if (pos < len && inRanges2(c, ranges)) {
|
|
1382
|
+
pos++;
|
|
1383
|
+
continue;
|
|
1384
|
+
}
|
|
1385
|
+
if (single ? c === c0 : commentCodes.includes(c)) {
|
|
1386
|
+
pos++;
|
|
1387
|
+
while (pos < len) {
|
|
1388
|
+
const cc = input.charCodeAt(pos);
|
|
1389
|
+
if (cc === 10 || cc === 13) break;
|
|
1390
|
+
pos++;
|
|
1391
|
+
}
|
|
1392
|
+
continue;
|
|
1393
|
+
}
|
|
1394
|
+
break;
|
|
1395
|
+
}
|
|
1332
1396
|
return pos;
|
|
1333
1397
|
};
|
|
1334
1398
|
}
|
|
1399
|
+
function splitTopLevelAlts(body) {
|
|
1400
|
+
const arms = [];
|
|
1401
|
+
let inClass = false;
|
|
1402
|
+
let start = 0;
|
|
1403
|
+
for (let i = 0; i < body.length; i++) {
|
|
1404
|
+
const c = body[i];
|
|
1405
|
+
if (c === "\\") {
|
|
1406
|
+
i++;
|
|
1407
|
+
continue;
|
|
1408
|
+
}
|
|
1409
|
+
if (inClass) {
|
|
1410
|
+
if (c === "]") inClass = false;
|
|
1411
|
+
continue;
|
|
1412
|
+
}
|
|
1413
|
+
if (c === "[") inClass = true;
|
|
1414
|
+
else if (c === "(") return null;
|
|
1415
|
+
else if (c === "|") {
|
|
1416
|
+
arms.push(body.slice(start, i));
|
|
1417
|
+
start = i + 1;
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
arms.push(body.slice(start));
|
|
1421
|
+
return arms;
|
|
1422
|
+
}
|
|
1423
|
+
function altStarSource(source) {
|
|
1424
|
+
const m = /^\(\?:(.*)\)[*+]$/.exec(source);
|
|
1425
|
+
if (!m) return null;
|
|
1426
|
+
const armSrcs = splitTopLevelAlts(m[1]);
|
|
1427
|
+
if (!armSrcs || armSrcs.length < 2) return null;
|
|
1428
|
+
const arms = [];
|
|
1429
|
+
for (const src of armSrcs) {
|
|
1430
|
+
const arm = classifyTriviaArm(src);
|
|
1431
|
+
if (!arm) return null;
|
|
1432
|
+
arms.push(arm);
|
|
1433
|
+
}
|
|
1434
|
+
const ranges = [];
|
|
1435
|
+
const commentCodes = [];
|
|
1436
|
+
for (const arm of arms) {
|
|
1437
|
+
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1438
|
+
else commentCodes.push(arm.code);
|
|
1439
|
+
}
|
|
1440
|
+
if (commentCodes.some((code) => inRanges2(code, ranges))) {
|
|
1441
|
+
return loopScanner(arms.map(armScanner));
|
|
1442
|
+
}
|
|
1443
|
+
if (commentCodes.length === 0) return armScanner({ kind: "class", ranges });
|
|
1444
|
+
return fusedTriviaScanner(ranges, commentCodes);
|
|
1445
|
+
}
|
|
1335
1446
|
function blockCommentSource(source) {
|
|
1336
1447
|
return source === "\\/\\*(?:[^*]|\\*(?!\\/))*\\*\\/" || source === "\\/\\*[^]*?\\*\\/";
|
|
1337
1448
|
}
|
|
@@ -1685,6 +1796,7 @@ function markUnusedValues(root) {
|
|
|
1685
1796
|
}
|
|
1686
1797
|
|
|
1687
1798
|
// src/combinators/parser.ts
|
|
1799
|
+
var RULE_ORDER = "__parsemanRuleOrder";
|
|
1688
1800
|
function tagRule(r, key) {
|
|
1689
1801
|
;
|
|
1690
1802
|
r._ruleName = key;
|
|
@@ -1729,6 +1841,11 @@ function rules(a, b) {
|
|
|
1729
1841
|
for (const key of Object.keys(definitions)) {
|
|
1730
1842
|
markUnusedValues(cache[key]);
|
|
1731
1843
|
}
|
|
1844
|
+
Object.defineProperty(cache, RULE_ORDER, {
|
|
1845
|
+
value: Object.keys(definitions),
|
|
1846
|
+
enumerable: false,
|
|
1847
|
+
configurable: true
|
|
1848
|
+
});
|
|
1732
1849
|
return cache;
|
|
1733
1850
|
}
|
|
1734
1851
|
|
|
@@ -5433,9 +5550,10 @@ function publicRuleWrapperSource(rule, fnSource) {
|
|
|
5433
5550
|
if (labels === void 0) return fnSource;
|
|
5434
5551
|
return `Object.assign(${fnSource}, { _meta: { triviaKindLabels: ${JSON.stringify(labels)} } })`;
|
|
5435
5552
|
}
|
|
5436
|
-
function compileLinkable(ruleMapArg, ns) {
|
|
5553
|
+
function compileLinkable(ruleMapArg, ns, opts) {
|
|
5437
5554
|
if (!ns) throw new Error("compileLinkable: ns must be a non-empty namespace");
|
|
5438
5555
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
5556
|
+
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
5439
5557
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
5440
5558
|
const d = val._def;
|
|
5441
5559
|
if (d.tag !== "lazy") return true;
|
|
@@ -5466,7 +5584,8 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5466
5584
|
capturing: ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
5467
5585
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
5468
5586
|
ns,
|
|
5469
|
-
deferFirstSetRefs: true
|
|
5587
|
+
deferFirstSetRefs: true,
|
|
5588
|
+
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {}
|
|
5470
5589
|
};
|
|
5471
5590
|
const seen = /* @__PURE__ */ new Map();
|
|
5472
5591
|
const ruleNames = /* @__PURE__ */ new Map();
|
|
@@ -5529,7 +5648,10 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5529
5648
|
ctx.indent = 1;
|
|
5530
5649
|
ctx.failLabel = "_pfail";
|
|
5531
5650
|
ctx.recordFail = true;
|
|
5651
|
+
const savedTrivia = ctx.activeTrivia;
|
|
5652
|
+
if (rule._meta.isTrivia) ctx.activeTrivia = void 0;
|
|
5532
5653
|
const body = emit(resolved, ctx, "_pos");
|
|
5654
|
+
ctx.activeTrivia = savedTrivia;
|
|
5533
5655
|
ctx.indent = savedIndent;
|
|
5534
5656
|
ctx.failLabel = savedFail;
|
|
5535
5657
|
ctx.recordFail = savedRec;
|
|
@@ -5728,6 +5850,64 @@ function escapeClassChar(ch) {
|
|
|
5728
5850
|
}
|
|
5729
5851
|
|
|
5730
5852
|
// src/compiler/ir-serialize.ts
|
|
5853
|
+
function childrenOf2(def) {
|
|
5854
|
+
switch (def.tag) {
|
|
5855
|
+
case "sequence":
|
|
5856
|
+
case "choice":
|
|
5857
|
+
return def.parsers;
|
|
5858
|
+
case "many":
|
|
5859
|
+
case "oneOrMore":
|
|
5860
|
+
case "optional":
|
|
5861
|
+
case "transform":
|
|
5862
|
+
case "trivia":
|
|
5863
|
+
case "token":
|
|
5864
|
+
case "label":
|
|
5865
|
+
case "field":
|
|
5866
|
+
case "not":
|
|
5867
|
+
case "node":
|
|
5868
|
+
case "expect":
|
|
5869
|
+
return [def.parser];
|
|
5870
|
+
case "grammar":
|
|
5871
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
5872
|
+
case "sepBy":
|
|
5873
|
+
return [def.parser, def.separator];
|
|
5874
|
+
case "skip":
|
|
5875
|
+
return [def.main, def.skipped];
|
|
5876
|
+
case "scanTo":
|
|
5877
|
+
return [def.sentinel, ...def.skip];
|
|
5878
|
+
case "lazy":
|
|
5879
|
+
case "literal":
|
|
5880
|
+
case "regex":
|
|
5881
|
+
case "keywords":
|
|
5882
|
+
case "guard":
|
|
5883
|
+
case "withCtx":
|
|
5884
|
+
case "recover":
|
|
5885
|
+
case "unknown":
|
|
5886
|
+
return [];
|
|
5887
|
+
}
|
|
5888
|
+
}
|
|
5889
|
+
var ruleNameOf = (c) => c._ruleName;
|
|
5890
|
+
function lazyTarget(c) {
|
|
5891
|
+
if (c._def.tag !== "lazy") return null;
|
|
5892
|
+
try {
|
|
5893
|
+
return c._def.thunk();
|
|
5894
|
+
} catch {
|
|
5895
|
+
return null;
|
|
5896
|
+
}
|
|
5897
|
+
}
|
|
5898
|
+
var Unserializable = class extends Error {
|
|
5899
|
+
};
|
|
5900
|
+
function serializeRuleMap(ruleMap) {
|
|
5901
|
+
try {
|
|
5902
|
+
return new Serializer(ruleMap).run();
|
|
5903
|
+
} catch (e) {
|
|
5904
|
+
if (e instanceof Unserializable) {
|
|
5905
|
+
if (process.env.PARSEMAN_IR_DEBUG) console.error(`[ir] fallback: ${e.message}`);
|
|
5906
|
+
return null;
|
|
5907
|
+
}
|
|
5908
|
+
throw e;
|
|
5909
|
+
}
|
|
5910
|
+
}
|
|
5731
5911
|
function evalRuleMapIR(ir) {
|
|
5732
5912
|
const _tf = (child, src) => {
|
|
5733
5913
|
let fn2;
|
|
@@ -5802,11 +5982,172 @@ function evalRuleMapIR(ir) {
|
|
|
5802
5982
|
);
|
|
5803
5983
|
return Object.entries(map);
|
|
5804
5984
|
}
|
|
5985
|
+
var Serializer = class {
|
|
5986
|
+
counts = /* @__PURE__ */ new Map();
|
|
5987
|
+
selfRef = /* @__PURE__ */ new Set();
|
|
5988
|
+
// combinators reached by an unnamed lazy pointing back into their own subtree
|
|
5989
|
+
constName = /* @__PURE__ */ new Map();
|
|
5990
|
+
emitted = /* @__PURE__ */ new Set();
|
|
5991
|
+
decls = [];
|
|
5992
|
+
ruleValues = /* @__PURE__ */ new Set();
|
|
5993
|
+
ruleMap;
|
|
5994
|
+
constructor(ruleMap) {
|
|
5995
|
+
this.ruleMap = ruleMap;
|
|
5996
|
+
for (const [, c] of ruleMap) this.ruleValues.add(this.body(c));
|
|
5997
|
+
}
|
|
5998
|
+
/** A `rules()` map wraps each rule value in a named `lazy` proxy; the real body is
|
|
5999
|
+
* its target (compileLinkable unwraps the same way). A ref INSIDE a body stays a
|
|
6000
|
+
* `g[name]` ref — only the top-level entry is unwrapped. */
|
|
6001
|
+
body(c) {
|
|
6002
|
+
return c._def.tag === "lazy" && ruleNameOf(c) !== void 0 ? lazyTarget(c) ?? c : c;
|
|
6003
|
+
}
|
|
6004
|
+
run() {
|
|
6005
|
+
for (const [, c] of this.ruleMap) this.analyze(this.body(c), /* @__PURE__ */ new Set());
|
|
6006
|
+
let n = 0;
|
|
6007
|
+
for (const [c, count] of this.counts) {
|
|
6008
|
+
if (this.ruleValues.has(c)) continue;
|
|
6009
|
+
if (count >= 2 || this.selfRef.has(c)) this.constName.set(c, `_s${n++}`);
|
|
6010
|
+
}
|
|
6011
|
+
const body = this.ruleMap.map(([name, c]) => ` ${JSON.stringify(name)}: ${this.wrap(this.body(c))}`).join(",\n");
|
|
6012
|
+
if (this.decls.length === 0) return `rules((g) => ({
|
|
6013
|
+
${body}
|
|
6014
|
+
}))`;
|
|
6015
|
+
return `rules((g) => {
|
|
6016
|
+
${this.decls.map((d) => " " + d).join("\n")}
|
|
6017
|
+
return ({
|
|
6018
|
+
${body}
|
|
6019
|
+
})
|
|
6020
|
+
})`;
|
|
6021
|
+
}
|
|
6022
|
+
/** Count identity references and flag self-referential subtrees. `active` is the
|
|
6023
|
+
* set of combinators on the current DFS path (to detect a lazy pointing back). */
|
|
6024
|
+
analyze(c, active) {
|
|
6025
|
+
const def = c._def;
|
|
6026
|
+
if (def.tag === "lazy") {
|
|
6027
|
+
if (ruleNameOf(c) !== void 0) return;
|
|
6028
|
+
const target = lazyTarget(c);
|
|
6029
|
+
if (!target) throw new Unserializable("unresolved unnamed ref");
|
|
6030
|
+
if (active.has(target)) {
|
|
6031
|
+
this.selfRef.add(target);
|
|
6032
|
+
return;
|
|
6033
|
+
}
|
|
6034
|
+
this.analyze(target, active);
|
|
6035
|
+
return;
|
|
6036
|
+
}
|
|
6037
|
+
if (def.tag === "guard" || def.tag === "withCtx" || def.tag === "recover" || def.tag === "unknown") {
|
|
6038
|
+
throw new Unserializable(`unsupported tag ${def.tag}`);
|
|
6039
|
+
}
|
|
6040
|
+
this.counts.set(c, (this.counts.get(c) ?? 0) + 1);
|
|
6041
|
+
if ((this.counts.get(c) ?? 0) > 1) return;
|
|
6042
|
+
active.add(c);
|
|
6043
|
+
for (const child of childrenOf2(def)) this.analyze(child, active);
|
|
6044
|
+
active.delete(c);
|
|
6045
|
+
}
|
|
6046
|
+
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
6047
|
+
* `selfOf` is the const currently being wrapped in a ref()/define closure — an
|
|
6048
|
+
* unnamed lazy back into it emits the local ref var instead of recursing. */
|
|
6049
|
+
ref(c, selfOf) {
|
|
6050
|
+
const cn = this.constName.get(c);
|
|
6051
|
+
if (cn) {
|
|
6052
|
+
this.emitDecl(c);
|
|
6053
|
+
return cn;
|
|
6054
|
+
}
|
|
6055
|
+
return this.expr(c, selfOf);
|
|
6056
|
+
}
|
|
6057
|
+
emitDecl(c) {
|
|
6058
|
+
const name = this.constName.get(c);
|
|
6059
|
+
if (this.emitted.has(name)) return;
|
|
6060
|
+
this.emitted.add(name);
|
|
6061
|
+
this.decls.push(`const ${name} = ${this.wrap(c)}`);
|
|
6062
|
+
}
|
|
6063
|
+
selfN = 0;
|
|
6064
|
+
/** Emit `c`'s own constructor call, wrapping it in a `ref()`+`.define()` closure
|
|
6065
|
+
* if it is self-referential (an unnamed lazy in its subtree points back to it) —
|
|
6066
|
+
* the shape `balanced()` and other recursive library combinators build. */
|
|
6067
|
+
wrap(c) {
|
|
6068
|
+
if (!this.selfRef.has(c)) return this.expr(c, null);
|
|
6069
|
+
const rv = `_rr${this.selfN++}`;
|
|
6070
|
+
const bodyExpr = this.expr(c, { comb: c, var: rv });
|
|
6071
|
+
return `(() => { const ${rv} = ref(); const _b = ${bodyExpr}; ${rv}.define(_b); return _b })()`;
|
|
6072
|
+
}
|
|
6073
|
+
/** Emit the constructor-call source for `c` (never a const shortcut for `c` itself). */
|
|
6074
|
+
expr(c, selfOf) {
|
|
6075
|
+
const def = c._def;
|
|
6076
|
+
const kid = (x) => this.ref(x, selfOf);
|
|
6077
|
+
switch (def.tag) {
|
|
6078
|
+
case "lazy": {
|
|
6079
|
+
if (ruleNameOf(c) !== void 0) return `g[${JSON.stringify(ruleNameOf(c))}]`;
|
|
6080
|
+
const target = lazyTarget(c);
|
|
6081
|
+
if (selfOf && target === selfOf.comb) return selfOf.var;
|
|
6082
|
+
return this.ref(target, selfOf);
|
|
6083
|
+
}
|
|
6084
|
+
case "literal":
|
|
6085
|
+
return `literal(${JSON.stringify(def.value)}${def.caseInsensitive ? ", { caseInsensitive: true }" : ""})`;
|
|
6086
|
+
case "regex":
|
|
6087
|
+
return `regex(${JSON.stringify(def.source)}, ${JSON.stringify(def.flags)})`;
|
|
6088
|
+
case "keywords":
|
|
6089
|
+
return `keywords(${JSON.stringify(def.words)}, { caseInsensitive: ${def.caseInsensitive}${def.boundary !== void 0 ? `, boundary: ${JSON.stringify(def.boundary)}` : ""} })`;
|
|
6090
|
+
case "sequence":
|
|
6091
|
+
return `sequence(${def.parsers.map(kid).join(", ")})`;
|
|
6092
|
+
case "choice": {
|
|
6093
|
+
if (def.gates.some((g) => g !== null)) throw new Unserializable("choice with a gate() has no source");
|
|
6094
|
+
return `choice(${def.parsers.map(kid).join(", ")})`;
|
|
6095
|
+
}
|
|
6096
|
+
case "many":
|
|
6097
|
+
return `many(${kid(def.parser)})`;
|
|
6098
|
+
case "oneOrMore":
|
|
6099
|
+
return `oneOrMore(${kid(def.parser)})`;
|
|
6100
|
+
case "optional":
|
|
6101
|
+
return `optional(${kid(def.parser)})`;
|
|
6102
|
+
case "sepBy":
|
|
6103
|
+
return `sepBy(${kid(def.parser)}, ${kid(def.separator)})`;
|
|
6104
|
+
case "not":
|
|
6105
|
+
return `not(${kid(def.parser)})`;
|
|
6106
|
+
case "trivia":
|
|
6107
|
+
return `trivia(${kid(def.parser)})`;
|
|
6108
|
+
case "token":
|
|
6109
|
+
return `token(${kid(def.parser)})`;
|
|
6110
|
+
case "label":
|
|
6111
|
+
return `label(${JSON.stringify(def.label)}, ${kid(def.parser)})`;
|
|
6112
|
+
case "field":
|
|
6113
|
+
return `field(${JSON.stringify(def.name)}, ${kid(def.parser)})`;
|
|
6114
|
+
case "expect":
|
|
6115
|
+
return `expect(${kid(def.parser)}${def.label !== void 0 ? `, ${JSON.stringify(def.label)}` : ""})`;
|
|
6116
|
+
case "skip":
|
|
6117
|
+
return `skip(${kid(def.main)}, ${kid(def.skipped)})`;
|
|
6118
|
+
case "scanTo":
|
|
6119
|
+
return `scanTo(${kid(def.sentinel)}, { skip: [${def.skip.map(kid).join(", ")}], orEOF: ${def.orEOF} })`;
|
|
6120
|
+
case "transform": {
|
|
6121
|
+
if (def.fnSrc === void 0) throw new Unserializable("transform without fnSrc");
|
|
6122
|
+
return `_tf(${kid(def.parser)}, ${JSON.stringify(def.fnSrc)})`;
|
|
6123
|
+
}
|
|
6124
|
+
case "node": {
|
|
6125
|
+
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
6126
|
+
const opts = def.unwrap || def.collapse ? `, { ${def.unwrap ? "unwrap: true" : "collapse: true"} }` : "";
|
|
6127
|
+
if (def.type === void 0) {
|
|
6128
|
+
if (def.buildSrc !== void 0) throw new Unserializable("inferred node build without inferred type");
|
|
6129
|
+
return opts ? `node(${kid(def.parser)}, undefined${opts})` : `node(${kid(def.parser)})`;
|
|
6130
|
+
}
|
|
6131
|
+
if (def.buildSrc !== void 0) return `_nd(${JSON.stringify(def.type)}, ${kid(def.parser)}, ${JSON.stringify(def.buildSrc)}${opts})`;
|
|
6132
|
+
return opts ? `node(${JSON.stringify(def.type)}, ${kid(def.parser)}, undefined${opts})` : `node(${JSON.stringify(def.type)}, ${kid(def.parser)})`;
|
|
6133
|
+
}
|
|
6134
|
+
case "grammar": {
|
|
6135
|
+
const trivia2 = def.clearTrivia ? "null" : def.triviaParser ? kid(def.triviaParser) : "undefined";
|
|
6136
|
+
return `parser({ trivia: ${trivia2}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(def.parser)})`;
|
|
6137
|
+
}
|
|
6138
|
+
case "guard":
|
|
6139
|
+
case "withCtx":
|
|
6140
|
+
case "recover":
|
|
6141
|
+
case "unknown":
|
|
6142
|
+
throw new Unserializable(`unsupported tag ${def.tag}`);
|
|
6143
|
+
}
|
|
6144
|
+
}
|
|
6145
|
+
};
|
|
5805
6146
|
|
|
5806
6147
|
// src/compiler/linker.ts
|
|
5807
6148
|
var _nsCounter = 0;
|
|
5808
|
-
function linkable(rulesMap, ns) {
|
|
5809
|
-
const pieces = compileLinkable(
|
|
6149
|
+
function linkable(rulesMap, ns, trivia2) {
|
|
6150
|
+
const pieces = compileLinkable(Object.entries(rulesMap), ns ?? `_lk${_nsCounter++}_`, trivia2 ? { trivia: trivia2 } : void 0);
|
|
5810
6151
|
if (!pieces) throw new Error("linkable(): this grammar cannot be compiled to a linkable artifact (contains a runtime-only parser fallback)");
|
|
5811
6152
|
return pieces;
|
|
5812
6153
|
}
|
|
@@ -5830,28 +6171,6 @@ function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, trivi
|
|
|
5830
6171
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
5831
6172
|
return host;
|
|
5832
6173
|
}
|
|
5833
|
-
function pick(grammar, names) {
|
|
5834
|
-
const p = grammar.ruleFns instanceof Map ? grammar : linkable(grammar);
|
|
5835
|
-
const keep = /* @__PURE__ */ new Set();
|
|
5836
|
-
const has = new Set(p.keys);
|
|
5837
|
-
for (const n of names) {
|
|
5838
|
-
if (!has.has(n)) throw new Error(`pick: rule "${n}" is not in this grammar (available: ${p.keys.join(", ")})`);
|
|
5839
|
-
}
|
|
5840
|
-
const visit = (n) => {
|
|
5841
|
-
if (keep.has(n) || !has.has(n)) return;
|
|
5842
|
-
keep.add(n);
|
|
5843
|
-
for (const d of p.deps.get(n) ?? []) visit(d);
|
|
5844
|
-
};
|
|
5845
|
-
for (const n of names) visit(n);
|
|
5846
|
-
const filt = (m) => new Map([...m].filter(([k]) => keep.has(k)));
|
|
5847
|
-
return {
|
|
5848
|
-
...p,
|
|
5849
|
-
keys: [...keep],
|
|
5850
|
-
ruleFns: filt(p.ruleFns),
|
|
5851
|
-
wrappers: filt(p.wrappers),
|
|
5852
|
-
deps: filt(p.deps)
|
|
5853
|
-
};
|
|
5854
|
-
}
|
|
5855
6174
|
function fusedBody(pieces) {
|
|
5856
6175
|
const winner = /* @__PURE__ */ new Map();
|
|
5857
6176
|
for (const p of pieces) for (const k of p.keys) winner.set(k, p);
|
|
@@ -5871,7 +6190,7 @@ function fusedBody(pieces) {
|
|
|
5871
6190
|
...needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [],
|
|
5872
6191
|
...needsHostReads ? [HOST_READS_DECL] : [],
|
|
5873
6192
|
// Each contributing artifact's namespaced private prelude (regexes, _pf, …).
|
|
5874
|
-
...
|
|
6193
|
+
...new Set(contributingPieces.flatMap((p) => p.prelude)),
|
|
5875
6194
|
// The winning `_r_<Name>` function for each rule (one per name → no redeclare).
|
|
5876
6195
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
5877
6196
|
];
|
|
@@ -5905,12 +6224,13 @@ function fuseRules(pieces) {
|
|
|
5905
6224
|
return new Function("_env", body)(env);
|
|
5906
6225
|
}
|
|
5907
6226
|
var COMPOSED_PIECES = /* @__PURE__ */ Symbol.for("parseman.composedPieces");
|
|
6227
|
+
var COMPOSED_TRIVIA = /* @__PURE__ */ Symbol.for("parseman.composedTrivia");
|
|
5908
6228
|
function isIRPiece(p) {
|
|
5909
6229
|
return !!p && typeof p === "object" && typeof p.ir === "string" && typeof p.ns === "string" && !("ruleFns" in p);
|
|
5910
6230
|
}
|
|
5911
|
-
function materializePiece(p) {
|
|
6231
|
+
function materializePiece(p, trivia2) {
|
|
5912
6232
|
if (!isIRPiece(p)) return p;
|
|
5913
|
-
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns);
|
|
6233
|
+
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, trivia2 ? { trivia: trivia2 } : void 0);
|
|
5914
6234
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
5915
6235
|
return pieces;
|
|
5916
6236
|
}
|
|
@@ -5922,17 +6242,52 @@ function nextComposeNs(used) {
|
|
|
5922
6242
|
used.add(ns);
|
|
5923
6243
|
return ns;
|
|
5924
6244
|
}
|
|
5925
|
-
function
|
|
6245
|
+
function itemCarried(item, used, trivia2) {
|
|
5926
6246
|
const carried = item[COMPOSED_PIECES];
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
6247
|
+
if (Array.isArray(carried)) {
|
|
6248
|
+
const items = carried;
|
|
6249
|
+
for (const p of items) used.add(p.ns);
|
|
6250
|
+
return items;
|
|
6251
|
+
}
|
|
6252
|
+
if (item.ruleFns instanceof Map) {
|
|
6253
|
+
const p = item;
|
|
6254
|
+
used.add(p.ns);
|
|
6255
|
+
return [p];
|
|
6256
|
+
}
|
|
6257
|
+
const map = item;
|
|
6258
|
+
const ns = nextComposeNs(used);
|
|
6259
|
+
const entries = Object.entries(map).filter(([, val]) => {
|
|
6260
|
+
const d = val._def;
|
|
6261
|
+
if (d.tag !== "lazy") return true;
|
|
6262
|
+
try {
|
|
6263
|
+
d.thunk();
|
|
6264
|
+
return true;
|
|
6265
|
+
} catch {
|
|
6266
|
+
return false;
|
|
6267
|
+
}
|
|
6268
|
+
});
|
|
6269
|
+
const ir = serializeRuleMap(entries);
|
|
6270
|
+
return ir ? [{ ns, ir }] : [linkable(map, ns, trivia2)];
|
|
6271
|
+
}
|
|
6272
|
+
function composingTriviaOf(items) {
|
|
6273
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
6274
|
+
const item = items[i];
|
|
6275
|
+
if (!item || item.ruleFns instanceof Map || item[COMPOSED_PIECES]) continue;
|
|
6276
|
+
for (const v2 of Object.values(item)) {
|
|
6277
|
+
const t = v2?._meta?.grammarTrivia;
|
|
6278
|
+
if (t) return t;
|
|
6279
|
+
}
|
|
6280
|
+
}
|
|
6281
|
+
return void 0;
|
|
5930
6282
|
}
|
|
5931
6283
|
function compose(items) {
|
|
5932
6284
|
const used = /* @__PURE__ */ new Set();
|
|
5933
|
-
const
|
|
6285
|
+
const trivia2 = composingTriviaOf(items);
|
|
6286
|
+
const carried = items.flatMap((item) => itemCarried(item, used, trivia2));
|
|
6287
|
+
const pieces = carried.map((p) => materializePiece(p, trivia2));
|
|
5934
6288
|
const map = fuseRules(pieces);
|
|
5935
|
-
Object.defineProperty(map, COMPOSED_PIECES, { value:
|
|
6289
|
+
Object.defineProperty(map, COMPOSED_PIECES, { value: carried, enumerable: false });
|
|
6290
|
+
if (trivia2) Object.defineProperty(map, COMPOSED_TRIVIA, { value: trivia2, enumerable: false });
|
|
5936
6291
|
return map;
|
|
5937
6292
|
}
|
|
5938
6293
|
|
|
@@ -6683,7 +7038,6 @@ export {
|
|
|
6683
7038
|
parse,
|
|
6684
7039
|
parseDoc,
|
|
6685
7040
|
parser,
|
|
6686
|
-
pick,
|
|
6687
7041
|
recover,
|
|
6688
7042
|
ref,
|
|
6689
7043
|
regex,
|