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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAuBA,OAAO,WAAW,MAAM,cAAc,CAAA;AAiBtC,MAAM,MAAM,uBAAuB,GAAG;IACpC,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B,CAAA;;;AA4MD,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAA;IAC3C,kFAAkF;IAClF,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB,CAAA;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,aAAa,cAA6B,EAC1C,kBAAkB,UAAQ,GACzB,oBAAoB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAuBA,OAAO,WAAW,MAAM,cAAc,CAAA;AAiBtC,MAAM,MAAM,uBAAuB,GAAG;IACpC,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B,CAAA;;;AA4MD,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAA;IAC3C,kFAAkF;IAClF,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB,CAAA;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,aAAa,cAA6B,EAC1C,kBAAkB,UAAQ,GACzB,oBAAoB,GAAG,IAAI,CA8wB7B"}
|
package/dist/plugin/index.js
CHANGED
|
@@ -387,24 +387,35 @@ function literal(value, opts = {}) {
|
|
|
387
387
|
{ lo: firstUpper, hi: firstUpper }
|
|
388
388
|
] } : firstSet2;
|
|
389
389
|
}
|
|
390
|
+
const expected = [JSON.stringify(value)];
|
|
391
|
+
const parse2 = !caseInsensitive && value.length === 1 ? (() => {
|
|
392
|
+
const code = value.charCodeAt(0);
|
|
393
|
+
return function parse3(input, pos, ctx) {
|
|
394
|
+
if (input.charCodeAt(pos) === code) {
|
|
395
|
+
const span = { start: pos, end: pos + 1 };
|
|
396
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
397
|
+
return { ok: true, value, span };
|
|
398
|
+
}
|
|
399
|
+
return failAt(ctx, expected, pos);
|
|
400
|
+
};
|
|
401
|
+
})() : function parse3(input, pos, ctx) {
|
|
402
|
+
const end = pos + value.length;
|
|
403
|
+
if (end > input.length) {
|
|
404
|
+
return failAt(ctx, expected, pos);
|
|
405
|
+
}
|
|
406
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
407
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
408
|
+
const span = { start: pos, end };
|
|
409
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: matchedValue, span });
|
|
410
|
+
return { ok: true, value: matchedValue, span };
|
|
411
|
+
}
|
|
412
|
+
return failAt(ctx, expected, pos);
|
|
413
|
+
};
|
|
390
414
|
return {
|
|
391
415
|
_tag: "literal",
|
|
392
416
|
_meta: meta,
|
|
393
417
|
_def: { tag: "literal", value, caseInsensitive },
|
|
394
|
-
parse
|
|
395
|
-
const end = pos + value.length;
|
|
396
|
-
if (end > input.length) {
|
|
397
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
398
|
-
}
|
|
399
|
-
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
400
|
-
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
401
|
-
const span = { start: pos, end };
|
|
402
|
-
const leaf = { _tag: "leaf", value: matchedValue, span };
|
|
403
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
404
|
-
return { ok: true, value: matchedValue, span };
|
|
405
|
-
}
|
|
406
|
-
return failAt(ctx, [JSON.stringify(value)], pos);
|
|
407
|
-
}
|
|
418
|
+
parse: parse2
|
|
408
419
|
};
|
|
409
420
|
}
|
|
410
421
|
|
|
@@ -539,8 +550,7 @@ function regex(pattern, flags = "") {
|
|
|
539
550
|
if (scanEnd === null) return failAt(ctx, [`/${source}/`], pos);
|
|
540
551
|
const value = input.slice(pos, scanEnd);
|
|
541
552
|
const span2 = { start: pos, end: scanEnd };
|
|
542
|
-
|
|
543
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf2);
|
|
553
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span: span2 });
|
|
544
554
|
return { ok: true, value, span: span2 };
|
|
545
555
|
}
|
|
546
556
|
anchored.lastIndex = pos;
|
|
@@ -549,8 +559,7 @@ function regex(pattern, flags = "") {
|
|
|
549
559
|
return failAt(ctx, [`/${source}/`], pos);
|
|
550
560
|
}
|
|
551
561
|
const span = { start: pos, end: pos + m[0].length };
|
|
552
|
-
|
|
553
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
562
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value: m[0], span });
|
|
554
563
|
return { ok: true, value: m[0], span };
|
|
555
564
|
}
|
|
556
565
|
};
|
|
@@ -855,8 +864,7 @@ function keywords(words, opts = {}) {
|
|
|
855
864
|
}
|
|
856
865
|
const value = m[0];
|
|
857
866
|
const span = { start: pos, end: pos + value.length };
|
|
858
|
-
|
|
859
|
-
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, leaf);
|
|
867
|
+
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
860
868
|
return { ok: true, value, span };
|
|
861
869
|
}
|
|
862
870
|
};
|
|
@@ -1346,33 +1354,136 @@ function loopScanner(arms) {
|
|
|
1346
1354
|
}
|
|
1347
1355
|
function regexTriviaScanner(parser2) {
|
|
1348
1356
|
if (parser2._def.tag !== "regex" || parser2._def.flags) return null;
|
|
1349
|
-
const
|
|
1350
|
-
|
|
1351
|
-
return blockCommentSource(parser2._def.source) ? scanBlockComment : null;
|
|
1357
|
+
const source = parser2._def.source;
|
|
1358
|
+
return classRunSource(source) ?? altStarSource(source) ?? (blockCommentSource(source) ? scanBlockComment : null);
|
|
1352
1359
|
}
|
|
1353
|
-
function
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1360
|
+
function inRanges2(cp, ranges) {
|
|
1361
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
1362
|
+
const r = ranges[i];
|
|
1363
|
+
if (cp >= r[0] && cp <= r[1]) return true;
|
|
1364
|
+
}
|
|
1365
|
+
return false;
|
|
1366
|
+
}
|
|
1367
|
+
function classScanner(classBody) {
|
|
1368
|
+
const ranges = parseClassRanges(classBody);
|
|
1369
|
+
if (!ranges) return null;
|
|
1370
|
+
return (input, cur) => {
|
|
1371
|
+
let pos = cur;
|
|
1372
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1373
|
+
return pos;
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
function lineCommentScanner(commentCode) {
|
|
1377
|
+
return (input, cur) => {
|
|
1378
|
+
if (input.charCodeAt(cur) !== commentCode) return cur;
|
|
1379
|
+
let pos = cur + 1;
|
|
1380
|
+
while (pos < input.length) {
|
|
1381
|
+
const cc = input.charCodeAt(pos);
|
|
1382
|
+
if (cc === 10 || cc === 13) break;
|
|
1383
|
+
pos++;
|
|
1362
1384
|
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1385
|
+
return pos;
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
function classRunSource(source) {
|
|
1389
|
+
const m = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]$/.exec(source);
|
|
1390
|
+
return m ? classScanner(m[1]) : null;
|
|
1391
|
+
}
|
|
1392
|
+
function classifyTriviaArm(arm) {
|
|
1393
|
+
const cls = /^\[([^\]^](?:[^\]]|\\.)*)\][*+]?$/.exec(arm);
|
|
1394
|
+
if (cls) {
|
|
1395
|
+
const ranges = parseClassRanges(cls[1]);
|
|
1396
|
+
return ranges ? { kind: "class", ranges } : null;
|
|
1397
|
+
}
|
|
1398
|
+
const lc = /^(\\?.)\[\^\\n\\r\]\*$/.exec(arm);
|
|
1399
|
+
if (lc) {
|
|
1400
|
+
const marker = lc[1];
|
|
1401
|
+
return { kind: "comment", code: (marker.length === 2 ? marker[1] : marker[0]).charCodeAt(0) };
|
|
1369
1402
|
}
|
|
1403
|
+
return null;
|
|
1404
|
+
}
|
|
1405
|
+
function armScanner(arm) {
|
|
1406
|
+
if (arm.kind === "comment") return lineCommentScanner(arm.code);
|
|
1407
|
+
const ranges = arm.ranges;
|
|
1370
1408
|
return (input, cur) => {
|
|
1371
1409
|
let pos = cur;
|
|
1372
|
-
while (pos < input.length &&
|
|
1410
|
+
while (pos < input.length && inRanges2(input.charCodeAt(pos), ranges)) pos++;
|
|
1373
1411
|
return pos;
|
|
1374
1412
|
};
|
|
1375
1413
|
}
|
|
1414
|
+
function fusedTriviaScanner(ranges, commentCodes) {
|
|
1415
|
+
const c0 = commentCodes[0];
|
|
1416
|
+
const single = commentCodes.length === 1;
|
|
1417
|
+
return (input, cur) => {
|
|
1418
|
+
let pos = cur;
|
|
1419
|
+
const len = input.length;
|
|
1420
|
+
for (; ; ) {
|
|
1421
|
+
const c = input.charCodeAt(pos);
|
|
1422
|
+
if (pos < len && inRanges2(c, ranges)) {
|
|
1423
|
+
pos++;
|
|
1424
|
+
continue;
|
|
1425
|
+
}
|
|
1426
|
+
if (single ? c === c0 : commentCodes.includes(c)) {
|
|
1427
|
+
pos++;
|
|
1428
|
+
while (pos < len) {
|
|
1429
|
+
const cc = input.charCodeAt(pos);
|
|
1430
|
+
if (cc === 10 || cc === 13) break;
|
|
1431
|
+
pos++;
|
|
1432
|
+
}
|
|
1433
|
+
continue;
|
|
1434
|
+
}
|
|
1435
|
+
break;
|
|
1436
|
+
}
|
|
1437
|
+
return pos;
|
|
1438
|
+
};
|
|
1439
|
+
}
|
|
1440
|
+
function splitTopLevelAlts(body) {
|
|
1441
|
+
const arms = [];
|
|
1442
|
+
let inClass = false;
|
|
1443
|
+
let start = 0;
|
|
1444
|
+
for (let i = 0; i < body.length; i++) {
|
|
1445
|
+
const c = body[i];
|
|
1446
|
+
if (c === "\\") {
|
|
1447
|
+
i++;
|
|
1448
|
+
continue;
|
|
1449
|
+
}
|
|
1450
|
+
if (inClass) {
|
|
1451
|
+
if (c === "]") inClass = false;
|
|
1452
|
+
continue;
|
|
1453
|
+
}
|
|
1454
|
+
if (c === "[") inClass = true;
|
|
1455
|
+
else if (c === "(") return null;
|
|
1456
|
+
else if (c === "|") {
|
|
1457
|
+
arms.push(body.slice(start, i));
|
|
1458
|
+
start = i + 1;
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
arms.push(body.slice(start));
|
|
1462
|
+
return arms;
|
|
1463
|
+
}
|
|
1464
|
+
function altStarSource(source) {
|
|
1465
|
+
const m = /^\(\?:(.*)\)[*+]$/.exec(source);
|
|
1466
|
+
if (!m) return null;
|
|
1467
|
+
const armSrcs = splitTopLevelAlts(m[1]);
|
|
1468
|
+
if (!armSrcs || armSrcs.length < 2) return null;
|
|
1469
|
+
const arms = [];
|
|
1470
|
+
for (const src of armSrcs) {
|
|
1471
|
+
const arm = classifyTriviaArm(src);
|
|
1472
|
+
if (!arm) return null;
|
|
1473
|
+
arms.push(arm);
|
|
1474
|
+
}
|
|
1475
|
+
const ranges = [];
|
|
1476
|
+
const commentCodes = [];
|
|
1477
|
+
for (const arm of arms) {
|
|
1478
|
+
if (arm.kind === "class") ranges.push(...arm.ranges);
|
|
1479
|
+
else commentCodes.push(arm.code);
|
|
1480
|
+
}
|
|
1481
|
+
if (commentCodes.some((code) => inRanges2(code, ranges))) {
|
|
1482
|
+
return loopScanner(arms.map(armScanner));
|
|
1483
|
+
}
|
|
1484
|
+
if (commentCodes.length === 0) return armScanner({ kind: "class", ranges });
|
|
1485
|
+
return fusedTriviaScanner(ranges, commentCodes);
|
|
1486
|
+
}
|
|
1376
1487
|
function blockCommentSource(source) {
|
|
1377
1488
|
return source === "\\/\\*(?:[^*]|\\*(?!\\/))*\\*\\/" || source === "\\/\\*[^]*?\\*\\/";
|
|
1378
1489
|
}
|
|
@@ -1689,6 +1800,7 @@ function markUnusedValues(root) {
|
|
|
1689
1800
|
}
|
|
1690
1801
|
|
|
1691
1802
|
// src/combinators/parser.ts
|
|
1803
|
+
var RULE_ORDER = "__parsemanRuleOrder";
|
|
1692
1804
|
function tagRule(r, key) {
|
|
1693
1805
|
;
|
|
1694
1806
|
r._ruleName = key;
|
|
@@ -1733,6 +1845,11 @@ function rules(a, b) {
|
|
|
1733
1845
|
for (const key of Object.keys(definitions)) {
|
|
1734
1846
|
markUnusedValues(cache[key]);
|
|
1735
1847
|
}
|
|
1848
|
+
Object.defineProperty(cache, RULE_ORDER, {
|
|
1849
|
+
value: Object.keys(definitions),
|
|
1850
|
+
enumerable: false,
|
|
1851
|
+
configurable: true
|
|
1852
|
+
});
|
|
1736
1853
|
return cache;
|
|
1737
1854
|
}
|
|
1738
1855
|
|
|
@@ -5504,9 +5621,10 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
5504
5621
|
].join("\n");
|
|
5505
5622
|
return { keys: perEntry.map((e) => e.key), replacement };
|
|
5506
5623
|
}
|
|
5507
|
-
function compileLinkable(ruleMapArg, ns) {
|
|
5624
|
+
function compileLinkable(ruleMapArg, ns, opts) {
|
|
5508
5625
|
if (!ns) throw new Error("compileLinkable: ns must be a non-empty namespace");
|
|
5509
5626
|
for (const [, rule] of ruleMapArg) markUnusedValues(rule);
|
|
5627
|
+
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
5510
5628
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
5511
5629
|
const d = val._def;
|
|
5512
5630
|
if (d.tag !== "lazy") return true;
|
|
@@ -5537,7 +5655,8 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5537
5655
|
capturing: ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
5538
5656
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
5539
5657
|
ns,
|
|
5540
|
-
deferFirstSetRefs: true
|
|
5658
|
+
deferFirstSetRefs: true,
|
|
5659
|
+
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {}
|
|
5541
5660
|
};
|
|
5542
5661
|
const seen = /* @__PURE__ */ new Map();
|
|
5543
5662
|
const ruleNames = /* @__PURE__ */ new Map();
|
|
@@ -5600,7 +5719,10 @@ function compileLinkable(ruleMapArg, ns) {
|
|
|
5600
5719
|
ctx.indent = 1;
|
|
5601
5720
|
ctx.failLabel = "_pfail";
|
|
5602
5721
|
ctx.recordFail = true;
|
|
5722
|
+
const savedTrivia = ctx.activeTrivia;
|
|
5723
|
+
if (rule._meta.isTrivia) ctx.activeTrivia = void 0;
|
|
5603
5724
|
const body = emit(resolved, ctx, "_pos");
|
|
5725
|
+
ctx.activeTrivia = savedTrivia;
|
|
5604
5726
|
ctx.indent = savedIndent;
|
|
5605
5727
|
ctx.failLabel = savedFail;
|
|
5606
5728
|
ctx.recordFail = savedRec;
|
|
@@ -6094,6 +6216,23 @@ ${body}
|
|
|
6094
6216
|
};
|
|
6095
6217
|
|
|
6096
6218
|
// src/compiler/linker.ts
|
|
6219
|
+
function pickPieces(pieces, names) {
|
|
6220
|
+
const winner = /* @__PURE__ */ new Map();
|
|
6221
|
+
for (const pc of pieces) for (const k of pc.keys) winner.set(k, pc);
|
|
6222
|
+
for (const n of names) {
|
|
6223
|
+
if (!winner.has(n)) throw new Error(`pick: rule "${n}" is not in this grammar (available: ${[...winner.keys()].join(", ")})`);
|
|
6224
|
+
}
|
|
6225
|
+
const keep = /* @__PURE__ */ new Set();
|
|
6226
|
+
const visit = (n) => {
|
|
6227
|
+
const w = winner.get(n);
|
|
6228
|
+
if (keep.has(n) || !w) return;
|
|
6229
|
+
keep.add(n);
|
|
6230
|
+
for (const d of w.deps.get(n) ?? []) visit(d);
|
|
6231
|
+
};
|
|
6232
|
+
for (const n of names) visit(n);
|
|
6233
|
+
const filt = (m, pc) => new Map([...m].filter(([k]) => keep.has(k) && winner.get(k) === pc));
|
|
6234
|
+
return pieces.map((pc) => ({ ...pc, keys: pc.keys.filter((k) => keep.has(k) && winner.get(k) === pc), ruleFns: filt(pc.ruleFns, pc), wrappers: filt(pc.wrappers, pc), deps: filt(pc.deps, pc) })).filter((pc) => pc.keys.length > 0);
|
|
6235
|
+
}
|
|
6097
6236
|
function fusedBody(pieces) {
|
|
6098
6237
|
const winner = /* @__PURE__ */ new Map();
|
|
6099
6238
|
for (const p of pieces) for (const k of p.keys) winner.set(k, p);
|
|
@@ -6113,7 +6252,7 @@ function fusedBody(pieces) {
|
|
|
6113
6252
|
...needsEmptyTl ? ["const _EMPTY_TL = Object.freeze([])"] : [],
|
|
6114
6253
|
...needsHostReads ? [HOST_READS_DECL] : [],
|
|
6115
6254
|
// Each contributing artifact's namespaced private prelude (regexes, _pf, …).
|
|
6116
|
-
...
|
|
6255
|
+
...new Set(contributingPieces.flatMap((p) => p.prelude)),
|
|
6117
6256
|
// The winning `_r_<Name>` function for each rule (one per name → no redeclare).
|
|
6118
6257
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
6119
6258
|
];
|
|
@@ -6154,9 +6293,9 @@ ${body}
|
|
|
6154
6293
|
function isIRPiece(p) {
|
|
6155
6294
|
return !!p && typeof p === "object" && typeof p.ir === "string" && typeof p.ns === "string" && !("ruleFns" in p);
|
|
6156
6295
|
}
|
|
6157
|
-
function materializePiece(p) {
|
|
6296
|
+
function materializePiece(p, trivia2) {
|
|
6158
6297
|
if (!isIRPiece(p)) return p;
|
|
6159
|
-
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns);
|
|
6298
|
+
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, trivia2 ? { trivia: trivia2 } : void 0);
|
|
6160
6299
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
6161
6300
|
return pieces;
|
|
6162
6301
|
}
|
|
@@ -6862,11 +7001,13 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
6862
7001
|
warn(init.start, `${label2}: rule map couldn't be inlined`);
|
|
6863
7002
|
return null;
|
|
6864
7003
|
}
|
|
6865
|
-
return { replacement: compiled.replacement, ruleMap };
|
|
7004
|
+
return { replacement: compiled.replacement, ruleMap, ...gTrivia ? { trivia: gTrivia } : {} };
|
|
6866
7005
|
};
|
|
6867
7006
|
const isRulesCall = (init) => init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "rules";
|
|
6868
7007
|
const isComposeCall = (init) => init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "compose";
|
|
7008
|
+
const isPickCall = (init) => init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "pick";
|
|
6869
7009
|
const localRuleMaps = /* @__PURE__ */ new Map();
|
|
7010
|
+
const localGrammarTrivia = /* @__PURE__ */ new Map();
|
|
6870
7011
|
const nsFor = (label2) => `_${createHash("sha1").update(`${id}#${label2}`).digest("hex").slice(0, 8)}_`;
|
|
6871
7012
|
const stripIndent = (s) => s.replace(/\n[ \t]+/g, "\n");
|
|
6872
7013
|
const serializePieces = (p) => {
|
|
@@ -6880,7 +7021,8 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
6880
7021
|
const serializeItem = (it) => isSpread(it) ? `...(${it.__spreadLocal}[Symbol.for('parseman.composedPieces')] ?? [])` : isIR(it) ? `{ ns: ${JSON.stringify(it.ns)}, ir: ${JSON.stringify(it.ir)} }` : serializePieces(it);
|
|
6881
7022
|
const serializeList = (list) => `[${list.map(serializeItem).join(", ")}]`;
|
|
6882
7023
|
const withCarriedPieces = (grammarExpr, list) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.composedPieces'), { value: ${serializeList(list)}, enumerable: false })`;
|
|
6883
|
-
const
|
|
7024
|
+
const localComposedCarried = /* @__PURE__ */ new Map();
|
|
7025
|
+
const localComposedTrivia = /* @__PURE__ */ new Map();
|
|
6884
7026
|
const importedPiecesCache = /* @__PURE__ */ new Map();
|
|
6885
7027
|
const resolveModulePieces = (file, exportName, seen) => {
|
|
6886
7028
|
const mod = parseModuleCached(file);
|
|
@@ -6914,7 +7056,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
6914
7056
|
}
|
|
6915
7057
|
try {
|
|
6916
7058
|
const list = new Function(...stubNames, `return (${literal2})`)(...stubVals);
|
|
6917
|
-
return list
|
|
7059
|
+
return list;
|
|
6918
7060
|
} catch {
|
|
6919
7061
|
return null;
|
|
6920
7062
|
}
|
|
@@ -6934,32 +7076,108 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
6934
7076
|
importedPiecesCache.set(localName, result2);
|
|
6935
7077
|
return result2;
|
|
6936
7078
|
};
|
|
6937
|
-
const
|
|
7079
|
+
const materializeCarried = (items, composing) => {
|
|
7080
|
+
const out = [];
|
|
7081
|
+
for (const it of items) {
|
|
7082
|
+
if (isSpread(it)) {
|
|
7083
|
+
for (const p of importedPieces(it.__spreadLocal) ?? []) out.push(materializePiece(p, composing));
|
|
7084
|
+
} else if (isIR(it)) {
|
|
7085
|
+
out.push(materializePiece(it, composing));
|
|
7086
|
+
} else {
|
|
7087
|
+
out.push(it);
|
|
7088
|
+
}
|
|
7089
|
+
}
|
|
7090
|
+
return out;
|
|
7091
|
+
};
|
|
7092
|
+
const localCarried = (rm, label2, composing) => {
|
|
6938
7093
|
const entries = [...rm];
|
|
6939
7094
|
const ns = nsFor(label2);
|
|
6940
|
-
const p = compileLinkable(entries, ns);
|
|
6941
|
-
if (!p) return null;
|
|
6942
7095
|
const ir = serializeRuleMap(entries);
|
|
6943
|
-
|
|
7096
|
+
if (ir) return { carried: [{ ns, ir }] };
|
|
7097
|
+
const p = compileLinkable(entries, ns, composing ? { trivia: composing } : void 0);
|
|
7098
|
+
return p ? { carried: [p] } : null;
|
|
6944
7099
|
};
|
|
6945
|
-
const argPieces = (arg, label2) => {
|
|
7100
|
+
const argPieces = (arg, label2, composing) => {
|
|
7101
|
+
if (isPickCall(arg)) {
|
|
7102
|
+
const pargs = arg.arguments;
|
|
7103
|
+
const inner = pargs[0];
|
|
7104
|
+
const namesArg = pargs[1];
|
|
7105
|
+
if (!inner || namesArg?.type !== "ArrayExpression") return null;
|
|
7106
|
+
const names = [];
|
|
7107
|
+
for (const el of namesArg.elements ?? []) {
|
|
7108
|
+
const v2 = el?.value;
|
|
7109
|
+
if ((el?.type === "Literal" || el?.type === "StringLiteral") && typeof v2 === "string") names.push(v2);
|
|
7110
|
+
else return null;
|
|
7111
|
+
}
|
|
7112
|
+
const innerArg = argPieces(inner, `${label2}_pick`);
|
|
7113
|
+
if (!innerArg) return null;
|
|
7114
|
+
try {
|
|
7115
|
+
return { carried: pickPieces(materializeCarried(innerArg.carried, ownTrivia(inner)), names) };
|
|
7116
|
+
} catch (e) {
|
|
7117
|
+
warn(arg.start, `pick(): ${e.message}`);
|
|
7118
|
+
return null;
|
|
7119
|
+
}
|
|
7120
|
+
}
|
|
6946
7121
|
if (isRulesCall(arg)) {
|
|
6947
|
-
const
|
|
7122
|
+
const rulesArgs = arg.arguments;
|
|
7123
|
+
const a0 = rulesArgs[0];
|
|
7124
|
+
const a1 = rulesArgs[1];
|
|
7125
|
+
const optionsFirst = a0?.type === "ObjectExpression";
|
|
7126
|
+
const factory = optionsFirst ? a1 : a0;
|
|
6948
7127
|
const rm = factory ? evaluateParserFactory(factory, scope, code, []) : null;
|
|
6949
|
-
return rm ?
|
|
7128
|
+
return rm ? localCarried(rm, label2, composing) : null;
|
|
6950
7129
|
}
|
|
6951
7130
|
if (arg.type === "Identifier") {
|
|
6952
7131
|
const name = arg.name;
|
|
6953
7132
|
const rm = localRuleMaps.get(name);
|
|
6954
|
-
if (rm) return
|
|
6955
|
-
const composed =
|
|
6956
|
-
if (composed) return {
|
|
7133
|
+
if (rm) return localCarried(rm, label2, composing);
|
|
7134
|
+
const composed = localComposedCarried.get(name);
|
|
7135
|
+
if (composed) return { carried: composed };
|
|
6957
7136
|
const pieces = importedPieces(name);
|
|
6958
7137
|
if (!pieces) return null;
|
|
6959
|
-
return importBindings.has(name) ? {
|
|
7138
|
+
return { carried: importBindings.has(name) ? [{ __spreadLocal: name }] : [...pieces] };
|
|
6960
7139
|
}
|
|
6961
7140
|
return null;
|
|
6962
7141
|
};
|
|
7142
|
+
const rulesCallTrivia = (el) => {
|
|
7143
|
+
const rulesArgs = el.arguments;
|
|
7144
|
+
const a0 = rulesArgs[0];
|
|
7145
|
+
const a1 = rulesArgs[1];
|
|
7146
|
+
const optExpr = a0?.type === "ObjectExpression" ? a0 : a1?.type === "ObjectExpression" ? a1 : void 0;
|
|
7147
|
+
const triviaProp = (optExpr?.properties ?? []).find(
|
|
7148
|
+
(p) => p.key?.name === "trivia"
|
|
7149
|
+
);
|
|
7150
|
+
if (!triviaProp?.value) return void 0;
|
|
7151
|
+
return evaluateExpr(triviaProp.value, scope, code, []) ?? void 0;
|
|
7152
|
+
};
|
|
7153
|
+
const composingTrivia = (elements) => {
|
|
7154
|
+
for (let i = elements.length - 1; i >= 0; i--) {
|
|
7155
|
+
const el = elements[i];
|
|
7156
|
+
if (!el) continue;
|
|
7157
|
+
if (isRulesCall(el)) {
|
|
7158
|
+
const t = rulesCallTrivia(el);
|
|
7159
|
+
if (t) return t;
|
|
7160
|
+
continue;
|
|
7161
|
+
}
|
|
7162
|
+
if (el.type === "Identifier") {
|
|
7163
|
+
const t = localGrammarTrivia.get(el.name);
|
|
7164
|
+
if (t) return t;
|
|
7165
|
+
}
|
|
7166
|
+
}
|
|
7167
|
+
return void 0;
|
|
7168
|
+
};
|
|
7169
|
+
const ownTrivia = (arg) => {
|
|
7170
|
+
if (isRulesCall(arg)) return rulesCallTrivia(arg);
|
|
7171
|
+
if (isPickCall(arg)) {
|
|
7172
|
+
const inner = arg.arguments[0];
|
|
7173
|
+
return inner ? ownTrivia(inner) : void 0;
|
|
7174
|
+
}
|
|
7175
|
+
if (arg.type === "Identifier") {
|
|
7176
|
+
const name = arg.name;
|
|
7177
|
+
return localGrammarTrivia.get(name) ?? localComposedTrivia.get(name);
|
|
7178
|
+
}
|
|
7179
|
+
return void 0;
|
|
7180
|
+
};
|
|
6963
7181
|
const compileComposeCall = (init) => {
|
|
6964
7182
|
const args = init.arguments;
|
|
6965
7183
|
const arr = args[0];
|
|
@@ -6968,21 +7186,19 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
6968
7186
|
return null;
|
|
6969
7187
|
}
|
|
6970
7188
|
const elements = arr.elements;
|
|
6971
|
-
const
|
|
7189
|
+
const composing = composingTrivia(elements);
|
|
6972
7190
|
const carried = [];
|
|
6973
7191
|
for (let i = 0; i < elements.length; i++) {
|
|
6974
|
-
const r = argPieces(elements[i], `compose${init.start}_${i}
|
|
7192
|
+
const r = argPieces(elements[i], `compose${init.start}_${i}`, composing);
|
|
6975
7193
|
if (!r) {
|
|
6976
7194
|
warn(init.start, `compose(): argument ${i} isn't a build-resolvable grammar; falling back to runtime`);
|
|
6977
7195
|
return null;
|
|
6978
7196
|
}
|
|
6979
|
-
|
|
6980
|
-
if (r.spreadLocal) carried.push({ __spreadLocal: r.spreadLocal });
|
|
6981
|
-
else if (r.ir) carried.push(r.ir);
|
|
6982
|
-
else carried.push(...r.pieces);
|
|
7197
|
+
carried.push(...r.carried);
|
|
6983
7198
|
}
|
|
7199
|
+
const pieces = materializeCarried(carried, composing);
|
|
6984
7200
|
try {
|
|
6985
|
-
return { replacement: emitFusedSource(pieces),
|
|
7201
|
+
return { replacement: emitFusedSource(pieces), carried, ...composing ? { trivia: composing } : {} };
|
|
6986
7202
|
} catch (e) {
|
|
6987
7203
|
warn(init.start, `compose(): ${e.message}; falling back to runtime`);
|
|
6988
7204
|
return null;
|
|
@@ -7067,6 +7283,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
7067
7283
|
const compiledRules = compileRulesFactory(init, varName);
|
|
7068
7284
|
if (!compiledRules) continue;
|
|
7069
7285
|
localRuleMaps.set(varName, compiledRules.ruleMap);
|
|
7286
|
+
if (compiledRules.trivia) localGrammarTrivia.set(varName, compiledRules.trivia);
|
|
7070
7287
|
let replacement = compiledRules.replacement;
|
|
7071
7288
|
if (exportPrefix) {
|
|
7072
7289
|
const ns = nsFor(varName);
|
|
@@ -7082,7 +7299,8 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
7082
7299
|
if (isComposeCall(init)) {
|
|
7083
7300
|
const fused = compileComposeCall(init);
|
|
7084
7301
|
if (!fused) continue;
|
|
7085
|
-
|
|
7302
|
+
localComposedCarried.set(varName, fused.carried);
|
|
7303
|
+
if (fused.trivia) localComposedTrivia.set(varName, fused.trivia);
|
|
7086
7304
|
const replacement = exportPrefix ? withCarriedPieces(fused.replacement, fused.carried) : fused.replacement;
|
|
7087
7305
|
replacements.push({ start: init.start, end: init.end, replacement });
|
|
7088
7306
|
continue;
|