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/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ __export(index_exports, {
|
|
|
45
45
|
makeFunctionalDoc: () => makeFunctionalDoc,
|
|
46
46
|
makeWord: () => makeWord,
|
|
47
47
|
many: () => many,
|
|
48
|
+
noTrivia: () => noTrivia,
|
|
48
49
|
node: () => node,
|
|
49
50
|
not: () => not,
|
|
50
51
|
offsetToLineCol: () => offsetToLineCol,
|
|
@@ -1052,8 +1053,10 @@ function optional(combinator) {
|
|
|
1052
1053
|
_meta: meta,
|
|
1053
1054
|
_def: { tag: "optional", parser: combinator },
|
|
1054
1055
|
parse(input, pos, ctx) {
|
|
1056
|
+
const mark = saveTriviaMark(ctx);
|
|
1055
1057
|
const result = combinator.parse(input, pos, ctx);
|
|
1056
1058
|
if (result.ok) return result;
|
|
1059
|
+
rollbackTrivia(ctx, mark);
|
|
1057
1060
|
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
1058
1061
|
}
|
|
1059
1062
|
};
|
|
@@ -1074,7 +1077,7 @@ function sepBy(combinator, separator) {
|
|
|
1074
1077
|
const values = [first.value];
|
|
1075
1078
|
let cur = first.span.end;
|
|
1076
1079
|
while (cur < input.length) {
|
|
1077
|
-
|
|
1080
|
+
const loopMark = saveTriviaMark(ctx);
|
|
1078
1081
|
let sepPos = cur;
|
|
1079
1082
|
if (ctx.trivia) {
|
|
1080
1083
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -1087,10 +1090,9 @@ function sepBy(combinator, separator) {
|
|
|
1087
1090
|
}
|
|
1088
1091
|
const sep = separator.parse(input, sepPos, ctx);
|
|
1089
1092
|
if (!sep.ok) {
|
|
1090
|
-
rollbackTrivia(ctx,
|
|
1093
|
+
rollbackTrivia(ctx, loopMark);
|
|
1091
1094
|
break;
|
|
1092
1095
|
}
|
|
1093
|
-
mark = saveTriviaMark(ctx);
|
|
1094
1096
|
let nextPos = sep.span.end;
|
|
1095
1097
|
if (ctx.trivia) {
|
|
1096
1098
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -1103,7 +1105,7 @@ function sepBy(combinator, separator) {
|
|
|
1103
1105
|
}
|
|
1104
1106
|
const next = combinator.parse(input, nextPos, ctx);
|
|
1105
1107
|
if (!next.ok) {
|
|
1106
|
-
rollbackTrivia(ctx,
|
|
1108
|
+
rollbackTrivia(ctx, loopMark);
|
|
1107
1109
|
break;
|
|
1108
1110
|
}
|
|
1109
1111
|
values.push(next.value);
|
|
@@ -1306,13 +1308,15 @@ function annotateSpan(span, index) {
|
|
|
1306
1308
|
|
|
1307
1309
|
// src/combinators/grammar.ts
|
|
1308
1310
|
function parser(opts, root) {
|
|
1311
|
+
const clearTrivia = opts.trivia === null;
|
|
1309
1312
|
return {
|
|
1310
1313
|
_tag: "grammar",
|
|
1311
1314
|
_meta: root._meta,
|
|
1312
1315
|
_def: {
|
|
1313
1316
|
tag: "grammar",
|
|
1314
1317
|
parser: root,
|
|
1315
|
-
triviaParser: opts.trivia,
|
|
1318
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
1319
|
+
clearTrivia,
|
|
1316
1320
|
trackLines: opts.trackLines ?? false
|
|
1317
1321
|
},
|
|
1318
1322
|
parse(input, pos, _ctx) {
|
|
@@ -1320,7 +1324,11 @@ function parser(opts, root) {
|
|
|
1320
1324
|
const ctx = {
|
|
1321
1325
|
..._ctx,
|
|
1322
1326
|
trackLines,
|
|
1323
|
-
|
|
1327
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
1328
|
+
...clearTrivia ? {
|
|
1329
|
+
trivia: void 0,
|
|
1330
|
+
triviaKindLabels: void 0
|
|
1331
|
+
} : opts.trivia != null ? {
|
|
1324
1332
|
trivia: opts.trivia,
|
|
1325
1333
|
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
1326
1334
|
} : {},
|
|
@@ -1335,6 +1343,9 @@ function parser(opts, root) {
|
|
|
1335
1343
|
}
|
|
1336
1344
|
};
|
|
1337
1345
|
}
|
|
1346
|
+
function noTrivia(root) {
|
|
1347
|
+
return parser({ trivia: null }, root);
|
|
1348
|
+
}
|
|
1338
1349
|
function parse(combinator, input, opts = {}) {
|
|
1339
1350
|
const trackLines = opts.trackLines ?? false;
|
|
1340
1351
|
const _errors = opts.recover ? [] : void 0;
|
|
@@ -1673,6 +1684,41 @@ function v(ctx, prefix = "_v") {
|
|
|
1673
1684
|
function ind(ctx) {
|
|
1674
1685
|
return " ".repeat(ctx.indent);
|
|
1675
1686
|
}
|
|
1687
|
+
function reindentStmts(stmts, targetLevels) {
|
|
1688
|
+
const nonEmpty = stmts.filter((s) => s.trim().length > 0);
|
|
1689
|
+
if (nonEmpty.length === 0) return stmts;
|
|
1690
|
+
const minLeading = Math.min(...nonEmpty.map((s) => s.length - s.trimStart().length));
|
|
1691
|
+
const targetPrefix = " ".repeat(targetLevels);
|
|
1692
|
+
return stmts.map((s) => s.trim().length === 0 ? "" : targetPrefix + s.slice(minLeading));
|
|
1693
|
+
}
|
|
1694
|
+
function failReturn(expected, posExpr) {
|
|
1695
|
+
return `return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1696
|
+
}
|
|
1697
|
+
function failReturnArr(expectedArr, posExpr) {
|
|
1698
|
+
return `return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1699
|
+
}
|
|
1700
|
+
function failBody(ctx, expected, posExpr) {
|
|
1701
|
+
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
1702
|
+
return failReturn(expected, posExpr);
|
|
1703
|
+
}
|
|
1704
|
+
function failArrBody(ctx, expectedArr, posExpr) {
|
|
1705
|
+
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
1706
|
+
return failReturnArr(expectedArr, posExpr);
|
|
1707
|
+
}
|
|
1708
|
+
function emitIfFail(ctx, cond, body) {
|
|
1709
|
+
return [
|
|
1710
|
+
`${ind(ctx)}if (${cond}) {`,
|
|
1711
|
+
`${ind(ctx)} ${body}`,
|
|
1712
|
+
`${ind(ctx)}}`
|
|
1713
|
+
];
|
|
1714
|
+
}
|
|
1715
|
+
function emitElseFail(ctx, body) {
|
|
1716
|
+
return [
|
|
1717
|
+
`${ind(ctx)}else {`,
|
|
1718
|
+
`${ind(ctx)} ${body}`,
|
|
1719
|
+
`${ind(ctx)}}`
|
|
1720
|
+
];
|
|
1721
|
+
}
|
|
1676
1722
|
var NAMED_FN_FAIL = "_pfFail";
|
|
1677
1723
|
var NAMED_FN_END = "_pfEnd";
|
|
1678
1724
|
function namedFnPrelude() {
|
|
@@ -1683,8 +1729,10 @@ function pushNamedFnDecl(ctx, fnName, bodyStmts, valueVar, endVar) {
|
|
|
1683
1729
|
`function ${fnName}(input, _pos, _ctx) {`,
|
|
1684
1730
|
` let _pfok = false, _pfv, _pfe = _pos`,
|
|
1685
1731
|
` _pfail: {`,
|
|
1686
|
-
...bodyStmts,
|
|
1687
|
-
`
|
|
1732
|
+
...reindentStmts(bodyStmts, 2),
|
|
1733
|
+
` _pfv = ${valueVar}`,
|
|
1734
|
+
` _pfe = ${endVar}`,
|
|
1735
|
+
` _pfok = true`,
|
|
1688
1736
|
` }`,
|
|
1689
1737
|
` if (!_pfok) return ${NAMED_FN_FAIL}`,
|
|
1690
1738
|
` ${NAMED_FN_END} = _pfe`,
|
|
@@ -1698,7 +1746,7 @@ function emitNamedFnCall(ctx, fnName, pos, failExpected) {
|
|
|
1698
1746
|
return {
|
|
1699
1747
|
stmts: [
|
|
1700
1748
|
`${ind(ctx)}const ${vv} = ${fnName}(input, ${pos}, _ctx)`,
|
|
1701
|
-
|
|
1749
|
+
...emitIfFail(ctx, `${vv} === ${NAMED_FN_FAIL}`, failBody(ctx, failExpected, pos)),
|
|
1702
1750
|
`${ind(ctx)}const ${ev} = ${NAMED_FN_END}`
|
|
1703
1751
|
],
|
|
1704
1752
|
valueVar: vv,
|
|
@@ -1781,7 +1829,7 @@ function ensureTriviaFn(ctx) {
|
|
|
1781
1829
|
`function ${fnName}(input, _pos, _ctx, _cap) {`,
|
|
1782
1830
|
` let _e = _pos`,
|
|
1783
1831
|
` _triv: {`,
|
|
1784
|
-
...r.stmts,
|
|
1832
|
+
...reindentStmts(r.stmts, 2),
|
|
1785
1833
|
` _e = ${r.endVar}`,
|
|
1786
1834
|
` }`,
|
|
1787
1835
|
` if (_cap && _e > _pos) {`,
|
|
@@ -1796,14 +1844,6 @@ function ensureTriviaFn(ctx) {
|
|
|
1796
1844
|
function ensureTriviaCaptureFn(ctx) {
|
|
1797
1845
|
return ensureTriviaFn(ctx);
|
|
1798
1846
|
}
|
|
1799
|
-
function failStmt(ctx, expected, posExpr) {
|
|
1800
|
-
if (ctx.failLabel) return `${ind(ctx)}break ${ctx.failLabel}`;
|
|
1801
|
-
return `${ind(ctx)}return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1802
|
-
}
|
|
1803
|
-
function failArr(ctx, expectedArr, posExpr) {
|
|
1804
|
-
if (ctx.failLabel) return `${ind(ctx)}break ${ctx.failLabel}`;
|
|
1805
|
-
return `${ind(ctx)}return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
1806
|
-
}
|
|
1807
1847
|
function firstSetCond(codeVar, fs) {
|
|
1808
1848
|
if (fs.kind === "any") return "true";
|
|
1809
1849
|
if (fs.kind === "empty") return "false";
|
|
@@ -1819,19 +1859,32 @@ function emitFallible(inner, ctx, pos) {
|
|
|
1819
1859
|
const savedLabel = ctx.failLabel;
|
|
1820
1860
|
const savedIndent = ctx.indent;
|
|
1821
1861
|
ctx.failLabel = lbl;
|
|
1822
|
-
ctx.indent =
|
|
1862
|
+
ctx.indent = savedIndent + 1;
|
|
1823
1863
|
const r = emit(inner, ctx, pos);
|
|
1824
1864
|
ctx.failLabel = savedLabel;
|
|
1825
1865
|
ctx.indent = savedIndent;
|
|
1826
1866
|
const ind0 = ind(ctx);
|
|
1867
|
+
const mL = ctx.capturing ? v(ctx, "_fcl") : null;
|
|
1868
|
+
const mR = ctx.capturing ? v(ctx, "_fcr") : null;
|
|
1869
|
+
const mTl = ctx.capturing ? v(ctx, "_fctl") : null;
|
|
1870
|
+
const mLg = ctx.capturing ? v(ctx, "_fclg") : null;
|
|
1827
1871
|
const stmts = [
|
|
1828
1872
|
`${ind0}let ${okV} = false, ${valV}, ${endV} = ${pos}`,
|
|
1873
|
+
...mL ? [
|
|
1874
|
+
`${ind0}const ${mL} = _ctx._cstLeaves?.length ?? 0`,
|
|
1875
|
+
`${ind0}const ${mR} = _ctx._cstRawChildren?.length ?? 0`,
|
|
1876
|
+
`${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0`,
|
|
1877
|
+
`${ind0}const ${mLg} = _ctx._triviaLog?.length ?? 0`
|
|
1878
|
+
] : [],
|
|
1829
1879
|
`${ind0}${lbl}: {`,
|
|
1830
1880
|
...r.stmts,
|
|
1831
1881
|
`${ind0} ${valV} = ${r.valueVar}`,
|
|
1832
1882
|
`${ind0} ${endV} = ${r.endVar}`,
|
|
1833
1883
|
`${ind0} ${okV} = true`,
|
|
1834
|
-
`${ind0}}
|
|
1884
|
+
`${ind0}}`,
|
|
1885
|
+
...mL ? [
|
|
1886
|
+
`${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} }`
|
|
1887
|
+
] : []
|
|
1835
1888
|
];
|
|
1836
1889
|
return { stmts, okVar: okV, valVar: valV, endVar: endV };
|
|
1837
1890
|
}
|
|
@@ -1844,9 +1897,9 @@ function emitLit(def, ctx, pos) {
|
|
|
1844
1897
|
if (caseInsensitive) {
|
|
1845
1898
|
ctx.needsCollator = true;
|
|
1846
1899
|
stmts.push(
|
|
1847
|
-
|
|
1900
|
+
...emitIfFail(ctx, `${pos} + ${len} > input.length`, failBody(ctx, expectedStr, pos)),
|
|
1848
1901
|
`${ind(ctx)}const ${vv}_s = input.slice(${pos}, ${pos} + ${len})`,
|
|
1849
|
-
|
|
1902
|
+
...emitIfFail(ctx, `_collator.compare(${vv}_s, ${JSON.stringify(value)}) !== 0`, failBody(ctx, expectedStr, pos)),
|
|
1850
1903
|
`${ind(ctx)}const ${vv} = ${vv}_s`
|
|
1851
1904
|
);
|
|
1852
1905
|
} else if (len === 0) {
|
|
@@ -1854,7 +1907,7 @@ function emitLit(def, ctx, pos) {
|
|
|
1854
1907
|
} else if (len === 1) {
|
|
1855
1908
|
const code = value.codePointAt(0);
|
|
1856
1909
|
stmts.push(
|
|
1857
|
-
|
|
1910
|
+
...emitIfFail(ctx, `${pos} >= input.length || input.charCodeAt(${pos}) !== ${code}`, failBody(ctx, expectedStr, pos)),
|
|
1858
1911
|
`${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
|
|
1859
1912
|
);
|
|
1860
1913
|
} else if (len <= 4) {
|
|
@@ -1863,12 +1916,12 @@ function emitLit(def, ctx, pos) {
|
|
|
1863
1916
|
(_, i) => `input.charCodeAt(${pos}${i > 0 ? ` + ${i}` : ""}) !== ${value.codePointAt(i)}`
|
|
1864
1917
|
).join(" || ");
|
|
1865
1918
|
stmts.push(
|
|
1866
|
-
|
|
1919
|
+
...emitIfFail(ctx, `${pos} + ${len} > input.length || ${checks}`, failBody(ctx, expectedStr, pos)),
|
|
1867
1920
|
`${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
|
|
1868
1921
|
);
|
|
1869
1922
|
} else {
|
|
1870
1923
|
stmts.push(
|
|
1871
|
-
|
|
1924
|
+
...emitIfFail(ctx, `!input.startsWith(${JSON.stringify(value)}, ${pos})`, failBody(ctx, expectedStr, pos)),
|
|
1872
1925
|
`${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
|
|
1873
1926
|
);
|
|
1874
1927
|
}
|
|
@@ -1896,7 +1949,7 @@ function emitKeywords(def, ctx, pos) {
|
|
|
1896
1949
|
const stmts = [
|
|
1897
1950
|
`${ind(ctx)}${rName}.lastIndex = ${pos}`,
|
|
1898
1951
|
`${ind(ctx)}const ${mv} = ${rName}.exec(input)`,
|
|
1899
|
-
|
|
1952
|
+
...emitIfFail(ctx, `${mv} === null`, failBody(ctx, '"keyword"', pos)),
|
|
1900
1953
|
`${ind(ctx)}const ${vv} = ${mv}[0]`
|
|
1901
1954
|
];
|
|
1902
1955
|
const endVar = `${pos} + ${vv}.length`;
|
|
@@ -1918,7 +1971,7 @@ function emitRegex(def, ctx, pos) {
|
|
|
1918
1971
|
const stmts = [
|
|
1919
1972
|
`${ind(ctx)}${rName}.lastIndex = ${pos}`,
|
|
1920
1973
|
`${ind(ctx)}const ${mv} = ${rName}.exec(input)`,
|
|
1921
|
-
|
|
1974
|
+
...emitIfFail(ctx, `${mv} === null`, failBody(ctx, expectedStr, pos)),
|
|
1922
1975
|
`${ind(ctx)}const ${vv} = ${mv}[0]`
|
|
1923
1976
|
];
|
|
1924
1977
|
const endVar = `${pos} + ${vv}.length`;
|
|
@@ -1999,11 +2052,12 @@ function emitChoice(def, ctx, pos) {
|
|
|
1999
2052
|
ctx.indent++;
|
|
2000
2053
|
const r = emit(p, ctx, pos);
|
|
2001
2054
|
stmts.push(...r.stmts);
|
|
2002
|
-
stmts.push(`${ind(ctx)}${valV} = ${r.valueVar}
|
|
2055
|
+
stmts.push(`${ind(ctx)}${valV} = ${r.valueVar}`);
|
|
2056
|
+
stmts.push(`${ind(ctx)}${endV} = ${r.endVar}`);
|
|
2003
2057
|
ctx.indent--;
|
|
2004
2058
|
stmts.push(`${ind(ctx)}}`);
|
|
2005
2059
|
}
|
|
2006
|
-
stmts.push(
|
|
2060
|
+
stmts.push(...emitElseFail(ctx, failArrBody(ctx, allExpected, pos)));
|
|
2007
2061
|
return { stmts, valueVar: valV, endVar: endV };
|
|
2008
2062
|
}
|
|
2009
2063
|
return emitNonDisjoint(def, def.strategy, allExpected, ctx, pos);
|
|
@@ -2026,7 +2080,7 @@ function emitGreedyClassify(def, superIndex, allExpected, ctx, pos) {
|
|
|
2026
2080
|
const stmts = [
|
|
2027
2081
|
`${ind(ctx)}${reVar}.lastIndex = ${pos}`,
|
|
2028
2082
|
`${ind(ctx)}const ${matchV} = ${reVar}.exec(input)`,
|
|
2029
|
-
|
|
2083
|
+
...emitIfFail(ctx, `${matchV} === null`, failArrBody(ctx, allExpected, pos)),
|
|
2030
2084
|
`${ind(ctx)}const ${wordV} = ${matchV}[0]`,
|
|
2031
2085
|
`${ind(ctx)}const ${endV} = ${pos} + ${wordV}.length`,
|
|
2032
2086
|
`${ind(ctx)}let ${valV}`
|
|
@@ -2075,12 +2129,13 @@ function emitLiteralsLongestFirst(def, sortedIndices, allExpected, ctx, pos) {
|
|
|
2075
2129
|
stmts.push(
|
|
2076
2130
|
...emitLeafCapture(ctx, JSON.stringify(litVal), pos, litEnd),
|
|
2077
2131
|
...tR.stmts,
|
|
2078
|
-
`${ind(ctx)}${valV} = ${tR.valueVar}
|
|
2132
|
+
`${ind(ctx)}${valV} = ${tR.valueVar}`,
|
|
2133
|
+
`${ind(ctx)}${endV} = ${litEnd}`
|
|
2079
2134
|
);
|
|
2080
2135
|
ctx.indent--;
|
|
2081
2136
|
stmts.push(`${ind(ctx)}}`);
|
|
2082
2137
|
}
|
|
2083
|
-
stmts.push(
|
|
2138
|
+
stmts.push(...emitElseFail(ctx, failArrBody(ctx, allExpected, pos)));
|
|
2084
2139
|
return { stmts, valueVar: valV, endVar: endV };
|
|
2085
2140
|
}
|
|
2086
2141
|
function emitFirstMatch(def, allExpected, ctx, pos) {
|
|
@@ -2126,17 +2181,26 @@ function emitFirstMatch(def, allExpected, ctx, pos) {
|
|
|
2126
2181
|
const rejectCond = autoNot.map(
|
|
2127
2182
|
(check) => check.kind === "firstSet" ? firstSetCond(anCode, check.set) : `input.startsWith(${JSON.stringify(check.value)}, ${endVar})`
|
|
2128
2183
|
).join(" || ");
|
|
2129
|
-
stmts.push(
|
|
2130
|
-
|
|
2131
|
-
);
|
|
2184
|
+
stmts.push(`${ind0} if (${okVar}) {`);
|
|
2185
|
+
stmts.push(`${ind0} const ${anCode} = ${endVar} < input.length ? input.charCodeAt(${endVar}) : -1`);
|
|
2186
|
+
stmts.push(`${ind0} if (!(${rejectCond})) {`);
|
|
2187
|
+
stmts.push(`${ind0} ${resValV} = ${valVar}`);
|
|
2188
|
+
stmts.push(`${ind0} ${resEndV} = ${endVar}`);
|
|
2189
|
+
stmts.push(`${ind0} ${resOkV} = true`);
|
|
2190
|
+
stmts.push(`${ind0} }`);
|
|
2191
|
+
stmts.push(`${ind0} }`);
|
|
2132
2192
|
if (rollback) stmts.push(`${ind0} if (!${resOkV}) { ${rollback} }`);
|
|
2133
2193
|
} else {
|
|
2134
|
-
stmts.push(`${ind0} if (${okVar}) {
|
|
2194
|
+
stmts.push(`${ind0} if (${okVar}) {`);
|
|
2195
|
+
stmts.push(`${ind0} ${resValV} = ${valVar}`);
|
|
2196
|
+
stmts.push(`${ind0} ${resEndV} = ${endVar}`);
|
|
2197
|
+
stmts.push(`${ind0} ${resOkV} = true`);
|
|
2198
|
+
stmts.push(`${ind0} }`);
|
|
2135
2199
|
if (rollback) stmts.push(`${ind0} else { ${rollback} }`);
|
|
2136
2200
|
}
|
|
2137
2201
|
stmts.push(`${ind0}}`);
|
|
2138
2202
|
}
|
|
2139
|
-
stmts.push(
|
|
2203
|
+
stmts.push(...emitIfFail(ctx, `!${resOkV}`, failArrBody(ctx, allExpected, pos)));
|
|
2140
2204
|
return { stmts, valueVar: resValV, endVar: resEndV };
|
|
2141
2205
|
}
|
|
2142
2206
|
function emitNonDisjoint(def, strategy, allExpected, ctx, pos) {
|
|
@@ -2261,32 +2325,26 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
2261
2325
|
const markV = v(ctx, "_mk");
|
|
2262
2326
|
const markTl = v(ctx, "_mktl");
|
|
2263
2327
|
const markLog = v(ctx, "_mklg");
|
|
2328
|
+
const markLv = v(ctx, "_mklv");
|
|
2264
2329
|
const spV = v(ctx, "_sp");
|
|
2265
2330
|
stmts.push(
|
|
2266
2331
|
`${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
2267
2332
|
`${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
2268
2333
|
`${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
2334
|
+
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
2269
2335
|
`${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`
|
|
2270
2336
|
);
|
|
2271
2337
|
sepAtPos = spV;
|
|
2272
|
-
const
|
|
2338
|
+
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}; `;
|
|
2273
2339
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos);
|
|
2274
|
-
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${
|
|
2275
|
-
const mark2V = v(ctx, "_mk2");
|
|
2276
|
-
const mark2Tl = v(ctx, "_mktl2");
|
|
2277
|
-
const mark2Log = v(ctx, "_mklg2");
|
|
2340
|
+
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}break }`);
|
|
2278
2341
|
const npV = v(ctx, "_np");
|
|
2279
|
-
stmts.push(
|
|
2280
|
-
`${ind(ctx)}const ${mark2V} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
|
|
2281
|
-
`${ind(ctx)}const ${mark2Tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
|
|
2282
|
-
`${ind(ctx)}const ${mark2Log} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
|
|
2283
|
-
`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`
|
|
2284
|
-
);
|
|
2285
|
-
const nextRollback = `if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${mark2V}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${mark2Tl}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${mark2Log}; `;
|
|
2342
|
+
stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`);
|
|
2286
2343
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, npV);
|
|
2287
2344
|
stmts.push(
|
|
2288
2345
|
...nextStmts,
|
|
2289
|
-
|
|
2346
|
+
// item failed → unwind the separator too, back to the end of the last item
|
|
2347
|
+
`${ind(ctx)}if (!${nextOk}) { ${rollbackToSep}break }`,
|
|
2290
2348
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
2291
2349
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
2292
2350
|
);
|
|
@@ -2308,12 +2366,21 @@ function emitSepBy(_p, def, ctx, pos) {
|
|
|
2308
2366
|
);
|
|
2309
2367
|
}
|
|
2310
2368
|
} else {
|
|
2369
|
+
const markLv = ctx.capturing ? v(ctx, "_mklv") : null;
|
|
2370
|
+
const markRw = ctx.capturing ? v(ctx, "_mkrw") : null;
|
|
2371
|
+
if (markLv) {
|
|
2372
|
+
stmts.push(
|
|
2373
|
+
`${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
|
|
2374
|
+
`${ind(ctx)}const ${markRw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`
|
|
2375
|
+
);
|
|
2376
|
+
}
|
|
2311
2377
|
const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos);
|
|
2312
2378
|
stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) break`);
|
|
2379
|
+
const nextRb = markLv ? `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${markRw}; ` : "";
|
|
2313
2380
|
const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, sepEnd);
|
|
2314
2381
|
stmts.push(
|
|
2315
2382
|
...nextStmts,
|
|
2316
|
-
`${ind(ctx)}if (!${nextOk}) break`,
|
|
2383
|
+
`${ind(ctx)}if (!${nextOk}) { ${nextRb}break }`,
|
|
2317
2384
|
`${ind(ctx)}${arrV}.push(${nextVal})`,
|
|
2318
2385
|
`${ind(ctx)}${curV} = ${nextEnd}`
|
|
2319
2386
|
);
|
|
@@ -2357,12 +2424,12 @@ function emitScanTo(def, ctx, pos) {
|
|
|
2357
2424
|
if (!def.orEOF) {
|
|
2358
2425
|
const sentDef = def.sentinel._def;
|
|
2359
2426
|
const expectedStr = sentDef.tag === "literal" ? JSON.stringify([JSON.stringify(sentDef.value)]) : `["sentinel"]`;
|
|
2360
|
-
stmts.push(
|
|
2427
|
+
stmts.push(...emitIfFail(ctx, `!${foundV}`, failArrBody(ctx, expectedStr, pos)));
|
|
2361
2428
|
}
|
|
2362
2429
|
const valV = v(ctx);
|
|
2363
2430
|
stmts.push(`${ind(ctx)}const ${valV} = input.slice(${pos}, ${curV})`);
|
|
2364
2431
|
if (ctx.capturing) {
|
|
2365
|
-
const cap = emitLeafCapture(ctx, valV, pos, curV).
|
|
2432
|
+
const cap = reindentStmts(emitLeafCapture(ctx, valV, pos, curV), ctx.indent + 1);
|
|
2366
2433
|
stmts.push(`${ind(ctx)}if (${curV} > ${pos}) {`, ...cap, `${ind(ctx)}}`);
|
|
2367
2434
|
}
|
|
2368
2435
|
return { stmts, valueVar: valV, endVar: curV };
|
|
@@ -2372,7 +2439,7 @@ function emitNot(def, ctx, pos) {
|
|
|
2372
2439
|
return {
|
|
2373
2440
|
stmts: [
|
|
2374
2441
|
...stmts,
|
|
2375
|
-
|
|
2442
|
+
...emitIfFail(ctx, okVar, failBody(ctx, '"not"', pos))
|
|
2376
2443
|
],
|
|
2377
2444
|
valueVar: "null",
|
|
2378
2445
|
endVar: pos
|
|
@@ -2399,7 +2466,7 @@ function emitNode(def, ctx, pos) {
|
|
|
2399
2466
|
const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
|
|
2400
2467
|
stmts.push(...innerStmts);
|
|
2401
2468
|
stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}`);
|
|
2402
|
-
stmts.push(
|
|
2469
|
+
stmts.push(...emitIfFail(ctx, `!${okVar}`, failBody(ctx, '"node"', pos)));
|
|
2403
2470
|
const stV = v(ctx, "_nst");
|
|
2404
2471
|
stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
|
|
2405
2472
|
const ndV = v(ctx, "_nd");
|
|
@@ -2419,7 +2486,7 @@ function emitRuntimeFallback(parser2, ctx, pos) {
|
|
|
2419
2486
|
const ev = v(ctx, "_rte");
|
|
2420
2487
|
const stmts = [
|
|
2421
2488
|
`${ind(ctx)}const ${rv} = _rp[${idx}].parse(input, ${pos}, _ctx)`,
|
|
2422
|
-
|
|
2489
|
+
...emitIfFail(ctx, `!${rv}.ok`, failBody(ctx, '"runtime"', pos)),
|
|
2423
2490
|
`${ind(ctx)}const ${vv} = ${rv}.value`,
|
|
2424
2491
|
`${ind(ctx)}const ${ev} = ${rv}.span.end`
|
|
2425
2492
|
];
|
|
@@ -2453,16 +2520,14 @@ function emitRecover(def, ctx, pos) {
|
|
|
2453
2520
|
const ind0 = ind(ctx);
|
|
2454
2521
|
const scanV = v(ctx, "_sc");
|
|
2455
2522
|
const errV = v(ctx, "_err");
|
|
2456
|
-
const
|
|
2457
|
-
ctx.indent += 2;
|
|
2523
|
+
const whileBodyLevels = ctx.indent + 2;
|
|
2458
2524
|
const { stmts: sentStmts, okVar: sentOk } = emitFallible(def.sentinel, ctx, scanV);
|
|
2459
|
-
ctx.indent = savedIndent;
|
|
2460
2525
|
const stmts = [
|
|
2461
2526
|
...innerStmts,
|
|
2462
2527
|
`${ind0}if (!${okVar}) {`,
|
|
2463
2528
|
`${ind0} let ${scanV} = ${pos}`,
|
|
2464
2529
|
`${ind0} while (${scanV} < input.length) {`,
|
|
2465
|
-
...sentStmts,
|
|
2530
|
+
...reindentStmts(sentStmts, whileBodyLevels),
|
|
2466
2531
|
`${ind0} if (${sentOk}) break`,
|
|
2467
2532
|
`${ind0} ${scanV}++`,
|
|
2468
2533
|
`${ind0} }`,
|
|
@@ -2544,7 +2609,7 @@ function emit(p, ctx, pos) {
|
|
|
2544
2609
|
// try skipped; if fails, keep main end
|
|
2545
2610
|
`${ind(ctx)}let ${endV} = ${mainR.endVar}`,
|
|
2546
2611
|
`${ind(ctx)}try {`,
|
|
2547
|
-
...skipR.stmts.
|
|
2612
|
+
...reindentStmts(skipR.stmts, ctx.indent + 1),
|
|
2548
2613
|
`${ind(ctx)} ${endV} = ${skipR.endVar}`,
|
|
2549
2614
|
`${ind(ctx)}} catch {}`
|
|
2550
2615
|
],
|
|
@@ -2561,7 +2626,10 @@ function emit(p, ctx, pos) {
|
|
|
2561
2626
|
case "grammar": {
|
|
2562
2627
|
const savedTrivia = ctx.activeTrivia;
|
|
2563
2628
|
const savedKindLabels = ctx.triviaKindLabels;
|
|
2564
|
-
if (def.
|
|
2629
|
+
if (def.clearTrivia) {
|
|
2630
|
+
ctx.activeTrivia = void 0;
|
|
2631
|
+
ctx.triviaKindLabels = void 0;
|
|
2632
|
+
} else if (def.triviaParser) {
|
|
2565
2633
|
ctx.activeTrivia = def.triviaParser;
|
|
2566
2634
|
if (def.triviaParser._meta.triviaKindLabels) {
|
|
2567
2635
|
ctx.triviaKindLabels = def.triviaParser._meta.triviaKindLabels;
|
|
@@ -2586,7 +2654,7 @@ function emit(p, ctx, pos) {
|
|
|
2586
2654
|
const vv = v(ctx);
|
|
2587
2655
|
return {
|
|
2588
2656
|
stmts: [
|
|
2589
|
-
|
|
2657
|
+
...emitIfFail(ctx, `!_mf[${fnIdx}](_ctx.state)`, failBody(ctx, '"gate"', pos)),
|
|
2590
2658
|
`${ind(ctx)}const ${vv} = null`
|
|
2591
2659
|
],
|
|
2592
2660
|
valueVar: vv,
|
|
@@ -2618,7 +2686,7 @@ function emit(p, ctx, pos) {
|
|
|
2618
2686
|
stmts: [
|
|
2619
2687
|
`${ind(ctx)}const ${rv} = { ..._ctx, state: _mf[${evIdx}]() }`,
|
|
2620
2688
|
`${ind(ctx)}const ${vv} = ${fn}(input, ${pos}, ${rv})`,
|
|
2621
|
-
|
|
2689
|
+
...emitIfFail(ctx, `${vv} === ${NAMED_FN_FAIL}`, failBody(ctx, '"withCtx"', pos)),
|
|
2622
2690
|
`${ind(ctx)}const ${ev} = ${NAMED_FN_END}`
|
|
2623
2691
|
],
|
|
2624
2692
|
valueVar: vv,
|
|
@@ -2695,7 +2763,7 @@ function compile(combinator, mapFnSources) {
|
|
|
2695
2763
|
...ctx.regexDecls,
|
|
2696
2764
|
"",
|
|
2697
2765
|
...namedPrelude,
|
|
2698
|
-
|
|
2766
|
+
ctx.namedFnDecls.join("\n\n"),
|
|
2699
2767
|
`${collatorDecl}function _parse(input, _pos, _rp, _mf, _build, _ctx) {`,
|
|
2700
2768
|
` let pos = _pos`,
|
|
2701
2769
|
...r.stmts,
|
|
@@ -2706,7 +2774,7 @@ function compile(combinator, mapFnSources) {
|
|
|
2706
2774
|
...ctx.regexDecls,
|
|
2707
2775
|
collatorDecl,
|
|
2708
2776
|
...namedPrelude,
|
|
2709
|
-
...ctx.namedFnDecls,
|
|
2777
|
+
...ctx.namedFnDecls.flatMap((decl, i) => i > 0 ? ["", decl] : [decl]),
|
|
2710
2778
|
`let pos = _pos`,
|
|
2711
2779
|
...r.stmts,
|
|
2712
2780
|
`return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`
|
|
@@ -2741,7 +2809,7 @@ function compile(combinator, mapFnSources) {
|
|
|
2741
2809
|
function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources) {
|
|
2742
2810
|
const bodyLines = [
|
|
2743
2811
|
` let pos = _pos`,
|
|
2744
|
-
...r.stmts
|
|
2812
|
+
...r.stmts,
|
|
2745
2813
|
` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`
|
|
2746
2814
|
];
|
|
2747
2815
|
const innerFn = [
|
|
@@ -2754,17 +2822,23 @@ function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources)
|
|
|
2754
2822
|
const needsWrapper = ctx.regexDecls.length > 0 || !!collatorDecl || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl;
|
|
2755
2823
|
if (!needsWrapper) return innerFn;
|
|
2756
2824
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
2757
|
-
|
|
2758
|
-
`/* @__PURE__ */ (() => {`,
|
|
2825
|
+
const hoistedDecls = [
|
|
2759
2826
|
...ctx.regexDecls.map((d) => ` ${d}`),
|
|
2760
2827
|
collatorDecl ? ` ${collatorDecl.trim()}` : "",
|
|
2761
2828
|
mfDecl,
|
|
2762
2829
|
buildDecl,
|
|
2763
2830
|
...namedPrelude.map((l) => ` ${l}`),
|
|
2764
|
-
...ctx.namedFnDecls.flatMap((
|
|
2831
|
+
...ctx.namedFnDecls.flatMap((decl, i) => {
|
|
2832
|
+
const lines = decl.split("\n").map((l) => ` ${l}`);
|
|
2833
|
+
return i > 0 ? ["", ...lines] : lines;
|
|
2834
|
+
})
|
|
2835
|
+
].filter(Boolean);
|
|
2836
|
+
return [
|
|
2837
|
+
`/* @__PURE__ */ (() => {`,
|
|
2838
|
+
...hoistedDecls,
|
|
2765
2839
|
` return ${innerFn}`,
|
|
2766
2840
|
`})()`
|
|
2767
|
-
].
|
|
2841
|
+
].join("\n");
|
|
2768
2842
|
}
|
|
2769
2843
|
|
|
2770
2844
|
// src/combinators/guard.ts
|