parseman 0.6.1 → 0.7.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/README.md +27 -3
- package/dist/combinators/grammar.d.ts +30 -1
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/repeat.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +9 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/index.cjs +145 -71
- package/dist/index.cjs.map +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +145 -71
- package/dist/index.js.map +2 -2
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +149 -73
- package/dist/plugin/index.cjs.map +2 -2
- package/dist/plugin/index.js +149 -73
- package/dist/plugin/index.js.map +2 -2
- package/dist/types.d.ts +3 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/plugin/index.js
CHANGED
|
@@ -1014,8 +1014,10 @@ function optional(combinator) {
|
|
|
1014
1014
|
_meta: meta,
|
|
1015
1015
|
_def: { tag: "optional", parser: combinator },
|
|
1016
1016
|
parse(input, pos, ctx) {
|
|
1017
|
+
const mark = saveTriviaMark(ctx);
|
|
1017
1018
|
const result = combinator.parse(input, pos, ctx);
|
|
1018
1019
|
if (result.ok) return result;
|
|
1020
|
+
rollbackTrivia(ctx, mark);
|
|
1019
1021
|
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1020
1022
|
}
|
|
1021
1023
|
};
|
|
@@ -1036,7 +1038,7 @@ function sepBy(combinator, separator) {
|
|
|
1036
1038
|
const values = [first.value];
|
|
1037
1039
|
let cur = first.span.end;
|
|
1038
1040
|
while (cur < input.length) {
|
|
1039
|
-
|
|
1041
|
+
const loopMark = saveTriviaMark(ctx);
|
|
1040
1042
|
let sepPos = cur;
|
|
1041
1043
|
if (ctx.trivia) {
|
|
1042
1044
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -1049,10 +1051,9 @@ function sepBy(combinator, separator) {
|
|
|
1049
1051
|
}
|
|
1050
1052
|
const sep = separator.parse(input, sepPos, ctx);
|
|
1051
1053
|
if (!sep.ok) {
|
|
1052
|
-
rollbackTrivia(ctx,
|
|
1054
|
+
rollbackTrivia(ctx, loopMark);
|
|
1053
1055
|
break;
|
|
1054
1056
|
}
|
|
1055
|
-
mark = saveTriviaMark(ctx);
|
|
1056
1057
|
let nextPos = sep.span.end;
|
|
1057
1058
|
if (ctx.trivia) {
|
|
1058
1059
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -1065,7 +1066,7 @@ function sepBy(combinator, separator) {
|
|
|
1065
1066
|
}
|
|
1066
1067
|
const next = combinator.parse(input, nextPos, ctx);
|
|
1067
1068
|
if (!next.ok) {
|
|
1068
|
-
rollbackTrivia(ctx,
|
|
1069
|
+
rollbackTrivia(ctx, loopMark);
|
|
1069
1070
|
break;
|
|
1070
1071
|
}
|
|
1071
1072
|
values.push(next.value);
|
|
@@ -1194,13 +1195,15 @@ function annotateSpan(span, index) {
|
|
|
1194
1195
|
|
|
1195
1196
|
// src/combinators/grammar.ts
|
|
1196
1197
|
function parser(opts, root) {
|
|
1198
|
+
const clearTrivia = opts.trivia === null;
|
|
1197
1199
|
return {
|
|
1198
1200
|
_tag: "grammar",
|
|
1199
1201
|
_meta: root._meta,
|
|
1200
1202
|
_def: {
|
|
1201
1203
|
tag: "grammar",
|
|
1202
1204
|
parser: root,
|
|
1203
|
-
triviaParser: opts.trivia,
|
|
1205
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
1206
|
+
clearTrivia,
|
|
1204
1207
|
trackLines: opts.trackLines ?? false
|
|
1205
1208
|
},
|
|
1206
1209
|
parse(input, pos, _ctx) {
|
|
@@ -1208,7 +1211,11 @@ function parser(opts, root) {
|
|
|
1208
1211
|
const ctx = {
|
|
1209
1212
|
..._ctx,
|
|
1210
1213
|
trackLines,
|
|
1211
|
-
|
|
1214
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
1215
|
+
...clearTrivia ? {
|
|
1216
|
+
trivia: void 0,
|
|
1217
|
+
triviaKindLabels: void 0
|
|
1218
|
+
} : opts.trivia != null ? {
|
|
1212
1219
|
trivia: opts.trivia,
|
|
1213
1220
|
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
1214
1221
|
} : {},
|
|
@@ -1223,6 +1230,9 @@ function parser(opts, root) {
|
|
|
1223
1230
|
}
|
|
1224
1231
|
};
|
|
1225
1232
|
}
|
|
1233
|
+
function noTrivia(root) {
|
|
1234
|
+
return parser({ trivia: null }, root);
|
|
1235
|
+
}
|
|
1226
1236
|
|
|
1227
1237
|
// src/compiler/trivia-fast-path.ts
|
|
1228
1238
|
var BLOCK_COMMENT = String.raw`\/\*(?:[^*]|\*(?!\/))*\*\/`;
|
|
@@ -1545,6 +1555,41 @@ function v(ctx, prefix = "_v") {
|
|
|
1545
1555
|
function ind(ctx) {
|
|
1546
1556
|
return " ".repeat(ctx.indent);
|
|
1547
1557
|
}
|
|
1558
|
+
function reindentStmts(stmts, targetLevels) {
|
|
1559
|
+
const nonEmpty = stmts.filter((s) => s.trim().length > 0);
|
|
1560
|
+
if (nonEmpty.length === 0) return stmts;
|
|
1561
|
+
const minLeading = Math.min(...nonEmpty.map((s) => s.length - s.trimStart().length));
|
|
1562
|
+
const targetPrefix = " ".repeat(targetLevels);
|
|
1563
|
+
return stmts.map((s) => s.trim().length === 0 ? "" : targetPrefix + s.slice(minLeading));
|
|
1564
|
+
}
|
|
1565
|
+
function failReturn(expected, posExpr) {
|
|
1566
|
+
return `return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1567
|
+
}
|
|
1568
|
+
function failReturnArr(expectedArr, posExpr) {
|
|
1569
|
+
return `return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1570
|
+
}
|
|
1571
|
+
function failBody(ctx, expected, posExpr) {
|
|
1572
|
+
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
1573
|
+
return failReturn(expected, posExpr);
|
|
1574
|
+
}
|
|
1575
|
+
function failArrBody(ctx, expectedArr, posExpr) {
|
|
1576
|
+
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
1577
|
+
return failReturnArr(expectedArr, posExpr);
|
|
1578
|
+
}
|
|
1579
|
+
function emitIfFail(ctx, cond, body) {
|
|
1580
|
+
return [
|
|
1581
|
+
`${ind(ctx)}if (${cond}) {`,
|
|
1582
|
+
`${ind(ctx)} ${body}`,
|
|
1583
|
+
`${ind(ctx)}}`
|
|
1584
|
+
];
|
|
1585
|
+
}
|
|
1586
|
+
function emitElseFail(ctx, body) {
|
|
1587
|
+
return [
|
|
1588
|
+
`${ind(ctx)}else {`,
|
|
1589
|
+
`${ind(ctx)} ${body}`,
|
|
1590
|
+
`${ind(ctx)}}`
|
|
1591
|
+
];
|
|
1592
|
+
}
|
|
1548
1593
|
var NAMED_FN_FAIL = "_pfFail";
|
|
1549
1594
|
var NAMED_FN_END = "_pfEnd";
|
|
1550
1595
|
function namedFnPrelude() {
|
|
@@ -1555,8 +1600,10 @@ function pushNamedFnDecl(ctx, fnName, bodyStmts, valueVar, endVar) {
|
|
|
1555
1600
|
`function ${fnName}(input, _pos, _ctx) {`,
|
|
1556
1601
|
` let _pfok = false, _pfv, _pfe = _pos`,
|
|
1557
1602
|
` _pfail: {`,
|
|
1558
|
-
...bodyStmts,
|
|
1559
|
-
`
|
|
1603
|
+
...reindentStmts(bodyStmts, 2),
|
|
1604
|
+
` _pfv = ${valueVar}`,
|
|
1605
|
+
` _pfe = ${endVar}`,
|
|
1606
|
+
` _pfok = true`,
|
|
1560
1607
|
` }`,
|
|
1561
1608
|
` if (!_pfok) return ${NAMED_FN_FAIL}`,
|
|
1562
1609
|
` ${NAMED_FN_END} = _pfe`,
|
|
@@ -1570,7 +1617,7 @@ function emitNamedFnCall(ctx, fnName, pos, failExpected) {
|
|
|
1570
1617
|
return {
|
|
1571
1618
|
stmts: [
|
|
1572
1619
|
`${ind(ctx)}const ${vv} = ${fnName}(input, ${pos}, _ctx)`,
|
|
1573
|
-
|
|
1620
|
+
...emitIfFail(ctx, `${vv} === ${NAMED_FN_FAIL}`, failBody(ctx, failExpected, pos)),
|
|
1574
1621
|
`${ind(ctx)}const ${ev} = ${NAMED_FN_END}`
|
|
1575
1622
|
],
|
|
1576
1623
|
valueVar: vv,
|
|
@@ -1653,7 +1700,7 @@ function ensureTriviaFn(ctx) {
|
|
|
1653
1700
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
1654
1701
|
` let _e = _pos`,
|
|
1655
1702
|
` _triv: {`,
|
|
1656
|
-
...r.stmts,
|
|
1703
|
+
...reindentStmts(r.stmts, 2),
|
|
1657
1704
|
` _e = ${r.endVar}`,
|
|
1658
1705
|
` }`,
|
|
1659
1706
|
` if (_cap && _e > _pos) {`,
|
|
@@ -1668,14 +1715,6 @@ function ensureTriviaFn(ctx) {
|
|
|
1668
1715
|
function ensureTriviaCaptureFn(ctx) {
|
|
1669
1716
|
return ensureTriviaFn(ctx);
|
|
1670
1717
|
}
|
|
1671
|
-
function failStmt(ctx, expected, posExpr) {
|
|
1672
|
-
if (ctx.failLabel) return `${ind(ctx)}break ${ctx.failLabel}`;
|
|
1673
|
-
return `${ind(ctx)}return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1674
|
-
}
|
|
1675
|
-
function failArr(ctx, expectedArr, posExpr) {
|
|
1676
|
-
if (ctx.failLabel) return `${ind(ctx)}break ${ctx.failLabel}`;
|
|
1677
|
-
return `${ind(ctx)}return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1678
|
-
}
|
|
1679
1718
|
function firstSetCond(codeVar, fs) {
|
|
1680
1719
|
if (fs.kind === "any") return "true";
|
|
1681
1720
|
if (fs.kind === "empty") return "false";
|
|
@@ -1691,19 +1730,32 @@ function emitFallible(inner, ctx, pos) {
|
|
|
1691
1730
|
const savedLabel = ctx.failLabel;
|
|
1692
1731
|
const savedIndent = ctx.indent;
|
|
1693
1732
|
ctx.failLabel = lbl;
|
|
1694
|
-
ctx.indent =
|
|
1733
|
+
ctx.indent = savedIndent + 1;
|
|
1695
1734
|
const r = emit(inner, ctx, pos);
|
|
1696
1735
|
ctx.failLabel = savedLabel;
|
|
1697
1736
|
ctx.indent = savedIndent;
|
|
1698
1737
|
const ind0 = ind(ctx);
|
|
1738
|
+
const mL = ctx.capturing ? v(ctx, "_fcl") : null;
|
|
1739
|
+
const mR = ctx.capturing ? v(ctx, "_fcr") : null;
|
|
1740
|
+
const mTl = ctx.capturing ? v(ctx, "_fctl") : null;
|
|
1741
|
+
const mLg = ctx.capturing ? v(ctx, "_fclg") : null;
|
|
1699
1742
|
const stmts = [
|
|
1700
1743
|
`${ind0}let ${okV} = false, ${valV}, ${endV} = ${pos}`,
|
|
1744
|
+
...mL ? [
|
|
1745
|
+
`${ind0}const ${mL} = _ctx._cstLeaves?.length ?? 0`,
|
|
1746
|
+
`${ind0}const ${mR} = _ctx._cstRawChildren?.length ?? 0`,
|
|
1747
|
+
`${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
1748
|
+
`${ind0}const ${mLg} = _ctx._triviaLog?.length ?? 0`
|
|
1749
|
+
] : [],
|
|
1701
1750
|
`${ind0}${lbl}: {`,
|
|
1702
1751
|
...r.stmts,
|
|
1703
1752
|
`${ind0} ${valV} = ${r.valueVar}`,
|
|
1704
1753
|
`${ind0} ${endV} = ${r.endVar}`,
|
|
1705
1754
|
`${ind0} ${okV} = true`,
|
|
1706
|
-
`${ind0}}
|
|
1755
|
+
`${ind0}}`,
|
|
1756
|
+
...mL ? [
|
|
1757
|
+
`${ind0}if (!${okV}) { if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${mL}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${mR}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${mTl}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${mLg} }`
|
|
1758
|
+
] : []
|
|
1707
1759
|
];
|
|
1708
1760
|
return { stmts, okVar: okV, valVar: valV, endVar: endV };
|
|
1709
1761
|
}
|
|
@@ -1716,9 +1768,9 @@ function emitLit(def, ctx, pos) {
|
|
|
1716
1768
|
if (caseInsensitive) {
|
|
1717
1769
|
ctx.needsCollator = true;
|
|
1718
1770
|
stmts.push(
|
|
1719
|
-
|
|
1771
|
+
...emitIfFail(ctx, `${pos} + ${len} > input.length`, failBody(ctx, expectedStr, pos)),
|
|
1720
1772
|
`${ind(ctx)}const ${vv}_s = input.slice(${pos}, ${pos} + ${len})`,
|
|
1721
|
-
|
|
1773
|
+
...emitIfFail(ctx, `_collator.compare(${vv}_s, ${JSON.stringify(value)}) !== 0`, failBody(ctx, expectedStr, pos)),
|
|
1722
1774
|
`${ind(ctx)}const ${vv} = ${vv}_s`
|
|
1723
1775
|
);
|
|
1724
1776
|
} else if (len === 0) {
|
|
@@ -1726,7 +1778,7 @@ function emitLit(def, ctx, pos) {
|
|
|
1726
1778
|
} else if (len === 1) {
|
|
1727
1779
|
const code = value.codePointAt(0);
|
|
1728
1780
|
stmts.push(
|
|
1729
|
-
|
|
1781
|
+
...emitIfFail(ctx, `${pos} >= input.length || input.charCodeAt(${pos}) !== ${code}`, failBody(ctx, expectedStr, pos)),
|
|
1730
1782
|
`${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
|
|
1731
1783
|
);
|
|
1732
1784
|
} else if (len <= 4) {
|
|
@@ -1735,12 +1787,12 @@ function emitLit(def, ctx, pos) {
|
|
|
1735
1787
|
(_, i) => `input.charCodeAt(${pos}${i > 0 ? ` + ${i}` : ""}) !== ${value.codePointAt(i)}`
|
|
1736
1788
|
).join(" || ");
|
|
1737
1789
|
stmts.push(
|
|
1738
|
-
|
|
1790
|
+
...emitIfFail(ctx, `${pos} + ${len} > input.length || ${checks}`, failBody(ctx, expectedStr, pos)),
|
|
1739
1791
|
`${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
|
|
1740
1792
|
);
|
|
1741
1793
|
} else {
|
|
1742
1794
|
stmts.push(
|
|
1743
|
-
|
|
1795
|
+
...emitIfFail(ctx, `!input.startsWith(${JSON.stringify(value)}, ${pos})`, failBody(ctx, expectedStr, pos)),
|
|
1744
1796
|
`${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
|
|
1745
1797
|
);
|
|
1746
1798
|
}
|
|
@@ -1768,7 +1820,7 @@ function emitKeywords(def, ctx, pos) {
|
|
|
1768
1820
|
const stmts = [
|
|
1769
1821
|
`${ind(ctx)}${rName}.lastIndex = ${pos}`,
|
|
1770
1822
|
`${ind(ctx)}const ${mv} = ${rName}.exec(input)`,
|
|
1771
|
-
|
|
1823
|
+
...emitIfFail(ctx, `${mv} === null`, failBody(ctx, '"keyword"', pos)),
|
|
1772
1824
|
`${ind(ctx)}const ${vv} = ${mv}[0]`
|
|
1773
1825
|
];
|
|
1774
1826
|
const endVar = `${pos} + ${vv}.length`;
|
|
@@ -1790,7 +1842,7 @@ function emitRegex(def, ctx, pos) {
|
|
|
1790
1842
|
const stmts = [
|
|
1791
1843
|
`${ind(ctx)}${rName}.lastIndex = ${pos}`,
|
|
1792
1844
|
`${ind(ctx)}const ${mv} = ${rName}.exec(input)`,
|
|
1793
|
-
|
|
1845
|
+
...emitIfFail(ctx, `${mv} === null`, failBody(ctx, expectedStr, pos)),
|
|
1794
1846
|
`${ind(ctx)}const ${vv} = ${mv}[0]`
|
|
1795
1847
|
];
|
|
1796
1848
|
const endVar = `${pos} + ${vv}.length`;
|
|
@@ -1871,11 +1923,12 @@ function emitChoice(def, ctx, pos) {
|
|
|
1871
1923
|
ctx.indent++;
|
|
1872
1924
|
const r = emit(p, ctx, pos);
|
|
1873
1925
|
stmts.push(...r.stmts);
|
|
1874
|
-
stmts.push(`${ind(ctx)}${valV} = ${r.valueVar}
|
|
1926
|
+
stmts.push(`${ind(ctx)}${valV} = ${r.valueVar}`);
|
|
1927
|
+
stmts.push(`${ind(ctx)}${endV} = ${r.endVar}`);
|
|
1875
1928
|
ctx.indent--;
|
|
1876
1929
|
stmts.push(`${ind(ctx)}}`);
|
|
1877
1930
|
}
|
|
1878
|
-
stmts.push(
|
|
1931
|
+
stmts.push(...emitElseFail(ctx, failArrBody(ctx, allExpected, pos)));
|
|
1879
1932
|
return { stmts, valueVar: valV, endVar: endV };
|
|
1880
1933
|
}
|
|
1881
1934
|
return emitNonDisjoint(def, def.strategy, allExpected, ctx, pos);
|
|
@@ -1898,7 +1951,7 @@ function emitGreedyClassify(def, superIndex, allExpected, ctx, pos) {
|
|
|
1898
1951
|
const stmts = [
|
|
1899
1952
|
`${ind(ctx)}${reVar}.lastIndex = ${pos}`,
|
|
1900
1953
|
`${ind(ctx)}const ${matchV} = ${reVar}.exec(input)`,
|
|
1901
|
-
|
|
1954
|
+
...emitIfFail(ctx, `${matchV} === null`, failArrBody(ctx, allExpected, pos)),
|
|
1902
1955
|
`${ind(ctx)}const ${wordV} = ${matchV}[0]`,
|
|
1903
1956
|
`${ind(ctx)}const ${endV} = ${pos} + ${wordV}.length`,
|
|
1904
1957
|
`${ind(ctx)}let ${valV}`
|
|
@@ -1947,12 +2000,13 @@ function emitLiteralsLongestFirst(def, sortedIndices, allExpected, ctx, pos) {
|
|
|
1947
2000
|
stmts.push(
|
|
1948
2001
|
...emitLeafCapture(ctx, JSON.stringify(litVal), pos, litEnd),
|
|
1949
2002
|
...tR.stmts,
|
|
1950
|
-
`${ind(ctx)}${valV} = ${tR.valueVar}
|
|
2003
|
+
`${ind(ctx)}${valV} = ${tR.valueVar}`,
|
|
2004
|
+
`${ind(ctx)}${endV} = ${litEnd}`
|
|
1951
2005
|
);
|
|
1952
2006
|
ctx.indent--;
|
|
1953
2007
|
stmts.push(`${ind(ctx)}}`);
|
|
1954
2008
|
}
|
|
1955
|
-
stmts.push(
|
|
2009
|
+
stmts.push(...emitElseFail(ctx, failArrBody(ctx, allExpected, pos)));
|
|
1956
2010
|
return { stmts, valueVar: valV, endVar: endV };
|
|
1957
2011
|
}
|
|
1958
2012
|
function emitFirstMatch(def, allExpected, ctx, pos) {
|
|
@@ -1998,17 +2052,26 @@ function emitFirstMatch(def, allExpected, ctx, pos) {
|
|
|
1998
2052
|
const rejectCond = autoNot.map(
|
|
1999
2053
|
(check) => check.kind === "firstSet" ? firstSetCond(anCode, check.set) : `input.startsWith(${JSON.stringify(check.value)}, ${endVar})`
|
|
2000
2054
|
).join(" || ");
|
|
2001
|
-
stmts.push(
|
|
2002
|
-
|
|
2003
|
-
);
|
|
2055
|
+
stmts.push(`${ind0} if (${okVar}) {`);
|
|
2056
|
+
stmts.push(`${ind0} const ${anCode} = ${endVar} < input.length ? input.charCodeAt(${endVar}) : -1`);
|
|
2057
|
+
stmts.push(`${ind0} if (!(${rejectCond})) {`);
|
|
2058
|
+
stmts.push(`${ind0} ${resValV} = ${valVar}`);
|
|
2059
|
+
stmts.push(`${ind0} ${resEndV} = ${endVar}`);
|
|
2060
|
+
stmts.push(`${ind0} ${resOkV} = true`);
|
|
2061
|
+
stmts.push(`${ind0} }`);
|
|
2062
|
+
stmts.push(`${ind0} }`);
|
|
2004
2063
|
if (rollback) stmts.push(`${ind0} if (!${resOkV}) { ${rollback} }`);
|
|
2005
2064
|
} else {
|
|
2006
|
-
stmts.push(`${ind0} if (${okVar}) {
|
|
2065
|
+
stmts.push(`${ind0} if (${okVar}) {`);
|
|
2066
|
+
stmts.push(`${ind0} ${resValV} = ${valVar}`);
|
|
2067
|
+
stmts.push(`${ind0} ${resEndV} = ${endVar}`);
|
|
2068
|
+
stmts.push(`${ind0} ${resOkV} = true`);
|
|
2069
|
+
stmts.push(`${ind0} }`);
|
|
2007
2070
|
if (rollback) stmts.push(`${ind0} else { ${rollback} }`);
|
|
2008
2071
|
}
|
|
2009
2072
|
stmts.push(`${ind0}}`);
|
|
2010
2073
|
}
|
|
2011
|
-
stmts.push(
|
|
2074
|
+
stmts.push(...emitIfFail(ctx, `!${resOkV}`, failArrBody(ctx, allExpected, pos)));
|
|
2012
2075
|
return { stmts, valueVar: resValV, endVar: resEndV };
|
|
2013
2076
|
}
|
|
2014
2077
|
function emitNonDisjoint(def, strategy, allExpected, ctx, pos) {
|
|
@@ -2133,32 +2196,26 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
2133
2196
|
const markV = v(ctx, "_mk");
|
|
2134
2197
|
const markTl = v(ctx, "_mktl");
|
|
2135
2198
|
const markLog = v(ctx, "_mklg");
|
|
2199
|
+
const markLv = v(ctx, "_mklv");
|
|
2136
2200
|
const spV = v(ctx, "_sp");
|
|
2137
2201
|
stmts.push(
|
|
2138
2202
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
2139
2203
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
2140
2204
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
2205
|
+
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
2141
2206
|
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`
|
|
2142
2207
|
);
|
|
2143
2208
|
sepAtPos = spV;
|
|
2144
|
-
const
|
|
2209
|
+
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}; `;
|
|
2145
2210
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos);
|
|
2146
|
-
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${
|
|
2147
|
-
const mark2V = v(ctx, "_mk2");
|
|
2148
|
-
const mark2Tl = v(ctx, "_mktl2");
|
|
2149
|
-
const mark2Log = v(ctx, "_mklg2");
|
|
2211
|
+
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}break }`);
|
|
2150
2212
|
const npV = v(ctx, "_np");
|
|
2151
|
-
stmts.push(
|
|
2152
|
-
`${ind(ctx)}const ${mark2V} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
2153
|
-
`${ind(ctx)}const ${mark2Tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
2154
|
-
`${ind(ctx)}const ${mark2Log} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
2155
|
-
`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`
|
|
2156
|
-
);
|
|
2157
|
-
const nextRollback = `if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${mark2V}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${mark2Tl}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${mark2Log}; `;
|
|
2213
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`);
|
|
2158
2214
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, npV);
|
|
2159
2215
|
stmts.push(
|
|
2160
2216
|
...nextStmts,
|
|
2161
|
-
|
|
2217
|
+
// item failed → unwind the separator too, back to the end of the last item
|
|
2218
|
+
`${ind(ctx)}if (!${nextOk}) { ${rollbackToSep}break }`,
|
|
2162
2219
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
2163
2220
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
2164
2221
|
);
|
|
@@ -2180,12 +2237,21 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
2180
2237
|
);
|
|
2181
2238
|
}
|
|
2182
2239
|
} else {
|
|
2240
|
+
const markLv = ctx.capturing ? v(ctx, "_mklv") : null;
|
|
2241
|
+
const markRw = ctx.capturing ? v(ctx, "_mkrw") : null;
|
|
2242
|
+
if (markLv) {
|
|
2243
|
+
stmts.push(
|
|
2244
|
+
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
2245
|
+
`${ind(ctx)}const ${markRw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`
|
|
2246
|
+
);
|
|
2247
|
+
}
|
|
2183
2248
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos);
|
|
2184
2249
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) break`);
|
|
2250
|
+
const nextRb = markLv ? `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${markRw}; ` : "";
|
|
2185
2251
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, sepEnd);
|
|
2186
2252
|
stmts.push(
|
|
2187
2253
|
...nextStmts,
|
|
2188
|
-
`${ind(ctx)}if (!${nextOk}) break`,
|
|
2254
|
+
`${ind(ctx)}if (!${nextOk}) { ${nextRb}break }`,
|
|
2189
2255
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
2190
2256
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
2191
2257
|
);
|
|
@@ -2229,12 +2295,12 @@ function emitScanTo(def, ctx, pos) {
|
|
|
2229
2295
|
if (!def.orEOF) {
|
|
2230
2296
|
const sentDef = def.sentinel._def;
|
|
2231
2297
|
const expectedStr = sentDef.tag === "literal" ? JSON.stringify([JSON.stringify(sentDef.value)]) : `["sentinel"]`;
|
|
2232
|
-
stmts.push(
|
|
2298
|
+
stmts.push(...emitIfFail(ctx, `!${foundV}`, failArrBody(ctx, expectedStr, pos)));
|
|
2233
2299
|
}
|
|
2234
2300
|
const valV = v(ctx);
|
|
2235
2301
|
stmts.push(`${ind(ctx)}const ${valV} = input.slice(${pos}, ${curV})`);
|
|
2236
2302
|
if (ctx.capturing) {
|
|
2237
|
-
const cap = emitLeafCapture(ctx, valV, pos, curV).
|
|
2303
|
+
const cap = reindentStmts(emitLeafCapture(ctx, valV, pos, curV), ctx.indent + 1);
|
|
2238
2304
|
stmts.push(`${ind(ctx)}if (${curV} > ${pos}) {`, ...cap, `${ind(ctx)}}`);
|
|
2239
2305
|
}
|
|
2240
2306
|
return { stmts, valueVar: valV, endVar: curV };
|
|
@@ -2244,7 +2310,7 @@ function emitNot(def, ctx, pos) {
|
|
|
2244
2310
|
return {
|
|
2245
2311
|
stmts: [
|
|
2246
2312
|
...stmts,
|
|
2247
|
-
|
|
2313
|
+
...emitIfFail(ctx, okVar, failBody(ctx, '"not"', pos))
|
|
2248
2314
|
],
|
|
2249
2315
|
valueVar: "null",
|
|
2250
2316
|
endVar: pos
|
|
@@ -2271,7 +2337,7 @@ function emitNode(def, ctx, pos) {
|
|
|
2271
2337
|
const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
|
|
2272
2338
|
stmts.push(...innerStmts);
|
|
2273
2339
|
stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}`);
|
|
2274
|
-
stmts.push(
|
|
2340
|
+
stmts.push(...emitIfFail(ctx, `!${okVar}`, failBody(ctx, '"node"', pos)));
|
|
2275
2341
|
const stV = v(ctx, "_nst");
|
|
2276
2342
|
stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
|
|
2277
2343
|
const ndV = v(ctx, "_nd");
|
|
@@ -2291,7 +2357,7 @@ function emitRuntimeFallback(parser2, ctx, pos) {
|
|
|
2291
2357
|
const ev = v(ctx, "_rte");
|
|
2292
2358
|
const stmts = [
|
|
2293
2359
|
`${ind(ctx)}const ${rv} = _rp[${idx}].parse(input, ${pos}, _ctx)`,
|
|
2294
|
-
|
|
2360
|
+
...emitIfFail(ctx, `!${rv}.ok`, failBody(ctx, '"runtime"', pos)),
|
|
2295
2361
|
`${ind(ctx)}const ${vv} = ${rv}.value`,
|
|
2296
2362
|
`${ind(ctx)}const ${ev} = ${rv}.span.end`
|
|
2297
2363
|
];
|
|
@@ -2325,16 +2391,14 @@ function emitRecover(def, ctx, pos) {
|
|
|
2325
2391
|
const ind0 = ind(ctx);
|
|
2326
2392
|
const scanV = v(ctx, "_sc");
|
|
2327
2393
|
const errV = v(ctx, "_err");
|
|
2328
|
-
const
|
|
2329
|
-
ctx.indent += 2;
|
|
2394
|
+
const whileBodyLevels = ctx.indent + 2;
|
|
2330
2395
|
const { stmts: sentStmts, okVar: sentOk } = emitFallible(def.sentinel, ctx, scanV);
|
|
2331
|
-
ctx.indent = savedIndent;
|
|
2332
2396
|
const stmts = [
|
|
2333
2397
|
...innerStmts,
|
|
2334
2398
|
`${ind0}if (!${okVar}) {`,
|
|
2335
2399
|
`${ind0} let ${scanV} = ${pos}`,
|
|
2336
2400
|
`${ind0} while (${scanV} < input.length) {`,
|
|
2337
|
-
...sentStmts,
|
|
2401
|
+
...reindentStmts(sentStmts, whileBodyLevels),
|
|
2338
2402
|
`${ind0} if (${sentOk}) break`,
|
|
2339
2403
|
`${ind0} ${scanV}++`,
|
|
2340
2404
|
`${ind0} }`,
|
|
@@ -2416,7 +2480,7 @@ function emit(p, ctx, pos) {
|
|
|
2416
2480
|
// try skipped; if fails, keep main end
|
|
2417
2481
|
`${ind(ctx)}let ${endV} = ${mainR.endVar}`,
|
|
2418
2482
|
`${ind(ctx)}try {`,
|
|
2419
|
-
...skipR.stmts.
|
|
2483
|
+
...reindentStmts(skipR.stmts, ctx.indent + 1),
|
|
2420
2484
|
`${ind(ctx)} ${endV} = ${skipR.endVar}`,
|
|
2421
2485
|
`${ind(ctx)}} catch {}`
|
|
2422
2486
|
],
|
|
@@ -2433,7 +2497,10 @@ function emit(p, ctx, pos) {
|
|
|
2433
2497
|
case "grammar": {
|
|
2434
2498
|
const savedTrivia = ctx.activeTrivia;
|
|
2435
2499
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
2436
|
-
if (def.
|
|
2500
|
+
if (def.clearTrivia) {
|
|
2501
|
+
ctx.activeTrivia = void 0;
|
|
2502
|
+
ctx.triviaKindLabels = void 0;
|
|
2503
|
+
} else if (def.triviaParser) {
|
|
2437
2504
|
ctx.activeTrivia = def.triviaParser;
|
|
2438
2505
|
if (def.triviaParser._meta.triviaKindLabels) {
|
|
2439
2506
|
ctx.triviaKindLabels = def.triviaParser._meta.triviaKindLabels;
|
|
@@ -2458,7 +2525,7 @@ function emit(p, ctx, pos) {
|
|
|
2458
2525
|
const vv = v(ctx);
|
|
2459
2526
|
return {
|
|
2460
2527
|
stmts: [
|
|
2461
|
-
|
|
2528
|
+
...emitIfFail(ctx, `!_mf[${fnIdx}](_ctx.state)`, failBody(ctx, '"gate"', pos)),
|
|
2462
2529
|
`${ind(ctx)}const ${vv} = null`
|
|
2463
2530
|
],
|
|
2464
2531
|
valueVar: vv,
|
|
@@ -2490,7 +2557,7 @@ function emit(p, ctx, pos) {
|
|
|
2490
2557
|
stmts: [
|
|
2491
2558
|
`${ind(ctx)}const ${rv} = { ..._ctx, state: _mf[${evIdx}]() }`,
|
|
2492
2559
|
`${ind(ctx)}const ${vv} = ${fn}(input, ${pos}, ${rv})`,
|
|
2493
|
-
|
|
2560
|
+
...emitIfFail(ctx, `${vv} === ${NAMED_FN_FAIL}`, failBody(ctx, '"withCtx"', pos)),
|
|
2494
2561
|
`${ind(ctx)}const ${ev} = ${NAMED_FN_END}`
|
|
2495
2562
|
],
|
|
2496
2563
|
valueVar: vv,
|
|
@@ -2567,7 +2634,7 @@ function compile(combinator, mapFnSources) {
|
|
|
2567
2634
|
...ctx.regexDecls,
|
|
2568
2635
|
"",
|
|
2569
2636
|
...namedPrelude,
|
|
2570
|
-
|
|
2637
|
+
ctx.namedFnDecls.join("\n\n"),
|
|
2571
2638
|
`${collatorDecl}function _parse(input, _pos, _rp, _mf, _build, _ctx) {`,
|
|
2572
2639
|
` let pos = _pos`,
|
|
2573
2640
|
...r.stmts,
|
|
@@ -2578,7 +2645,7 @@ function compile(combinator, mapFnSources) {
|
|
|
2578
2645
|
...ctx.regexDecls,
|
|
2579
2646
|
collatorDecl,
|
|
2580
2647
|
...namedPrelude,
|
|
2581
|
-
...ctx.namedFnDecls,
|
|
2648
|
+
...ctx.namedFnDecls.flatMap((decl, i) => i > 0 ? ["", decl] : [decl]),
|
|
2582
2649
|
`let pos = _pos`,
|
|
2583
2650
|
...r.stmts,
|
|
2584
2651
|
`return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`
|
|
@@ -2613,7 +2680,7 @@ function compile(combinator, mapFnSources) {
|
|
|
2613
2680
|
function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources) {
|
|
2614
2681
|
const bodyLines = [
|
|
2615
2682
|
` let pos = _pos`,
|
|
2616
|
-
...r.stmts
|
|
2683
|
+
...r.stmts,
|
|
2617
2684
|
` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`
|
|
2618
2685
|
];
|
|
2619
2686
|
const innerFn = [
|
|
@@ -2626,17 +2693,23 @@ function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources)
|
|
|
2626
2693
|
const needsWrapper = ctx.regexDecls.length > 0 || !!collatorDecl || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl;
|
|
2627
2694
|
if (!needsWrapper) return innerFn;
|
|
2628
2695
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
2629
|
-
|
|
2630
|
-
`/* @__PURE__ */ (() => {`,
|
|
2696
|
+
const hoistedDecls = [
|
|
2631
2697
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
2632
2698
|
collatorDecl ? ` ${collatorDecl.trim()}` : "",
|
|
2633
2699
|
mfDecl,
|
|
2634
2700
|
buildDecl,
|
|
2635
2701
|
...namedPrelude.map((l) => ` ${l}`),
|
|
2636
|
-
...ctx.namedFnDecls.flatMap((
|
|
2702
|
+
...ctx.namedFnDecls.flatMap((decl, i) => {
|
|
2703
|
+
const lines = decl.split("\n").map((l) => ` ${l}`);
|
|
2704
|
+
return i > 0 ? ["", ...lines] : lines;
|
|
2705
|
+
})
|
|
2706
|
+
].filter(Boolean);
|
|
2707
|
+
return [
|
|
2708
|
+
`/* @__PURE__ */ (() => {`,
|
|
2709
|
+
...hoistedDecls,
|
|
2637
2710
|
` return ${innerFn}`,
|
|
2638
2711
|
`})()`
|
|
2639
|
-
].
|
|
2712
|
+
].join("\n");
|
|
2640
2713
|
}
|
|
2641
2714
|
|
|
2642
2715
|
// src/combinators/scanTo.ts
|
|
@@ -2714,7 +2787,8 @@ var SUPPORTED = {
|
|
|
2714
2787
|
optional: (...a) => optional(a[0]),
|
|
2715
2788
|
sepBy: (...a) => sepBy(a[0], a[1]),
|
|
2716
2789
|
trivia: (...a) => trivia(a[0]),
|
|
2717
|
-
label: (...a) => label(a[0], a[1])
|
|
2790
|
+
label: (...a) => label(a[0], a[1]),
|
|
2791
|
+
noTrivia: (...a) => noTrivia(a[0])
|
|
2718
2792
|
};
|
|
2719
2793
|
function isScopeEntry(v2) {
|
|
2720
2794
|
return !!v2 && typeof v2 === "object" && "combi" in v2 && "mfSrcs" in v2;
|
|
@@ -3170,7 +3244,9 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
3170
3244
|
replacements.push({
|
|
3171
3245
|
start: init.start,
|
|
3172
3246
|
end: init.end,
|
|
3173
|
-
replacement: `{
|
|
3247
|
+
replacement: `{
|
|
3248
|
+
${compiledRules.entries.map(([k, expr]) => ` ${k}: ${expr}`).join(",\n")}
|
|
3249
|
+
}`
|
|
3174
3250
|
});
|
|
3175
3251
|
continue;
|
|
3176
3252
|
}
|