parseman 0.12.0 → 0.13.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/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/scannable-run.d.ts +80 -2
- package/dist/compiler/scannable-run.d.ts.map +1 -1
- package/dist/cst/types.d.ts +1 -1
- package/dist/functional/doc.d.ts +6 -6
- package/dist/functional/doc.d.ts.map +1 -1
- package/dist/index.cjs +727 -52
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +727 -52
- package/dist/index.js.map +3 -3
- package/dist/plugin/evaluator.d.ts +28 -2
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +974 -101
- package/dist/plugin/index.cjs.map +3 -3
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +974 -101
- package/dist/plugin/index.js.map +3 -3
- package/package.json +5 -4
- package/dist/combinators/lazy.d.ts +0 -14
- package/dist/combinators/lazy.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1399,8 +1399,29 @@ function expect(combinator, label2) {
|
|
|
1399
1399
|
var BACKSLASH = 92;
|
|
1400
1400
|
var CLASS_ESCAPES = { t: 9, n: 10, r: 13, f: 12, v: 11, "0": 0 };
|
|
1401
1401
|
var META = new Set("()[]{}*+?|^$.".split(""));
|
|
1402
|
+
var SPACE_RANGES = [
|
|
1403
|
+
[9, 13],
|
|
1404
|
+
[32, 32],
|
|
1405
|
+
[160, 160],
|
|
1406
|
+
[5760, 5760],
|
|
1407
|
+
[8192, 8202],
|
|
1408
|
+
[8232, 8232],
|
|
1409
|
+
[8233, 8233],
|
|
1410
|
+
[8239, 8239],
|
|
1411
|
+
[8287, 8287],
|
|
1412
|
+
[12288, 12288],
|
|
1413
|
+
[65279, 65279]
|
|
1414
|
+
];
|
|
1402
1415
|
function shorthandRanges(ch) {
|
|
1403
|
-
|
|
1416
|
+
if (ch === "d") return [[48, 57]];
|
|
1417
|
+
if (ch === "s") return SPACE_RANGES;
|
|
1418
|
+
return [[48, 57], [65, 90], [97, 122], [95, 95]];
|
|
1419
|
+
}
|
|
1420
|
+
function readUnicodeEscape(body, i) {
|
|
1421
|
+
if (body[i] !== "\\" || body[i + 1] !== "u") return null;
|
|
1422
|
+
const hex = body.slice(i + 2, i + 6);
|
|
1423
|
+
if (!/^[0-9a-fA-F]{4}$/.test(hex)) return null;
|
|
1424
|
+
return { cp: Number.parseInt(hex, 16), next: i + 6 };
|
|
1404
1425
|
}
|
|
1405
1426
|
function parseClassRanges(body) {
|
|
1406
1427
|
const ranges = [];
|
|
@@ -1409,11 +1430,16 @@ function parseClassRanges(body) {
|
|
|
1409
1430
|
const ch = body[i];
|
|
1410
1431
|
if (ch === void 0) return null;
|
|
1411
1432
|
if (ch === "\\") {
|
|
1433
|
+
const uni = readUnicodeEscape(body, i);
|
|
1434
|
+
if (uni) {
|
|
1435
|
+
i = uni.next;
|
|
1436
|
+
return { cp: uni.cp };
|
|
1437
|
+
}
|
|
1412
1438
|
const e = body[i + 1];
|
|
1413
1439
|
if (e === void 0) return null;
|
|
1414
1440
|
i += 2;
|
|
1415
1441
|
if (e in CLASS_ESCAPES) return { cp: CLASS_ESCAPES[e] };
|
|
1416
|
-
if (e === "d" || e === "w") return { set: shorthandRanges(e) };
|
|
1442
|
+
if (e === "d" || e === "w" || e === "s") return { set: shorthandRanges(e) };
|
|
1417
1443
|
if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
1418
1444
|
return { cp: e.codePointAt(0) };
|
|
1419
1445
|
}
|
|
@@ -1441,10 +1467,16 @@ function parseClassRanges(body) {
|
|
|
1441
1467
|
function classToRanges(cls) {
|
|
1442
1468
|
if (cls === "\\d") return shorthandRanges("d");
|
|
1443
1469
|
if (cls === "\\w") return shorthandRanges("w");
|
|
1470
|
+
if (cls === "\\s") return shorthandRanges("s");
|
|
1444
1471
|
const body = cls.slice(1, -1);
|
|
1445
1472
|
if (body.startsWith("^")) return null;
|
|
1446
1473
|
return parseClassRanges(body);
|
|
1447
1474
|
}
|
|
1475
|
+
var foldEq = (cVar, cp) => {
|
|
1476
|
+
if (cp >= 65 && cp <= 90) return `(${cVar} === ${cp} || ${cVar} === ${cp + 32})`;
|
|
1477
|
+
if (cp >= 97 && cp <= 122) return `(${cVar} === ${cp} || ${cVar} === ${cp - 32})`;
|
|
1478
|
+
return `${cVar} === ${cp}`;
|
|
1479
|
+
};
|
|
1448
1480
|
function literalCodePoints(frag) {
|
|
1449
1481
|
const out = [];
|
|
1450
1482
|
let i = 0;
|
|
@@ -1491,22 +1523,446 @@ function parseStringShape(source) {
|
|
|
1491
1523
|
if (!inSet(qcp) || !inSet(BACKSLASH)) return null;
|
|
1492
1524
|
return { kind: "string", quote: qcp, excluded, escLineTerm: esc !== "." };
|
|
1493
1525
|
}
|
|
1526
|
+
function parseSeqParts(source) {
|
|
1527
|
+
const parts = [];
|
|
1528
|
+
let lit = [];
|
|
1529
|
+
const flush = () => {
|
|
1530
|
+
if (lit.length) {
|
|
1531
|
+
parts.push({ part: "lit", cps: lit, optional: false });
|
|
1532
|
+
lit = [];
|
|
1533
|
+
}
|
|
1534
|
+
};
|
|
1535
|
+
const runFrom = (ranges, negated, q) => {
|
|
1536
|
+
if (q === "+") {
|
|
1537
|
+
parts.push({ part: "run", ranges, negated, min: 1, unbounded: true });
|
|
1538
|
+
return 1;
|
|
1539
|
+
}
|
|
1540
|
+
if (q === "*") {
|
|
1541
|
+
parts.push({ part: "run", ranges, negated, min: 0, unbounded: true });
|
|
1542
|
+
return 1;
|
|
1543
|
+
}
|
|
1544
|
+
if (q === "?") {
|
|
1545
|
+
parts.push({ part: "run", ranges, negated, min: 0, unbounded: false });
|
|
1546
|
+
return 1;
|
|
1547
|
+
}
|
|
1548
|
+
parts.push({ part: "run", ranges, negated, min: 1, unbounded: false });
|
|
1549
|
+
return 0;
|
|
1550
|
+
};
|
|
1551
|
+
let i = 0;
|
|
1552
|
+
while (i < source.length) {
|
|
1553
|
+
const ch = source[i];
|
|
1554
|
+
if (ch === "[") {
|
|
1555
|
+
let k = i + 1;
|
|
1556
|
+
const neg = source[k] === "^";
|
|
1557
|
+
if (neg) k++;
|
|
1558
|
+
let body = "";
|
|
1559
|
+
while (k < source.length && source[k] !== "]") {
|
|
1560
|
+
if (source[k] === "\\") {
|
|
1561
|
+
body += source[k] + (source[k + 1] ?? "");
|
|
1562
|
+
k += 2;
|
|
1563
|
+
} else {
|
|
1564
|
+
body += source[k];
|
|
1565
|
+
k++;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
if (source[k] !== "]") return null;
|
|
1569
|
+
const ranges = parseClassRanges(body);
|
|
1570
|
+
if (!ranges) return null;
|
|
1571
|
+
flush();
|
|
1572
|
+
i = k + 1;
|
|
1573
|
+
i += runFrom(ranges, neg, source[i]);
|
|
1574
|
+
continue;
|
|
1575
|
+
}
|
|
1576
|
+
if (ch === "\\") {
|
|
1577
|
+
const e = source[i + 1];
|
|
1578
|
+
if (e === "d" || e === "w" || e === "s") {
|
|
1579
|
+
flush();
|
|
1580
|
+
i += 2;
|
|
1581
|
+
i += runFrom(shorthandRanges(e), false, source[i]);
|
|
1582
|
+
continue;
|
|
1583
|
+
}
|
|
1584
|
+
const uni = readUnicodeEscape(source, i);
|
|
1585
|
+
let cp2;
|
|
1586
|
+
if (uni) {
|
|
1587
|
+
cp2 = uni.cp;
|
|
1588
|
+
i = uni.next;
|
|
1589
|
+
} else if (e === void 0) return null;
|
|
1590
|
+
else if (e in CLASS_ESCAPES) {
|
|
1591
|
+
cp2 = CLASS_ESCAPES[e];
|
|
1592
|
+
i += 2;
|
|
1593
|
+
} else if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
1594
|
+
else {
|
|
1595
|
+
cp2 = e.codePointAt(0);
|
|
1596
|
+
i += 2;
|
|
1597
|
+
}
|
|
1598
|
+
if (source[i] === "?") {
|
|
1599
|
+
flush();
|
|
1600
|
+
parts.push({ part: "lit", cps: [cp2], optional: true });
|
|
1601
|
+
i++;
|
|
1602
|
+
} else lit.push(cp2);
|
|
1603
|
+
continue;
|
|
1604
|
+
}
|
|
1605
|
+
if (ch === "(") {
|
|
1606
|
+
if (source[i + 1] !== "?" || source[i + 2] !== ":") return null;
|
|
1607
|
+
let k = i + 3;
|
|
1608
|
+
let depth = 1;
|
|
1609
|
+
while (k < source.length && depth > 0) {
|
|
1610
|
+
const c2 = source[k];
|
|
1611
|
+
if (c2 === "\\") {
|
|
1612
|
+
k += 2;
|
|
1613
|
+
continue;
|
|
1614
|
+
}
|
|
1615
|
+
if (c2 === "[") {
|
|
1616
|
+
let j = k + 1;
|
|
1617
|
+
if (source[j] === "^") j++;
|
|
1618
|
+
while (j < source.length && source[j] !== "]") {
|
|
1619
|
+
if (source[j] === "\\") j += 2;
|
|
1620
|
+
else j++;
|
|
1621
|
+
}
|
|
1622
|
+
if (source[j] !== "]") return null;
|
|
1623
|
+
k = j + 1;
|
|
1624
|
+
continue;
|
|
1625
|
+
}
|
|
1626
|
+
if (c2 === "(") depth++;
|
|
1627
|
+
else if (c2 === ")") depth--;
|
|
1628
|
+
k++;
|
|
1629
|
+
}
|
|
1630
|
+
if (depth !== 0) return null;
|
|
1631
|
+
const body = source.slice(i + 3, k - 1);
|
|
1632
|
+
const inner = parseScanShape(body);
|
|
1633
|
+
if (!inner || !groupInnerSafe(inner)) return null;
|
|
1634
|
+
const q = source[k];
|
|
1635
|
+
if (q === "{") return null;
|
|
1636
|
+
flush();
|
|
1637
|
+
if (q === "+") {
|
|
1638
|
+
if (shapeCanBeEmpty(inner)) return null;
|
|
1639
|
+
parts.push({ part: "group", inner, min: 1, unbounded: true });
|
|
1640
|
+
i = k + 1;
|
|
1641
|
+
} else if (q === "*") {
|
|
1642
|
+
if (shapeCanBeEmpty(inner)) return null;
|
|
1643
|
+
parts.push({ part: "group", inner, min: 0, unbounded: true });
|
|
1644
|
+
i = k + 1;
|
|
1645
|
+
} else if (q === "?") {
|
|
1646
|
+
parts.push({ part: "group", inner, min: 0, unbounded: false });
|
|
1647
|
+
i = k + 1;
|
|
1648
|
+
} else {
|
|
1649
|
+
parts.push({ part: "group", inner, min: 1, unbounded: false });
|
|
1650
|
+
i = k;
|
|
1651
|
+
}
|
|
1652
|
+
continue;
|
|
1653
|
+
}
|
|
1654
|
+
if (META.has(ch)) return null;
|
|
1655
|
+
const cp = ch.codePointAt(0);
|
|
1656
|
+
i += ch.length;
|
|
1657
|
+
if (source[i] === "?") {
|
|
1658
|
+
flush();
|
|
1659
|
+
parts.push({ part: "lit", cps: [cp], optional: true });
|
|
1660
|
+
i++;
|
|
1661
|
+
} else lit.push(cp);
|
|
1662
|
+
}
|
|
1663
|
+
flush();
|
|
1664
|
+
return parts.length ? parts : null;
|
|
1665
|
+
}
|
|
1666
|
+
function seqIsUnambiguous(parts) {
|
|
1667
|
+
let hasMandatory = false;
|
|
1668
|
+
for (let k = 0; k < parts.length; k++) {
|
|
1669
|
+
const p = parts[k];
|
|
1670
|
+
const mandatory = p.part === "lit" ? !p.optional : p.min === 1;
|
|
1671
|
+
if (mandatory) hasMandatory = true;
|
|
1672
|
+
const skippableSingle = p.part === "lit" && p.optional || p.part !== "lit" && !p.unbounded && p.min === 0;
|
|
1673
|
+
const isUnboundedRepeat = p.part !== "lit" && p.unbounded;
|
|
1674
|
+
if (skippableSingle || isUnboundedRepeat) {
|
|
1675
|
+
const rest = seqFirstAccept(parts.slice(k + 1));
|
|
1676
|
+
if (!firstSetsDisjoint(partFirstAccept(p), rest)) return false;
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
return hasMandatory;
|
|
1680
|
+
}
|
|
1681
|
+
function rangesOverlap(a, b) {
|
|
1682
|
+
return a.some(([lo, hi]) => b.some(([lo2, hi2]) => lo <= hi2 && lo2 <= hi));
|
|
1683
|
+
}
|
|
1684
|
+
function rangesSubset(sub, sup) {
|
|
1685
|
+
return sub.every(([lo, hi]) => sup.some(([lo2, hi2]) => lo >= lo2 && hi <= hi2));
|
|
1686
|
+
}
|
|
1687
|
+
function parseClassOperand(body) {
|
|
1688
|
+
if (body === "\\d" || body === "\\w" || body === "\\s") {
|
|
1689
|
+
return { ranges: shorthandRanges(body[1]), negated: false };
|
|
1690
|
+
}
|
|
1691
|
+
if (body.length >= 2 && body[0] === "[" && body[body.length - 1] === "]") {
|
|
1692
|
+
let inner = body.slice(1, -1);
|
|
1693
|
+
const negated = inner.startsWith("^");
|
|
1694
|
+
if (negated) inner = inner.slice(1);
|
|
1695
|
+
const ranges = parseClassRanges(inner);
|
|
1696
|
+
return ranges ? { ranges, negated } : null;
|
|
1697
|
+
}
|
|
1698
|
+
const cps = literalCodePoints(body);
|
|
1699
|
+
if (cps && cps.length === 1) return { ranges: [[cps[0], cps[0]]], negated: false };
|
|
1700
|
+
return null;
|
|
1701
|
+
}
|
|
1702
|
+
function classSubset(t, u) {
|
|
1703
|
+
if (!t.negated && !u.negated) return rangesSubset(t.ranges, u.ranges);
|
|
1704
|
+
if (!t.negated && u.negated) return !rangesOverlap(t.ranges, u.ranges);
|
|
1705
|
+
if (t.negated && !u.negated) return false;
|
|
1706
|
+
return rangesSubset(u.ranges, t.ranges);
|
|
1707
|
+
}
|
|
1708
|
+
function classDisjoint(t, u) {
|
|
1709
|
+
if (!t.negated && !u.negated) return !rangesOverlap(t.ranges, u.ranges);
|
|
1710
|
+
if (!t.negated && u.negated) return rangesSubset(t.ranges, u.ranges);
|
|
1711
|
+
if (t.negated && !u.negated) return rangesSubset(u.ranges, t.ranges);
|
|
1712
|
+
return false;
|
|
1713
|
+
}
|
|
1714
|
+
function firstSetsDisjoint(a, b) {
|
|
1715
|
+
if (a === "any" || b === "any") return false;
|
|
1716
|
+
return classDisjoint(a, b);
|
|
1717
|
+
}
|
|
1718
|
+
function trailingBacktrackClass(shape) {
|
|
1719
|
+
if (shape.kind === "chars") return { ranges: shape.ranges, negated: false };
|
|
1720
|
+
if (shape.kind === "ident") return { ranges: shape.tail, negated: false };
|
|
1721
|
+
if (shape.kind === "litFold") return null;
|
|
1722
|
+
if (shape.kind === "seq") {
|
|
1723
|
+
const last = shape.parts[shape.parts.length - 1];
|
|
1724
|
+
if (last.part === "lit") return null;
|
|
1725
|
+
if (last.part === "run") {
|
|
1726
|
+
if (last.unbounded || last.min === 0) return { ranges: last.ranges, negated: last.negated };
|
|
1727
|
+
return null;
|
|
1728
|
+
}
|
|
1729
|
+
const innerWiggle = trailingBacktrackClass(last.inner);
|
|
1730
|
+
if (innerWiggle === "unsupported") return "unsupported";
|
|
1731
|
+
const requiredOnce = !last.unbounded && last.min === 1;
|
|
1732
|
+
if (requiredOnce) return innerWiggle;
|
|
1733
|
+
const dropExposed = shapeFirstAccept(last.inner);
|
|
1734
|
+
if (dropExposed === "any") return "unsupported";
|
|
1735
|
+
if (innerWiggle === null) return dropExposed;
|
|
1736
|
+
const unioned = unionCharSets([innerWiggle, dropExposed]);
|
|
1737
|
+
return unioned === "any" ? "unsupported" : unioned;
|
|
1738
|
+
}
|
|
1739
|
+
if (shape.kind === "alt") {
|
|
1740
|
+
if (!shape.disjoint) return "unsupported";
|
|
1741
|
+
const classes = shape.arms.map(trailingBacktrackClass);
|
|
1742
|
+
if (classes.some((c) => c === "unsupported")) return "unsupported";
|
|
1743
|
+
const concrete = classes.filter((c) => c !== null);
|
|
1744
|
+
if (concrete.length === 0) return null;
|
|
1745
|
+
const unioned = unionCharSets(concrete);
|
|
1746
|
+
return unioned === "any" ? "unsupported" : unioned;
|
|
1747
|
+
}
|
|
1748
|
+
return "unsupported";
|
|
1749
|
+
}
|
|
1750
|
+
function lookaheadUnambiguous(inner, operand, negative) {
|
|
1751
|
+
const tail = trailingBacktrackClass(inner);
|
|
1752
|
+
if (tail === "unsupported") return false;
|
|
1753
|
+
if (tail === null) return true;
|
|
1754
|
+
return negative ? classSubset(tail, operand) : classDisjoint(tail, operand);
|
|
1755
|
+
}
|
|
1756
|
+
function stripTrailingLookahead(source) {
|
|
1757
|
+
if (!source.endsWith(")")) return null;
|
|
1758
|
+
for (const negative of [true, false]) {
|
|
1759
|
+
const lead = negative ? "(?!" : "(?=";
|
|
1760
|
+
const idx = source.lastIndexOf(lead);
|
|
1761
|
+
if (idx === -1) continue;
|
|
1762
|
+
const body = source.slice(idx + lead.length, -1);
|
|
1763
|
+
const operand = body.length ? parseClassOperand(body) : null;
|
|
1764
|
+
if (!operand) continue;
|
|
1765
|
+
return { base: source.slice(0, idx), ranges: operand.ranges, classNegated: operand.negated, negative };
|
|
1766
|
+
}
|
|
1767
|
+
return null;
|
|
1768
|
+
}
|
|
1769
|
+
function unwrapOuterGroup(source) {
|
|
1770
|
+
while (source.startsWith("(?:")) {
|
|
1771
|
+
let depth = 1;
|
|
1772
|
+
let i = 3;
|
|
1773
|
+
let ok = true;
|
|
1774
|
+
while (i < source.length && depth > 0) {
|
|
1775
|
+
const ch = source[i];
|
|
1776
|
+
if (ch === "\\") {
|
|
1777
|
+
i += 2;
|
|
1778
|
+
continue;
|
|
1779
|
+
}
|
|
1780
|
+
if (ch === "[") {
|
|
1781
|
+
let j = i + 1;
|
|
1782
|
+
if (source[j] === "^") j++;
|
|
1783
|
+
while (j < source.length && source[j] !== "]") {
|
|
1784
|
+
if (source[j] === "\\") j += 2;
|
|
1785
|
+
else j++;
|
|
1786
|
+
}
|
|
1787
|
+
if (source[j] !== "]") {
|
|
1788
|
+
ok = false;
|
|
1789
|
+
break;
|
|
1790
|
+
}
|
|
1791
|
+
i = j + 1;
|
|
1792
|
+
continue;
|
|
1793
|
+
}
|
|
1794
|
+
if (ch === "(") depth++;
|
|
1795
|
+
else if (ch === ")") depth--;
|
|
1796
|
+
i++;
|
|
1797
|
+
}
|
|
1798
|
+
if (!ok || depth !== 0 || i !== source.length) break;
|
|
1799
|
+
source = source.slice(3, -1);
|
|
1800
|
+
}
|
|
1801
|
+
return source;
|
|
1802
|
+
}
|
|
1803
|
+
function splitTopLevelAlternation(source) {
|
|
1804
|
+
const body = unwrapOuterGroup(source);
|
|
1805
|
+
const parts = [];
|
|
1806
|
+
let depth = 0;
|
|
1807
|
+
let last = 0;
|
|
1808
|
+
let i = 0;
|
|
1809
|
+
while (i < body.length) {
|
|
1810
|
+
const ch = body[i];
|
|
1811
|
+
if (ch === "\\") {
|
|
1812
|
+
i += 2;
|
|
1813
|
+
continue;
|
|
1814
|
+
}
|
|
1815
|
+
if (ch === "[") {
|
|
1816
|
+
let j = i + 1;
|
|
1817
|
+
if (body[j] === "^") j++;
|
|
1818
|
+
while (j < body.length && body[j] !== "]") {
|
|
1819
|
+
if (body[j] === "\\") j += 2;
|
|
1820
|
+
else j++;
|
|
1821
|
+
}
|
|
1822
|
+
if (body[j] !== "]") return null;
|
|
1823
|
+
i = j + 1;
|
|
1824
|
+
continue;
|
|
1825
|
+
}
|
|
1826
|
+
if (ch === "(") {
|
|
1827
|
+
depth++;
|
|
1828
|
+
i++;
|
|
1829
|
+
continue;
|
|
1830
|
+
}
|
|
1831
|
+
if (ch === ")") {
|
|
1832
|
+
depth--;
|
|
1833
|
+
if (depth < 0) return null;
|
|
1834
|
+
i++;
|
|
1835
|
+
continue;
|
|
1836
|
+
}
|
|
1837
|
+
if (ch === "|" && depth === 0) {
|
|
1838
|
+
parts.push(body.slice(last, i));
|
|
1839
|
+
last = i + 1;
|
|
1840
|
+
i++;
|
|
1841
|
+
continue;
|
|
1842
|
+
}
|
|
1843
|
+
i++;
|
|
1844
|
+
}
|
|
1845
|
+
if (depth !== 0) return null;
|
|
1846
|
+
parts.push(body.slice(last));
|
|
1847
|
+
if (parts.length < 2 || parts.some((p) => p.length === 0)) return null;
|
|
1848
|
+
return parts;
|
|
1849
|
+
}
|
|
1850
|
+
function shapeCanBeEmpty(shape) {
|
|
1851
|
+
if (shape.kind === "chars") return !shape.minOne;
|
|
1852
|
+
if (shape.kind === "lookahead") return shapeCanBeEmpty(shape.inner);
|
|
1853
|
+
if (shape.kind === "alt") return shape.arms.some(shapeCanBeEmpty);
|
|
1854
|
+
return false;
|
|
1855
|
+
}
|
|
1856
|
+
function unionCharSets(sets) {
|
|
1857
|
+
if (sets.some((s) => s === "any")) return "any";
|
|
1858
|
+
const concrete = sets;
|
|
1859
|
+
if (concrete.length === 1) return concrete[0];
|
|
1860
|
+
if (concrete.some((s) => s.negated)) return "any";
|
|
1861
|
+
return { ranges: concrete.flatMap((s) => s.ranges), negated: false };
|
|
1862
|
+
}
|
|
1863
|
+
function partFirstAccept(part) {
|
|
1864
|
+
if (part.part === "lit") return { ranges: [[part.cps[0], part.cps[0]]], negated: false };
|
|
1865
|
+
if (part.part === "run") return { ranges: part.ranges, negated: part.negated };
|
|
1866
|
+
return shapeFirstAccept(part.inner);
|
|
1867
|
+
}
|
|
1868
|
+
function seqFirstAccept(parts) {
|
|
1869
|
+
const sets = [];
|
|
1870
|
+
for (const p of parts) {
|
|
1871
|
+
const mandatory = p.part === "lit" ? !p.optional : p.min === 1;
|
|
1872
|
+
sets.push(partFirstAccept(p));
|
|
1873
|
+
if (mandatory) break;
|
|
1874
|
+
}
|
|
1875
|
+
return unionCharSets(sets);
|
|
1876
|
+
}
|
|
1877
|
+
function groupInnerSafe(shape) {
|
|
1878
|
+
if (shape.kind === "chars" || shape.kind === "ident" || shape.kind === "seq" || shape.kind === "litFold") return true;
|
|
1879
|
+
if (shape.kind === "lookahead") return groupInnerSafe(shape.inner);
|
|
1880
|
+
if (shape.kind === "alt") return shape.disjoint;
|
|
1881
|
+
return false;
|
|
1882
|
+
}
|
|
1883
|
+
function shapeFirstAccept(shape) {
|
|
1884
|
+
if (shapeCanBeEmpty(shape)) return "any";
|
|
1885
|
+
switch (shape.kind) {
|
|
1886
|
+
case "chars":
|
|
1887
|
+
return { ranges: shape.ranges, negated: false };
|
|
1888
|
+
case "ident":
|
|
1889
|
+
return { ranges: shape.head, negated: false };
|
|
1890
|
+
case "until":
|
|
1891
|
+
return { ranges: [[shape.open[0], shape.open[0]]], negated: false };
|
|
1892
|
+
case "delimited":
|
|
1893
|
+
return { ranges: [[shape.open[0], shape.open[0]]], negated: false };
|
|
1894
|
+
case "string":
|
|
1895
|
+
return { ranges: [[shape.quote, shape.quote]], negated: false };
|
|
1896
|
+
case "litFold": {
|
|
1897
|
+
const cp = shape.open[0];
|
|
1898
|
+
if (cp >= 65 && cp <= 90) return { ranges: [[cp, cp], [cp + 32, cp + 32]], negated: false };
|
|
1899
|
+
if (cp >= 97 && cp <= 122) return { ranges: [[cp, cp], [cp - 32, cp - 32]], negated: false };
|
|
1900
|
+
return { ranges: [[cp, cp]], negated: false };
|
|
1901
|
+
}
|
|
1902
|
+
case "seq":
|
|
1903
|
+
return seqFirstAccept(shape.parts);
|
|
1904
|
+
case "lookahead":
|
|
1905
|
+
return shapeFirstAccept(shape.inner);
|
|
1906
|
+
// zero-width — doesn't change first-char acceptance
|
|
1907
|
+
case "alt": {
|
|
1908
|
+
if (!shape.disjoint) return "any";
|
|
1909
|
+
const sets = shape.firsts.filter((f) => f !== null);
|
|
1910
|
+
return sets.length === shape.arms.length ? unionCharSets(sets) : "any";
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
function allPairsDisjoint(sets) {
|
|
1915
|
+
for (let i = 0; i < sets.length; i++) {
|
|
1916
|
+
const a = sets[i];
|
|
1917
|
+
if (a === "any") return false;
|
|
1918
|
+
for (let j = i + 1; j < sets.length; j++) {
|
|
1919
|
+
const b = sets[j];
|
|
1920
|
+
if (b === "any" || !classDisjoint(a, b)) return false;
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
return true;
|
|
1924
|
+
}
|
|
1925
|
+
function parseAlternation(source) {
|
|
1926
|
+
const parts = splitTopLevelAlternation(source);
|
|
1927
|
+
if (!parts) return null;
|
|
1928
|
+
const arms = [];
|
|
1929
|
+
for (const p of parts) {
|
|
1930
|
+
const arm = parseScanShape(p);
|
|
1931
|
+
if (!arm) return null;
|
|
1932
|
+
arms.push(arm);
|
|
1933
|
+
}
|
|
1934
|
+
const firstSets = arms.map(shapeFirstAccept);
|
|
1935
|
+
const disjoint = allPairsDisjoint(firstSets);
|
|
1936
|
+
return { kind: "alt", arms, disjoint, firsts: firstSets.map((f) => f === "any" ? null : f) };
|
|
1937
|
+
}
|
|
1494
1938
|
function parseScanShape(source) {
|
|
1939
|
+
const alt = parseAlternation(source);
|
|
1940
|
+
if (alt) return alt;
|
|
1941
|
+
const la = stripTrailingLookahead(source);
|
|
1942
|
+
if (la) {
|
|
1943
|
+
const inner = parseScanShapeCore(la.base);
|
|
1944
|
+
if (!inner) return null;
|
|
1945
|
+
const operand = { ranges: la.ranges, negated: la.classNegated };
|
|
1946
|
+
if (!lookaheadUnambiguous(inner, operand, la.negative)) return null;
|
|
1947
|
+
return { kind: "lookahead", inner, ranges: la.ranges, classNegated: la.classNegated, negative: la.negative };
|
|
1948
|
+
}
|
|
1949
|
+
return parseScanShapeCore(source);
|
|
1950
|
+
}
|
|
1951
|
+
function parseScanShapeCore(source) {
|
|
1495
1952
|
let m = /^\[((?:\\.|[^\]])+)\]([+*])$/.exec(source);
|
|
1496
|
-
if (m) {
|
|
1497
|
-
if (m[1].startsWith("^")) return null;
|
|
1953
|
+
if (m && !m[1].startsWith("^")) {
|
|
1498
1954
|
const ranges = parseClassRanges(m[1]);
|
|
1499
1955
|
return ranges ? { kind: "chars", ranges, minOne: m[2] === "+" } : null;
|
|
1500
1956
|
}
|
|
1501
|
-
m = /^\\([
|
|
1957
|
+
m = /^\\([dws])([+*])$/.exec(source);
|
|
1502
1958
|
if (m) {
|
|
1503
1959
|
return { kind: "chars", ranges: shorthandRanges(m[1]), minOne: m[2] === "+" };
|
|
1504
1960
|
}
|
|
1505
|
-
m = /^(\[(?:\\.|[^\]])+\]|\\[
|
|
1961
|
+
m = /^(\[(?:\\.|[^\]])+\]|\\[dws])(\[(?:\\.|[^\]])+\]|\\[dws])\*$/.exec(source);
|
|
1506
1962
|
if (m) {
|
|
1507
1963
|
const head = classToRanges(m[1]);
|
|
1508
1964
|
const tail = classToRanges(m[2]);
|
|
1509
|
-
|
|
1965
|
+
if (head && tail) return { kind: "ident", head, tail };
|
|
1510
1966
|
}
|
|
1511
1967
|
const str = parseStringShape(source);
|
|
1512
1968
|
if (str) return str;
|
|
@@ -1515,7 +1971,6 @@ function parseScanShape(source) {
|
|
|
1515
1971
|
const open = literalCodePoints(m[1]);
|
|
1516
1972
|
const stop = parseClassRanges(m[2]);
|
|
1517
1973
|
if (open && stop) return { kind: "until", open, stop };
|
|
1518
|
-
return null;
|
|
1519
1974
|
}
|
|
1520
1975
|
if (!source.includes("\\\\")) {
|
|
1521
1976
|
m = /^(.*?)\((?:\?:)?[\s\S]*\)\*(.*?)$/.exec(source);
|
|
@@ -1525,10 +1980,16 @@ function parseScanShape(source) {
|
|
|
1525
1980
|
if (open && close) return { kind: "delimited", open, close };
|
|
1526
1981
|
}
|
|
1527
1982
|
}
|
|
1983
|
+
const parts = parseSeqParts(source);
|
|
1984
|
+
if (parts && seqIsUnambiguous(parts)) return { kind: "seq", parts };
|
|
1528
1985
|
return null;
|
|
1529
1986
|
}
|
|
1530
1987
|
function scanShapeFromRegex(source, flags) {
|
|
1531
|
-
if (/[
|
|
1988
|
+
if (/[msu]/.test(flags)) return null;
|
|
1989
|
+
if (/i/.test(flags)) {
|
|
1990
|
+
const open = literalCodePoints(source);
|
|
1991
|
+
return open ? { kind: "litFold", open } : null;
|
|
1992
|
+
}
|
|
1532
1993
|
return parseScanShape(source);
|
|
1533
1994
|
}
|
|
1534
1995
|
var classCond = (cVar, ranges) => ranges.map(([lo, hi]) => lo === hi ? `${cVar} === ${lo}` : `(${cVar} >= ${lo} && ${cVar} <= ${hi})`).join(" || ");
|
|
@@ -1543,6 +2004,53 @@ function stringHardStop(shape) {
|
|
|
1543
2004
|
}
|
|
1544
2005
|
var codeAt = (start, firstChar) => firstChar ?? `input.charCodeAt(${start})`;
|
|
1545
2006
|
function emitShapeMatch(shape, start, mint, ind2, firstChar) {
|
|
2007
|
+
if (shape.kind === "lookahead") {
|
|
2008
|
+
const inner = emitShapeMatch(shape.inner, start, mint, ind2, firstChar);
|
|
2009
|
+
const okV = mint("_ok");
|
|
2010
|
+
const endV2 = mint("_end");
|
|
2011
|
+
const rawIn = classCond(`input.charCodeAt(${inner.end})`, shape.ranges);
|
|
2012
|
+
const charInClass = shape.classNegated ? `!(${rawIn})` : `(${rawIn})`;
|
|
2013
|
+
const hasMatchingChar = `${inner.end} < input.length && ${charInClass}`;
|
|
2014
|
+
const guardFails = shape.negative ? hasMatchingChar : `!(${hasMatchingChar})`;
|
|
2015
|
+
return {
|
|
2016
|
+
setup: [
|
|
2017
|
+
...inner.setup,
|
|
2018
|
+
`${ind2}let ${okV} = ${inner.ok}`,
|
|
2019
|
+
`${ind2}let ${endV2} = ${inner.end}`,
|
|
2020
|
+
`${ind2}if (${okV} && (${guardFails})) { ${okV} = false; ${endV2} = ${start} }`
|
|
2021
|
+
],
|
|
2022
|
+
ok: okV,
|
|
2023
|
+
end: endV2
|
|
2024
|
+
};
|
|
2025
|
+
}
|
|
2026
|
+
if (shape.kind === "alt") {
|
|
2027
|
+
const okV = mint("_ok");
|
|
2028
|
+
const endV2 = mint("_end");
|
|
2029
|
+
const lines = [`${ind2}let ${okV} = false`, `${ind2}let ${endV2} = ${start}`];
|
|
2030
|
+
if (shape.disjoint) {
|
|
2031
|
+
const c0 = codeAt(start, firstChar);
|
|
2032
|
+
shape.arms.forEach((arm, k) => {
|
|
2033
|
+
const fs = shape.firsts[k];
|
|
2034
|
+
const cond = fs.negated ? `!(${classCond(c0, fs.ranges)})` : `(${classCond(c0, fs.ranges)})`;
|
|
2035
|
+
const m = emitShapeMatch(arm, start, mint, `${ind2} `, firstChar);
|
|
2036
|
+
lines.push(`${ind2}${k === 0 ? "if" : "else if"} (${start} < input.length && ${cond}) {`);
|
|
2037
|
+
lines.push(...m.setup);
|
|
2038
|
+
lines.push(`${ind2} ${okV} = ${m.ok}`);
|
|
2039
|
+
lines.push(`${ind2} ${endV2} = ${m.ok} ? ${m.end} : ${start}`);
|
|
2040
|
+
lines.push(`${ind2}}`);
|
|
2041
|
+
});
|
|
2042
|
+
} else {
|
|
2043
|
+
const lbl = mint("_alt");
|
|
2044
|
+
lines.push(`${ind2}${lbl}: {`);
|
|
2045
|
+
for (const arm of shape.arms) {
|
|
2046
|
+
const m = emitShapeMatch(arm, start, mint, `${ind2} `, firstChar);
|
|
2047
|
+
lines.push(...m.setup);
|
|
2048
|
+
lines.push(`${ind2} if (${m.ok}) { ${okV} = true; ${endV2} = ${m.end}; break ${lbl} }`);
|
|
2049
|
+
}
|
|
2050
|
+
lines.push(`${ind2}}`);
|
|
2051
|
+
}
|
|
2052
|
+
return { setup: lines, ok: okV, end: endV2 };
|
|
2053
|
+
}
|
|
1546
2054
|
if (shape.kind === "chars") {
|
|
1547
2055
|
const cur = mint("_e");
|
|
1548
2056
|
return {
|
|
@@ -1569,6 +2077,82 @@ function emitShapeMatch(shape, start, mint, ind2, firstChar) {
|
|
|
1569
2077
|
end: cur
|
|
1570
2078
|
};
|
|
1571
2079
|
}
|
|
2080
|
+
if (shape.kind === "seq") {
|
|
2081
|
+
const endV2 = mint("_e");
|
|
2082
|
+
const okV = mint("_ok");
|
|
2083
|
+
const runCond = (p, at) => {
|
|
2084
|
+
const c = classCond(`input.charCodeAt(${at})`, p.ranges);
|
|
2085
|
+
return p.negated ? `!(${c})` : `(${c})`;
|
|
2086
|
+
};
|
|
2087
|
+
const lines = [`${ind2}let ${endV2} = ${start}`, `${ind2}let ${okV} = false`, `${ind2}do {`];
|
|
2088
|
+
let first = true;
|
|
2089
|
+
for (const p of shape.parts) {
|
|
2090
|
+
if (p.part === "lit") {
|
|
2091
|
+
const L = p.cps.length;
|
|
2092
|
+
const cond = litCond(endV2, p.cps, first ? firstChar : void 0);
|
|
2093
|
+
if (p.optional) {
|
|
2094
|
+
lines.push(`${ind2} if (${endV2} + ${L} <= input.length && (${cond})) ${endV2} += ${L}`);
|
|
2095
|
+
} else {
|
|
2096
|
+
lines.push(`${ind2} if (!(${endV2} + ${L} <= input.length && (${cond}))) break`);
|
|
2097
|
+
lines.push(`${ind2} ${endV2} += ${L}`);
|
|
2098
|
+
}
|
|
2099
|
+
} else if (p.part === "run" && !p.unbounded) {
|
|
2100
|
+
if (p.min === 1) {
|
|
2101
|
+
lines.push(`${ind2} if (!(${endV2} < input.length && ${runCond(p, endV2)})) break`);
|
|
2102
|
+
lines.push(`${ind2} ${endV2}++`);
|
|
2103
|
+
} else {
|
|
2104
|
+
lines.push(`${ind2} if (${endV2} < input.length && ${runCond(p, endV2)}) ${endV2}++`);
|
|
2105
|
+
}
|
|
2106
|
+
} else if (p.part === "run") {
|
|
2107
|
+
const s = mint("_s");
|
|
2108
|
+
lines.push(`${ind2} const ${s} = ${endV2}`);
|
|
2109
|
+
lines.push(`${ind2} while (${endV2} < input.length && ${runCond(p, endV2)}) ${endV2}++`);
|
|
2110
|
+
if (p.min === 1) lines.push(`${ind2} if (${endV2} === ${s}) break`);
|
|
2111
|
+
} else {
|
|
2112
|
+
const inner = emitShapeMatch(p.inner, endV2, mint, `${ind2} `, first ? firstChar : void 0);
|
|
2113
|
+
if (!p.unbounded) {
|
|
2114
|
+
lines.push(...inner.setup);
|
|
2115
|
+
if (p.min === 1) {
|
|
2116
|
+
lines.push(`${ind2} if (!(${inner.ok})) break`);
|
|
2117
|
+
lines.push(`${ind2} ${endV2} = ${inner.end}`);
|
|
2118
|
+
} else {
|
|
2119
|
+
lines.push(`${ind2} if (${inner.ok}) ${endV2} = ${inner.end}`);
|
|
2120
|
+
}
|
|
2121
|
+
} else {
|
|
2122
|
+
const progV = mint("_prog");
|
|
2123
|
+
lines.push(`${ind2} let ${progV} = false`);
|
|
2124
|
+
lines.push(`${ind2} while (true) {`);
|
|
2125
|
+
lines.push(...inner.setup);
|
|
2126
|
+
lines.push(`${ind2} if (!(${inner.ok})) break`);
|
|
2127
|
+
lines.push(`${ind2} ${endV2} = ${inner.end}`);
|
|
2128
|
+
lines.push(`${ind2} ${progV} = true`);
|
|
2129
|
+
lines.push(`${ind2} }`);
|
|
2130
|
+
if (p.min === 1) lines.push(`${ind2} if (!${progV}) break`);
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
first = false;
|
|
2134
|
+
}
|
|
2135
|
+
lines.push(`${ind2} ${okV} = true`);
|
|
2136
|
+
lines.push(`${ind2}} while (false)`);
|
|
2137
|
+
lines.push(`${ind2}if (!${okV}) ${endV2} = ${start}`);
|
|
2138
|
+
return { setup: lines, ok: okV, end: endV2 };
|
|
2139
|
+
}
|
|
2140
|
+
if (shape.kind === "litFold") {
|
|
2141
|
+
const openLen2 = shape.open.length;
|
|
2142
|
+
const endV2 = mint("_end");
|
|
2143
|
+
const checks = shape.open.map((cp, k) => {
|
|
2144
|
+
const cVar = k === 0 && firstChar ? firstChar : `input.charCodeAt(${start} + ${k})`;
|
|
2145
|
+
return foldEq(cVar, cp);
|
|
2146
|
+
});
|
|
2147
|
+
return {
|
|
2148
|
+
setup: [
|
|
2149
|
+
`${ind2}let ${endV2} = ${start}`,
|
|
2150
|
+
`${ind2}if (${start} + ${openLen2} <= input.length && (${checks.join(" && ")})) ${endV2} = ${start} + ${openLen2}`
|
|
2151
|
+
],
|
|
2152
|
+
ok: `${endV2} > ${start}`,
|
|
2153
|
+
end: endV2
|
|
2154
|
+
};
|
|
2155
|
+
}
|
|
1572
2156
|
if (shape.kind === "until") {
|
|
1573
2157
|
const j2 = mint("_j");
|
|
1574
2158
|
const openLen2 = shape.open.length;
|
|
@@ -1964,7 +2548,7 @@ function hoistExpected(ctx, constArrSource) {
|
|
|
1964
2548
|
let name = ctx.expectedMap.get(constArrSource);
|
|
1965
2549
|
if (name === void 0) {
|
|
1966
2550
|
name = `_fx${ctx.expectedDecls.length}`;
|
|
1967
|
-
ctx.expectedDecls.push(`const ${name} =
|
|
2551
|
+
ctx.expectedDecls.push(`const ${name} = ${constArrSource}`);
|
|
1968
2552
|
ctx.expectedMap.set(constArrSource, name);
|
|
1969
2553
|
}
|
|
1970
2554
|
return name;
|
|
@@ -2286,18 +2870,21 @@ function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
2286
2870
|
return true;
|
|
2287
2871
|
}
|
|
2288
2872
|
}
|
|
2289
|
-
function emitFallible(inner, ctx, pos) {
|
|
2873
|
+
function emitFallible(inner, ctx, pos, swallow = false) {
|
|
2290
2874
|
const lbl = v(ctx, "_lbl");
|
|
2291
2875
|
const okV = `${lbl}ok`;
|
|
2292
2876
|
const valV = `${lbl}v`;
|
|
2293
2877
|
const endV = `${lbl}e`;
|
|
2294
2878
|
const savedLabel = ctx.failLabel;
|
|
2295
2879
|
const savedIndent = ctx.indent;
|
|
2880
|
+
const savedRecord = ctx.recordFail;
|
|
2296
2881
|
ctx.failLabel = lbl;
|
|
2297
2882
|
ctx.indent = savedIndent + 1;
|
|
2883
|
+
if (swallow) ctx.recordFail = false;
|
|
2298
2884
|
const r = emit(inner, ctx, pos);
|
|
2299
2885
|
ctx.failLabel = savedLabel;
|
|
2300
2886
|
ctx.indent = savedIndent;
|
|
2887
|
+
ctx.recordFail = savedRecord;
|
|
2301
2888
|
const ind0 = ind(ctx);
|
|
2302
2889
|
const needsRollback = ctx.capturing && mayLeavePartialCapture(inner);
|
|
2303
2890
|
const mL = needsRollback ? v(ctx, "_fcl") : null;
|
|
@@ -2320,6 +2907,7 @@ function emitFallible(inner, ctx, pos) {
|
|
|
2320
2907
|
];
|
|
2321
2908
|
return { stmts, okVar: okV, valVar: valV, endVar: endV };
|
|
2322
2909
|
}
|
|
2910
|
+
var CHARCODE_CHAIN_MAX = 16;
|
|
2323
2911
|
function emitLit(def, ctx, pos) {
|
|
2324
2912
|
const { value, caseInsensitive } = def;
|
|
2325
2913
|
const len = value.length;
|
|
@@ -2342,7 +2930,7 @@ function emitLit(def, ctx, pos) {
|
|
|
2342
2930
|
...emitIfFail(ctx, `${pos} >= input.length || input.charCodeAt(${pos}) !== ${code}`, failBody(ctx, expectedStr, pos)),
|
|
2343
2931
|
`${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
|
|
2344
2932
|
);
|
|
2345
|
-
} else if (len <=
|
|
2933
|
+
} else if (len <= CHARCODE_CHAIN_MAX) {
|
|
2346
2934
|
const checks = Array.from(
|
|
2347
2935
|
{ length: len },
|
|
2348
2936
|
(_, i) => `input.charCodeAt(${pos}${i > 0 ? ` + ${i}` : ""}) !== ${value.codePointAt(i)}`
|
|
@@ -2364,7 +2952,55 @@ function emitLit(def, ctx, pos) {
|
|
|
2364
2952
|
function escapeKeywordRe(s) {
|
|
2365
2953
|
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2366
2954
|
}
|
|
2955
|
+
function emitKeywordsFast(def, ctx, pos) {
|
|
2956
|
+
if (def.words.length === 0 || def.words.some((w) => w.length === 0)) return null;
|
|
2957
|
+
if (def.words.some((w) => Array.from(w).length !== w.length)) return null;
|
|
2958
|
+
if (def.caseInsensitive && def.boundary) return null;
|
|
2959
|
+
let boundary = null;
|
|
2960
|
+
if (def.boundary) {
|
|
2961
|
+
let body = def.boundary;
|
|
2962
|
+
const negated = body.startsWith("^");
|
|
2963
|
+
if (negated) body = body.slice(1);
|
|
2964
|
+
const ranges = parseClassRanges(body);
|
|
2965
|
+
if (!ranges) return null;
|
|
2966
|
+
boundary = { ranges, negated };
|
|
2967
|
+
}
|
|
2968
|
+
const mint = (prefix = "_v") => v(ctx, prefix);
|
|
2969
|
+
const lbl = v(ctx, "_kwLbl");
|
|
2970
|
+
const valV = v(ctx, "_kwv");
|
|
2971
|
+
const endV = v(ctx, "_kwe");
|
|
2972
|
+
const bodyInd = ind(ctx) + " ";
|
|
2973
|
+
const tries = [];
|
|
2974
|
+
for (const w of def.words) {
|
|
2975
|
+
const cps = Array.from(w, (ch) => ch.codePointAt(0));
|
|
2976
|
+
let shape = def.caseInsensitive ? { kind: "litFold", open: cps } : { kind: "seq", parts: [{ part: "lit", cps, optional: false }] };
|
|
2977
|
+
if (boundary) {
|
|
2978
|
+
shape = { kind: "lookahead", inner: shape, ranges: boundary.ranges, classNegated: boundary.negated, negative: true };
|
|
2979
|
+
}
|
|
2980
|
+
const m = emitShapeMatch(shape, pos, mint, bodyInd);
|
|
2981
|
+
tries.push(
|
|
2982
|
+
...m.setup,
|
|
2983
|
+
// Slice from input rather than reusing the literal word: `caseInsensitive`
|
|
2984
|
+
// must return the text as it actually appeared (e.g. "ABC" for keyword
|
|
2985
|
+
// "abc"), matching what the original `RegExp.exec()[0]` returned.
|
|
2986
|
+
`${bodyInd}if (${m.ok}) { ${valV} = input.slice(${pos}, ${m.end}); ${endV} = ${m.end}; break ${lbl} }`
|
|
2987
|
+
);
|
|
2988
|
+
}
|
|
2989
|
+
const stmts = [
|
|
2990
|
+
`${ind(ctx)}let ${valV} = '', ${endV} = ${pos}`,
|
|
2991
|
+
`${ind(ctx)}${lbl}: {`,
|
|
2992
|
+
...tries,
|
|
2993
|
+
`${ind(ctx)}}`,
|
|
2994
|
+
// Every word has length >= 1 (checked above), so a real match always
|
|
2995
|
+
// advances past `pos` — `endV === pos` only happens when no candidate matched.
|
|
2996
|
+
...emitIfFail(ctx, `${endV} === ${pos}`, failBody(ctx, '"keyword"', pos))
|
|
2997
|
+
];
|
|
2998
|
+
stmts.push(...emitLeafCapture(ctx, valV, pos, endV));
|
|
2999
|
+
return { stmts, valueVar: valV, endVar: endV };
|
|
3000
|
+
}
|
|
2367
3001
|
function emitKeywords(def, ctx, pos) {
|
|
3002
|
+
const fast = emitKeywordsFast(def, ctx, pos);
|
|
3003
|
+
if (fast) return fast;
|
|
2368
3004
|
const alt = def.words.map(escapeKeywordRe).join("|");
|
|
2369
3005
|
const boundary = def.boundary ? `(?![${def.boundary}])` : "";
|
|
2370
3006
|
const flags = def.caseInsensitive ? "iuy" : "uy";
|
|
@@ -2495,6 +3131,31 @@ function failsAtStart(p) {
|
|
|
2495
3131
|
return false;
|
|
2496
3132
|
}
|
|
2497
3133
|
}
|
|
3134
|
+
function armStaticExpected(ctx, p) {
|
|
3135
|
+
return hoistExpected(ctx, staticExpectedArr([p]));
|
|
3136
|
+
}
|
|
3137
|
+
function canMatchEmptyAtStart(p) {
|
|
3138
|
+
const d = p._def;
|
|
3139
|
+
switch (d.tag) {
|
|
3140
|
+
case "regex":
|
|
3141
|
+
return /(?:[*?]|\{0,|\{\d*,)/.test(d.source);
|
|
3142
|
+
case "optional":
|
|
3143
|
+
return true;
|
|
3144
|
+
case "many":
|
|
3145
|
+
return true;
|
|
3146
|
+
case "transform":
|
|
3147
|
+
case "label":
|
|
3148
|
+
return canMatchEmptyAtStart(d.parser);
|
|
3149
|
+
case "literal":
|
|
3150
|
+
return d.value.length === 0;
|
|
3151
|
+
default:
|
|
3152
|
+
return false;
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
function needsFirstSetGuard(p) {
|
|
3156
|
+
const fs = p._meta.firstSet;
|
|
3157
|
+
return fs.kind !== "any" && !canMatchEmptyAtStart(p);
|
|
3158
|
+
}
|
|
2498
3159
|
function emitDisjointArm(p, ctx, pos, valV, endV) {
|
|
2499
3160
|
if (failsAtStart(p)) {
|
|
2500
3161
|
const r = emit(p, ctx, pos);
|
|
@@ -2636,16 +3297,21 @@ function emitFirstMatch(def, ctx, pos) {
|
|
|
2636
3297
|
const resValV = v(ctx, "_crv");
|
|
2637
3298
|
const resEndV = v(ctx, "_cre");
|
|
2638
3299
|
const resOkV = v(ctx, "_crok");
|
|
3300
|
+
const codeV = v(ctx, "_chcode");
|
|
2639
3301
|
const slots = def.parsers.map(() => v(ctx, "_cfx"));
|
|
2640
3302
|
const ind0 = ind(ctx);
|
|
2641
3303
|
const stmts = [
|
|
2642
3304
|
`${ind0}let ${resValV}, ${resEndV} = ${pos}, ${resOkV} = false`,
|
|
2643
|
-
`${ind0}let ${slots.join(", ")}
|
|
3305
|
+
`${ind0}let ${slots.join(", ")}`,
|
|
3306
|
+
`${ind0}const ${codeV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`
|
|
2644
3307
|
];
|
|
2645
3308
|
for (let i = 0; i < def.parsers.length; i++) {
|
|
2646
3309
|
const p = def.parsers[i];
|
|
2647
3310
|
const gate = def.gates[i];
|
|
2648
3311
|
const autoNot = def.autoNot[i];
|
|
3312
|
+
const atStart = failsAtStart(p);
|
|
3313
|
+
const staticFx = armStaticExpected(ctx, p);
|
|
3314
|
+
const fsGuard = needsFirstSetGuard(p) ? firstSetCond(codeV, p._meta.firstSet) : null;
|
|
2649
3315
|
let gateCond = null;
|
|
2650
3316
|
if (gate) {
|
|
2651
3317
|
const gateIdx = ctx.mapFns.length;
|
|
@@ -2660,39 +3326,41 @@ function emitFirstMatch(def, ctx, pos) {
|
|
|
2660
3326
|
const markTl = armNeedsRollback ? v(ctx, "_cmtl") : null;
|
|
2661
3327
|
const markLog = armNeedsRollback ? v(ctx, "_cmlg") : null;
|
|
2662
3328
|
const rollback = markLeaves ? captureRestoreBody(markLeaves, markRaw, markTl, markLog) : "";
|
|
3329
|
+
const failSlot = atStart ? staticFx : "_ctx._fx";
|
|
2663
3330
|
stmts.push(`${ind0}if (${skipCond}) {`);
|
|
2664
|
-
ctx
|
|
2665
|
-
|
|
3331
|
+
if (fsGuard) stmts.push(`${ind(ctx)}if (${fsGuard}) {`);
|
|
3332
|
+
ctx.indent += fsGuard ? 2 : 1;
|
|
2666
3333
|
if (markLeaves) {
|
|
2667
3334
|
stmts.push(
|
|
2668
|
-
`${
|
|
2669
|
-
`${
|
|
2670
|
-
`${
|
|
2671
|
-
`${
|
|
3335
|
+
`${ind(ctx)}const ${markLeaves} = _ctx._cstLeaves?.length ?? 0`,
|
|
3336
|
+
`${ind(ctx)}const ${markRaw} = _ctx._cstRawChildren?.length ?? 0`,
|
|
3337
|
+
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
3338
|
+
`${ind(ctx)}const ${markLog} = _ctx._triviaLog?.length ?? 0`
|
|
2672
3339
|
);
|
|
2673
3340
|
}
|
|
2674
|
-
const { stmts: armStmts, okVar, valVar, endVar } = emitFallible(p, ctx, pos);
|
|
3341
|
+
const { stmts: armStmts, okVar, valVar, endVar } = emitFallible(p, ctx, pos, atStart);
|
|
2675
3342
|
stmts.push(...armStmts);
|
|
2676
|
-
ctx.indent--;
|
|
2677
3343
|
if (autoNot && autoNot.length > 0) {
|
|
2678
3344
|
const anCode = v(ctx, "_anc");
|
|
2679
3345
|
const rejectCond = autoNot.map(
|
|
2680
3346
|
(check) => check.kind === "firstSet" ? firstSetCond(anCode, check.set) : `input.startsWith(${JSON.stringify(check.value)}, ${endVar})`
|
|
2681
3347
|
).join(" || ");
|
|
2682
|
-
stmts.push(`${
|
|
2683
|
-
stmts.push(`${
|
|
2684
|
-
stmts.push(`${
|
|
2685
|
-
stmts.push(`${
|
|
2686
|
-
stmts.push(`${
|
|
2687
|
-
stmts.push(`${
|
|
2688
|
-
stmts.push(`${
|
|
2689
|
-
stmts.push(`${
|
|
2690
|
-
stmts.push(`${
|
|
2691
|
-
if (rollback) stmts.push(`${
|
|
3348
|
+
stmts.push(`${ind(ctx)}if (${okVar}) {`);
|
|
3349
|
+
stmts.push(`${ind(ctx)} const ${anCode} = ${endVar} < input.length ? input.charCodeAt(${endVar}) : -1`);
|
|
3350
|
+
stmts.push(`${ind(ctx)} if (!(${rejectCond})) {`);
|
|
3351
|
+
stmts.push(`${ind(ctx)} ${resValV} = ${valVar}`);
|
|
3352
|
+
stmts.push(`${ind(ctx)} ${resEndV} = ${endVar}`);
|
|
3353
|
+
stmts.push(`${ind(ctx)} ${resOkV} = true`);
|
|
3354
|
+
stmts.push(`${ind(ctx)} }`);
|
|
3355
|
+
stmts.push(`${ind(ctx)}}`);
|
|
3356
|
+
stmts.push(`${ind(ctx)}else { ${slots[i]} = ${failSlot} }`);
|
|
3357
|
+
if (rollback) stmts.push(`${ind(ctx)}if (!${resOkV}) { ${rollback} }`);
|
|
2692
3358
|
} else {
|
|
2693
|
-
stmts.push(`${
|
|
2694
|
-
stmts.push(`${
|
|
3359
|
+
stmts.push(`${ind(ctx)}if (${okVar}) { ${resValV} = ${valVar}; ${resEndV} = ${endVar}; ${resOkV} = true }`);
|
|
3360
|
+
stmts.push(`${ind(ctx)}else { ${slots[i]} = ${failSlot}${rollback ? `; ${rollback}` : ""} }`);
|
|
2695
3361
|
}
|
|
3362
|
+
ctx.indent -= fsGuard ? 2 : 1;
|
|
3363
|
+
if (fsGuard) stmts.push(`${ind(ctx)}} else { ${slots[i]} = ${staticFx} }`);
|
|
2696
3364
|
stmts.push(`${ind0}}`);
|
|
2697
3365
|
}
|
|
2698
3366
|
const concatExpr = `[${slots.map((s) => `...(${s} || [])`).join(", ")}]`;
|
|
@@ -2725,7 +3393,7 @@ function emitTransformChain(p, baseValue, endV, startPos, ctx) {
|
|
|
2725
3393
|
function emitLiteralCondition(litVal, pos) {
|
|
2726
3394
|
const len = litVal.length;
|
|
2727
3395
|
if (len === 0) return "true";
|
|
2728
|
-
if (len >
|
|
3396
|
+
if (len > CHARCODE_CHAIN_MAX) return `input.startsWith(${JSON.stringify(litVal)}, ${pos})`;
|
|
2729
3397
|
const checks = [`${pos} + ${len} <= input.length`];
|
|
2730
3398
|
for (let i = 0; i < len; i++) {
|
|
2731
3399
|
const code = litVal.codePointAt(i);
|
|
@@ -2774,7 +3442,7 @@ function emitMany(def, ctx, pos) {
|
|
|
2774
3442
|
itemPos = npV;
|
|
2775
3443
|
}
|
|
2776
3444
|
}
|
|
2777
|
-
const { stmts: iterStmts, okVar: iterOk, valVar: iterVal, endVar: iterEnd } = emitFallible(def.parser, ctx, itemPos);
|
|
3445
|
+
const { stmts: iterStmts, okVar: iterOk, valVar: iterVal, endVar: iterEnd } = emitFallible(def.parser, ctx, itemPos, true);
|
|
2778
3446
|
stmts.push(
|
|
2779
3447
|
...iterStmts,
|
|
2780
3448
|
`${ind(ctx)}if (!${iterOk} || ${iterEnd} <= ${itemPos}) { ${rollback}break }`,
|
|
@@ -2788,7 +3456,7 @@ function emitMany(def, ctx, pos) {
|
|
|
2788
3456
|
function emitOptional(def, ctx, pos) {
|
|
2789
3457
|
const valV = v(ctx, "_opt");
|
|
2790
3458
|
const endV = v(ctx, "_opte");
|
|
2791
|
-
const { stmts: lblStmts, okVar, valVar, endVar } = emitFallible(def.parser, ctx, pos);
|
|
3459
|
+
const { stmts: lblStmts, okVar, valVar, endVar } = emitFallible(def.parser, ctx, pos, true);
|
|
2792
3460
|
const ind0 = ind(ctx);
|
|
2793
3461
|
const stmts = [
|
|
2794
3462
|
...lblStmts,
|
|
@@ -2800,7 +3468,7 @@ function emitOptional(def, ctx, pos) {
|
|
|
2800
3468
|
function emitSepBy(_p, def, ctx, pos) {
|
|
2801
3469
|
const arrV = v(ctx, "_arr");
|
|
2802
3470
|
const curV = v(ctx, "_cur");
|
|
2803
|
-
const { stmts: firstStmts, okVar: firstOk, valVar: firstVal, endVar: firstEnd } = emitFallible(def.parser, ctx, pos);
|
|
3471
|
+
const { stmts: firstStmts, okVar: firstOk, valVar: firstVal, endVar: firstEnd } = emitFallible(def.parser, ctx, pos, true);
|
|
2804
3472
|
const stmts = [
|
|
2805
3473
|
`${ind(ctx)}const ${arrV} = []`,
|
|
2806
3474
|
`${ind(ctx)}let ${curV} = ${pos}`,
|
|
@@ -2832,11 +3500,11 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
2832
3500
|
);
|
|
2833
3501
|
sepAtPos = spV;
|
|
2834
3502
|
const rollbackToSep = `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${markLog}; `;
|
|
2835
|
-
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos);
|
|
3503
|
+
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
2836
3504
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}break }`);
|
|
2837
3505
|
const npV = v(ctx, "_np");
|
|
2838
3506
|
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`);
|
|
2839
|
-
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, npV);
|
|
3507
|
+
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, npV, true);
|
|
2840
3508
|
stmts.push(
|
|
2841
3509
|
...nextStmts,
|
|
2842
3510
|
// item failed → unwind the separator too, back to the end of the last item
|
|
@@ -2849,11 +3517,11 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
2849
3517
|
const spV = v(ctx, "_sp");
|
|
2850
3518
|
stmts.push(`${ind(ctx)}const ${spV} = ${trivFn}(input, ${curV}, _ctx)`);
|
|
2851
3519
|
sepAtPos = spV;
|
|
2852
|
-
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos);
|
|
3520
|
+
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
2853
3521
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) break`);
|
|
2854
3522
|
const npV = v(ctx, "_np");
|
|
2855
3523
|
stmts.push(`${ind(ctx)}const ${npV} = ${trivFn}(input, ${sepEnd}, _ctx)`);
|
|
2856
|
-
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, npV);
|
|
3524
|
+
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, npV, true);
|
|
2857
3525
|
stmts.push(
|
|
2858
3526
|
...nextStmts,
|
|
2859
3527
|
`${ind(ctx)}if (!${nextOk}) break`,
|
|
@@ -2870,10 +3538,10 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
2870
3538
|
`${ind(ctx)}const ${markRw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`
|
|
2871
3539
|
);
|
|
2872
3540
|
}
|
|
2873
|
-
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos);
|
|
3541
|
+
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos, true);
|
|
2874
3542
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) break`);
|
|
2875
3543
|
const nextRb = markLv ? `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${markRw}; ` : "";
|
|
2876
|
-
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, sepEnd);
|
|
3544
|
+
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, sepEnd, true);
|
|
2877
3545
|
stmts.push(
|
|
2878
3546
|
...nextStmts,
|
|
2879
3547
|
`${ind(ctx)}if (!${nextOk}) { ${nextRb}break }`,
|
|
@@ -2931,7 +3599,7 @@ function emitScanTo(def, ctx, pos) {
|
|
|
2931
3599
|
return { stmts, valueVar: valV, endVar: curV };
|
|
2932
3600
|
}
|
|
2933
3601
|
function emitNot(def, ctx, pos) {
|
|
2934
|
-
const { stmts, okVar } = emitFallible(def.parser, ctx, pos);
|
|
3602
|
+
const { stmts, okVar } = emitFallible(def.parser, ctx, pos, true);
|
|
2935
3603
|
const label2 = JSON.stringify(`not(${def.parser._tag})`);
|
|
2936
3604
|
return {
|
|
2937
3605
|
stmts: [
|
|
@@ -3022,11 +3690,14 @@ function emitLazy(p, def, ctx, pos) {
|
|
|
3022
3690
|
}
|
|
3023
3691
|
const savedIndent = ctx.indent;
|
|
3024
3692
|
const savedFailLabel = ctx.failLabel;
|
|
3693
|
+
const savedRecord = ctx.recordFail;
|
|
3025
3694
|
ctx.indent = 1;
|
|
3026
3695
|
ctx.failLabel = "_pfail";
|
|
3696
|
+
ctx.recordFail = true;
|
|
3027
3697
|
const r = emit(resolved, ctx, "_pos");
|
|
3028
3698
|
ctx.indent = savedIndent;
|
|
3029
3699
|
ctx.failLabel = savedFailLabel;
|
|
3700
|
+
ctx.recordFail = savedRecord;
|
|
3030
3701
|
pushNamedFnDecl(ctx, fnName2, r.stmts, r.valueVar, r.endVar);
|
|
3031
3702
|
}
|
|
3032
3703
|
const fnName = ctx.namedParsers.get(p);
|
|
@@ -3206,11 +3877,14 @@ function emit(p, ctx, pos) {
|
|
|
3206
3877
|
ctx.namedParsers.set(innerParser, fnName);
|
|
3207
3878
|
const savedIndent = ctx.indent;
|
|
3208
3879
|
const savedFailLabel = ctx.failLabel;
|
|
3880
|
+
const savedRecord = ctx.recordFail;
|
|
3209
3881
|
ctx.indent = 1;
|
|
3210
3882
|
ctx.failLabel = "_pfail";
|
|
3883
|
+
ctx.recordFail = true;
|
|
3211
3884
|
const innerR = emit(innerParser, ctx, "_pos");
|
|
3212
3885
|
ctx.indent = savedIndent;
|
|
3213
3886
|
ctx.failLabel = savedFailLabel;
|
|
3887
|
+
ctx.recordFail = savedRecord;
|
|
3214
3888
|
pushNamedFnDecl(ctx, fnName, innerR.stmts, innerR.valueVar, innerR.endVar);
|
|
3215
3889
|
}
|
|
3216
3890
|
const fn = ctx.namedParsers.get(innerParser);
|
|
@@ -3358,6 +4032,7 @@ function compile(combinator, mapFnSources) {
|
|
|
3358
4032
|
regexMap: /* @__PURE__ */ new Map(),
|
|
3359
4033
|
expectedDecls: [],
|
|
3360
4034
|
expectedMap: /* @__PURE__ */ new Map(),
|
|
4035
|
+
recordFail: true,
|
|
3361
4036
|
mapFns: [],
|
|
3362
4037
|
mapFnSrcs: [],
|
|
3363
4038
|
buildFns: [],
|
|
@@ -3727,7 +4402,7 @@ function graftAndShift(root, path, newNode, delta) {
|
|
|
3727
4402
|
children: newChildren
|
|
3728
4403
|
};
|
|
3729
4404
|
}
|
|
3730
|
-
var
|
|
4405
|
+
var ParseDocImpl = class _ParseDocImpl {
|
|
3731
4406
|
_registry;
|
|
3732
4407
|
_rootRule;
|
|
3733
4408
|
_opts;
|
|
@@ -3744,7 +4419,7 @@ var FunctionalDocImpl = class _FunctionalDocImpl {
|
|
|
3744
4419
|
}
|
|
3745
4420
|
edit(from, to, replacement) {
|
|
3746
4421
|
const newInput = this.input.slice(0, from) + replacement + this.input.slice(to);
|
|
3747
|
-
const reparse = () =>
|
|
4422
|
+
const reparse = () => parseDoc(this._registry, this._rootRule, newInput, this._opts);
|
|
3748
4423
|
if (!this.tree) return reparse();
|
|
3749
4424
|
const delta = replacement.length - (to - from);
|
|
3750
4425
|
const found = findContaining(this.tree, from);
|
|
@@ -3766,25 +4441,25 @@ var FunctionalDocImpl = class _FunctionalDocImpl {
|
|
|
3766
4441
|
if (r.span.end === node2.span.end + delta) {
|
|
3767
4442
|
if (delta === 0) {
|
|
3768
4443
|
const newTree2 = replaceAtPath(rebuild, this.tree, path, r.value);
|
|
3769
|
-
return new
|
|
4444
|
+
return new _ParseDocImpl(this._registry, this._rootRule, this._opts, newTree2, [], newInput);
|
|
3770
4445
|
}
|
|
3771
4446
|
if (this._opts.rebuild) return reparse();
|
|
3772
4447
|
const newTree = graftAndShift(this.tree, path, r.value, delta);
|
|
3773
|
-
return new
|
|
4448
|
+
return new _ParseDocImpl(this._registry, this._rootRule, this._opts, newTree, [], newInput);
|
|
3774
4449
|
}
|
|
3775
4450
|
}
|
|
3776
4451
|
return reparse();
|
|
3777
4452
|
}
|
|
3778
4453
|
};
|
|
3779
|
-
function
|
|
4454
|
+
function parseDoc(registry, rootRule, input, opts = {}) {
|
|
3780
4455
|
const ruleFn = registry[rootRule];
|
|
3781
4456
|
if (!ruleFn) throw new Error(`No rule '${rootRule}' in registry`);
|
|
3782
4457
|
const ctx = { trackLines: false, state: opts.state };
|
|
3783
4458
|
const r = ruleFn(input, 0, ctx);
|
|
3784
4459
|
if (r.ok) {
|
|
3785
|
-
return new
|
|
4460
|
+
return new ParseDocImpl(registry, rootRule, opts, r.value, [], input);
|
|
3786
4461
|
}
|
|
3787
|
-
return new
|
|
4462
|
+
return new ParseDocImpl(registry, rootRule, opts, null, [{ ok: false, expected: r.expected, span: r.span }], input);
|
|
3788
4463
|
}
|
|
3789
4464
|
|
|
3790
4465
|
// src/cst/trivia-index.ts
|
|
@@ -3936,7 +4611,6 @@ export {
|
|
|
3936
4611
|
keywords,
|
|
3937
4612
|
label,
|
|
3938
4613
|
literal,
|
|
3939
|
-
makeFunctionalDoc,
|
|
3940
4614
|
makeWord,
|
|
3941
4615
|
many,
|
|
3942
4616
|
manyRecover,
|
|
@@ -3947,6 +4621,7 @@ export {
|
|
|
3947
4621
|
oneOrMore,
|
|
3948
4622
|
optional,
|
|
3949
4623
|
parse,
|
|
4624
|
+
parseDoc,
|
|
3950
4625
|
parser,
|
|
3951
4626
|
recover,
|
|
3952
4627
|
ref,
|