parseman 0.6.2 → 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.
@@ -1 +1 @@
1
- {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/plugin/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,UAAU,EAAE,IAAI,EAMjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAa7C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AACD,MAAM,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAM3C,KAAK,gBAAgB,GAAG;IAAE,GAAG,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AA6ShE,0EAA0E;AAC1E,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,gBAAgB,GAAG,IAAI,CAUzB;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAE5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,UAAU,EACvB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EAAE,GACrB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAuGzC;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAcnF"}
1
+ {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/plugin/evaluator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EACV,UAAU,EAAE,IAAI,EAMjB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAa7C,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AACD,MAAM,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AAM3C,KAAK,gBAAgB,GAAG;IAAE,GAAG,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AA8ShE,0EAA0E;AAC1E,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,gBAAgB,GAAG,IAAI,CAUzB;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAE5B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,UAAU,EACvB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EAAE,GACrB,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAuGzC;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAcnF"}
@@ -1049,8 +1049,10 @@ function optional(combinator) {
1049
1049
  _meta: meta,
1050
1050
  _def: { tag: "optional", parser: combinator },
1051
1051
  parse(input, pos, ctx) {
1052
+ const mark = saveTriviaMark(ctx);
1052
1053
  const result = combinator.parse(input, pos, ctx);
1053
1054
  if (result.ok) return result;
1055
+ rollbackTrivia(ctx, mark);
1054
1056
  return { ok: true, value: null, span: { start: pos, end: pos } };
1055
1057
  }
1056
1058
  };
@@ -1071,7 +1073,7 @@ function sepBy(combinator, separator) {
1071
1073
  const values = [first.value];
1072
1074
  let cur = first.span.end;
1073
1075
  while (cur < input.length) {
1074
- let mark = saveTriviaMark(ctx);
1076
+ const loopMark = saveTriviaMark(ctx);
1075
1077
  let sepPos = cur;
1076
1078
  if (ctx.trivia) {
1077
1079
  if (needsDeferredTriviaCommit(ctx)) {
@@ -1084,10 +1086,9 @@ function sepBy(combinator, separator) {
1084
1086
  }
1085
1087
  const sep = separator.parse(input, sepPos, ctx);
1086
1088
  if (!sep.ok) {
1087
- rollbackTrivia(ctx, mark);
1089
+ rollbackTrivia(ctx, loopMark);
1088
1090
  break;
1089
1091
  }
1090
- mark = saveTriviaMark(ctx);
1091
1092
  let nextPos = sep.span.end;
1092
1093
  if (ctx.trivia) {
1093
1094
  if (needsDeferredTriviaCommit(ctx)) {
@@ -1100,7 +1101,7 @@ function sepBy(combinator, separator) {
1100
1101
  }
1101
1102
  const next = combinator.parse(input, nextPos, ctx);
1102
1103
  if (!next.ok) {
1103
- rollbackTrivia(ctx, mark);
1104
+ rollbackTrivia(ctx, loopMark);
1104
1105
  break;
1105
1106
  }
1106
1107
  values.push(next.value);
@@ -1229,13 +1230,15 @@ function annotateSpan(span, index) {
1229
1230
 
1230
1231
  // src/combinators/grammar.ts
1231
1232
  function parser(opts, root) {
1233
+ const clearTrivia = opts.trivia === null;
1232
1234
  return {
1233
1235
  _tag: "grammar",
1234
1236
  _meta: root._meta,
1235
1237
  _def: {
1236
1238
  tag: "grammar",
1237
1239
  parser: root,
1238
- triviaParser: opts.trivia,
1240
+ triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
1241
+ clearTrivia,
1239
1242
  trackLines: opts.trackLines ?? false
1240
1243
  },
1241
1244
  parse(input, pos, _ctx) {
@@ -1243,7 +1246,11 @@ function parser(opts, root) {
1243
1246
  const ctx = {
1244
1247
  ..._ctx,
1245
1248
  trackLines,
1246
- ...opts.trivia !== void 0 ? {
1249
+ // trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
1250
+ ...clearTrivia ? {
1251
+ trivia: void 0,
1252
+ triviaKindLabels: void 0
1253
+ } : opts.trivia != null ? {
1247
1254
  trivia: opts.trivia,
1248
1255
  ...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
1249
1256
  } : {},
@@ -1258,6 +1265,9 @@ function parser(opts, root) {
1258
1265
  }
1259
1266
  };
1260
1267
  }
1268
+ function noTrivia(root) {
1269
+ return parser({ trivia: null }, root);
1270
+ }
1261
1271
 
1262
1272
  // src/compiler/trivia-fast-path.ts
1263
1273
  var BLOCK_COMMENT = String.raw`\/\*(?:[^*]|\*(?!\/))*\*\/`;
@@ -1580,6 +1590,41 @@ function v(ctx, prefix = "_v") {
1580
1590
  function ind(ctx) {
1581
1591
  return " ".repeat(ctx.indent);
1582
1592
  }
1593
+ function reindentStmts(stmts, targetLevels) {
1594
+ const nonEmpty = stmts.filter((s) => s.trim().length > 0);
1595
+ if (nonEmpty.length === 0) return stmts;
1596
+ const minLeading = Math.min(...nonEmpty.map((s) => s.length - s.trimStart().length));
1597
+ const targetPrefix = " ".repeat(targetLevels);
1598
+ return stmts.map((s) => s.trim().length === 0 ? "" : targetPrefix + s.slice(minLeading));
1599
+ }
1600
+ function failReturn(expected, posExpr) {
1601
+ return `return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
1602
+ }
1603
+ function failReturnArr(expectedArr, posExpr) {
1604
+ return `return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
1605
+ }
1606
+ function failBody(ctx, expected, posExpr) {
1607
+ if (ctx.failLabel) return `break ${ctx.failLabel}`;
1608
+ return failReturn(expected, posExpr);
1609
+ }
1610
+ function failArrBody(ctx, expectedArr, posExpr) {
1611
+ if (ctx.failLabel) return `break ${ctx.failLabel}`;
1612
+ return failReturnArr(expectedArr, posExpr);
1613
+ }
1614
+ function emitIfFail(ctx, cond, body) {
1615
+ return [
1616
+ `${ind(ctx)}if (${cond}) {`,
1617
+ `${ind(ctx)} ${body}`,
1618
+ `${ind(ctx)}}`
1619
+ ];
1620
+ }
1621
+ function emitElseFail(ctx, body) {
1622
+ return [
1623
+ `${ind(ctx)}else {`,
1624
+ `${ind(ctx)} ${body}`,
1625
+ `${ind(ctx)}}`
1626
+ ];
1627
+ }
1583
1628
  var NAMED_FN_FAIL = "_pfFail";
1584
1629
  var NAMED_FN_END = "_pfEnd";
1585
1630
  function namedFnPrelude() {
@@ -1590,8 +1635,10 @@ function pushNamedFnDecl(ctx, fnName, bodyStmts, valueVar, endVar) {
1590
1635
  `function ${fnName}(input, _pos, _ctx) {`,
1591
1636
  ` let _pfok = false, _pfv, _pfe = _pos`,
1592
1637
  ` _pfail: {`,
1593
- ...bodyStmts,
1594
- ` _pfv = ${valueVar}; _pfe = ${endVar}; _pfok = true`,
1638
+ ...reindentStmts(bodyStmts, 2),
1639
+ ` _pfv = ${valueVar}`,
1640
+ ` _pfe = ${endVar}`,
1641
+ ` _pfok = true`,
1595
1642
  ` }`,
1596
1643
  ` if (!_pfok) return ${NAMED_FN_FAIL}`,
1597
1644
  ` ${NAMED_FN_END} = _pfe`,
@@ -1605,7 +1652,7 @@ function emitNamedFnCall(ctx, fnName, pos, failExpected) {
1605
1652
  return {
1606
1653
  stmts: [
1607
1654
  `${ind(ctx)}const ${vv} = ${fnName}(input, ${pos}, _ctx)`,
1608
- `${ind(ctx)}if (${vv} === ${NAMED_FN_FAIL}) ${failStmt({ ...ctx, indent: 0 }, failExpected, pos).trim()}`,
1655
+ ...emitIfFail(ctx, `${vv} === ${NAMED_FN_FAIL}`, failBody(ctx, failExpected, pos)),
1609
1656
  `${ind(ctx)}const ${ev} = ${NAMED_FN_END}`
1610
1657
  ],
1611
1658
  valueVar: vv,
@@ -1688,7 +1735,7 @@ function ensureTriviaFn(ctx) {
1688
1735
  `function ${fnName}(input, _pos, _ctx, _cap) {`,
1689
1736
  ` let _e = _pos`,
1690
1737
  ` _triv: {`,
1691
- ...r.stmts,
1738
+ ...reindentStmts(r.stmts, 2),
1692
1739
  ` _e = ${r.endVar}`,
1693
1740
  ` }`,
1694
1741
  ` if (_cap && _e > _pos) {`,
@@ -1703,14 +1750,6 @@ function ensureTriviaFn(ctx) {
1703
1750
  function ensureTriviaCaptureFn(ctx) {
1704
1751
  return ensureTriviaFn(ctx);
1705
1752
  }
1706
- function failStmt(ctx, expected, posExpr) {
1707
- if (ctx.failLabel) return `${ind(ctx)}break ${ctx.failLabel}`;
1708
- return `${ind(ctx)}return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
1709
- }
1710
- function failArr(ctx, expectedArr, posExpr) {
1711
- if (ctx.failLabel) return `${ind(ctx)}break ${ctx.failLabel}`;
1712
- return `${ind(ctx)}return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
1713
- }
1714
1753
  function firstSetCond(codeVar, fs) {
1715
1754
  if (fs.kind === "any") return "true";
1716
1755
  if (fs.kind === "empty") return "false";
@@ -1726,19 +1765,32 @@ function emitFallible(inner, ctx, pos) {
1726
1765
  const savedLabel = ctx.failLabel;
1727
1766
  const savedIndent = ctx.indent;
1728
1767
  ctx.failLabel = lbl;
1729
- ctx.indent = 0;
1768
+ ctx.indent = savedIndent + 1;
1730
1769
  const r = emit(inner, ctx, pos);
1731
1770
  ctx.failLabel = savedLabel;
1732
1771
  ctx.indent = savedIndent;
1733
1772
  const ind0 = ind(ctx);
1773
+ const mL = ctx.capturing ? v(ctx, "_fcl") : null;
1774
+ const mR = ctx.capturing ? v(ctx, "_fcr") : null;
1775
+ const mTl = ctx.capturing ? v(ctx, "_fctl") : null;
1776
+ const mLg = ctx.capturing ? v(ctx, "_fclg") : null;
1734
1777
  const stmts = [
1735
1778
  `${ind0}let ${okV} = false, ${valV}, ${endV} = ${pos}`,
1779
+ ...mL ? [
1780
+ `${ind0}const ${mL} = _ctx._cstLeaves?.length ?? 0`,
1781
+ `${ind0}const ${mR} = _ctx._cstRawChildren?.length ?? 0`,
1782
+ `${ind0}const ${mTl} = _ctx._cstTriviaLog?.length ?? 0`,
1783
+ `${ind0}const ${mLg} = _ctx._triviaLog?.length ?? 0`
1784
+ ] : [],
1736
1785
  `${ind0}${lbl}: {`,
1737
1786
  ...r.stmts,
1738
1787
  `${ind0} ${valV} = ${r.valueVar}`,
1739
1788
  `${ind0} ${endV} = ${r.endVar}`,
1740
1789
  `${ind0} ${okV} = true`,
1741
- `${ind0}}`
1790
+ `${ind0}}`,
1791
+ ...mL ? [
1792
+ `${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} }`
1793
+ ] : []
1742
1794
  ];
1743
1795
  return { stmts, okVar: okV, valVar: valV, endVar: endV };
1744
1796
  }
@@ -1751,9 +1803,9 @@ function emitLit(def, ctx, pos) {
1751
1803
  if (caseInsensitive) {
1752
1804
  ctx.needsCollator = true;
1753
1805
  stmts.push(
1754
- `${ind(ctx)}if (${pos} + ${len} > input.length) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
1806
+ ...emitIfFail(ctx, `${pos} + ${len} > input.length`, failBody(ctx, expectedStr, pos)),
1755
1807
  `${ind(ctx)}const ${vv}_s = input.slice(${pos}, ${pos} + ${len})`,
1756
- `${ind(ctx)}if (_collator.compare(${vv}_s, ${JSON.stringify(value)}) !== 0) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
1808
+ ...emitIfFail(ctx, `_collator.compare(${vv}_s, ${JSON.stringify(value)}) !== 0`, failBody(ctx, expectedStr, pos)),
1757
1809
  `${ind(ctx)}const ${vv} = ${vv}_s`
1758
1810
  );
1759
1811
  } else if (len === 0) {
@@ -1761,7 +1813,7 @@ function emitLit(def, ctx, pos) {
1761
1813
  } else if (len === 1) {
1762
1814
  const code = value.codePointAt(0);
1763
1815
  stmts.push(
1764
- `${ind(ctx)}if (${pos} >= input.length || input.charCodeAt(${pos}) !== ${code}) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
1816
+ ...emitIfFail(ctx, `${pos} >= input.length || input.charCodeAt(${pos}) !== ${code}`, failBody(ctx, expectedStr, pos)),
1765
1817
  `${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
1766
1818
  );
1767
1819
  } else if (len <= 4) {
@@ -1770,12 +1822,12 @@ function emitLit(def, ctx, pos) {
1770
1822
  (_, i) => `input.charCodeAt(${pos}${i > 0 ? ` + ${i}` : ""}) !== ${value.codePointAt(i)}`
1771
1823
  ).join(" || ");
1772
1824
  stmts.push(
1773
- `${ind(ctx)}if (${pos} + ${len} > input.length || ${checks}) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
1825
+ ...emitIfFail(ctx, `${pos} + ${len} > input.length || ${checks}`, failBody(ctx, expectedStr, pos)),
1774
1826
  `${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
1775
1827
  );
1776
1828
  } else {
1777
1829
  stmts.push(
1778
- `${ind(ctx)}if (!input.startsWith(${JSON.stringify(value)}, ${pos})) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
1830
+ ...emitIfFail(ctx, `!input.startsWith(${JSON.stringify(value)}, ${pos})`, failBody(ctx, expectedStr, pos)),
1779
1831
  `${ind(ctx)}const ${vv} = ${JSON.stringify(value)}`
1780
1832
  );
1781
1833
  }
@@ -1803,7 +1855,7 @@ function emitKeywords(def, ctx, pos) {
1803
1855
  const stmts = [
1804
1856
  `${ind(ctx)}${rName}.lastIndex = ${pos}`,
1805
1857
  `${ind(ctx)}const ${mv} = ${rName}.exec(input)`,
1806
- `${ind(ctx)}if (${mv} === null) ${failStmt({ ...ctx, indent: 0 }, '"keyword"', pos).trim()}`,
1858
+ ...emitIfFail(ctx, `${mv} === null`, failBody(ctx, '"keyword"', pos)),
1807
1859
  `${ind(ctx)}const ${vv} = ${mv}[0]`
1808
1860
  ];
1809
1861
  const endVar = `${pos} + ${vv}.length`;
@@ -1825,7 +1877,7 @@ function emitRegex(def, ctx, pos) {
1825
1877
  const stmts = [
1826
1878
  `${ind(ctx)}${rName}.lastIndex = ${pos}`,
1827
1879
  `${ind(ctx)}const ${mv} = ${rName}.exec(input)`,
1828
- `${ind(ctx)}if (${mv} === null) ${failStmt({ ...ctx, indent: 0 }, expectedStr, pos).trim()}`,
1880
+ ...emitIfFail(ctx, `${mv} === null`, failBody(ctx, expectedStr, pos)),
1829
1881
  `${ind(ctx)}const ${vv} = ${mv}[0]`
1830
1882
  ];
1831
1883
  const endVar = `${pos} + ${vv}.length`;
@@ -1906,11 +1958,12 @@ function emitChoice(def, ctx, pos) {
1906
1958
  ctx.indent++;
1907
1959
  const r = emit(p, ctx, pos);
1908
1960
  stmts.push(...r.stmts);
1909
- stmts.push(`${ind(ctx)}${valV} = ${r.valueVar}; ${endV} = ${r.endVar}`);
1961
+ stmts.push(`${ind(ctx)}${valV} = ${r.valueVar}`);
1962
+ stmts.push(`${ind(ctx)}${endV} = ${r.endVar}`);
1910
1963
  ctx.indent--;
1911
1964
  stmts.push(`${ind(ctx)}}`);
1912
1965
  }
1913
- stmts.push(`${ind(ctx)}else ${failArr({ ...ctx, indent: 0 }, allExpected, pos)}`);
1966
+ stmts.push(...emitElseFail(ctx, failArrBody(ctx, allExpected, pos)));
1914
1967
  return { stmts, valueVar: valV, endVar: endV };
1915
1968
  }
1916
1969
  return emitNonDisjoint(def, def.strategy, allExpected, ctx, pos);
@@ -1933,7 +1986,7 @@ function emitGreedyClassify(def, superIndex, allExpected, ctx, pos) {
1933
1986
  const stmts = [
1934
1987
  `${ind(ctx)}${reVar}.lastIndex = ${pos}`,
1935
1988
  `${ind(ctx)}const ${matchV} = ${reVar}.exec(input)`,
1936
- `${ind(ctx)}if (${matchV} === null) ${failArr({ ...ctx, indent: 0 }, allExpected, pos)}`,
1989
+ ...emitIfFail(ctx, `${matchV} === null`, failArrBody(ctx, allExpected, pos)),
1937
1990
  `${ind(ctx)}const ${wordV} = ${matchV}[0]`,
1938
1991
  `${ind(ctx)}const ${endV} = ${pos} + ${wordV}.length`,
1939
1992
  `${ind(ctx)}let ${valV}`
@@ -1982,12 +2035,13 @@ function emitLiteralsLongestFirst(def, sortedIndices, allExpected, ctx, pos) {
1982
2035
  stmts.push(
1983
2036
  ...emitLeafCapture(ctx, JSON.stringify(litVal), pos, litEnd),
1984
2037
  ...tR.stmts,
1985
- `${ind(ctx)}${valV} = ${tR.valueVar}; ${endV} = ${litEnd}`
2038
+ `${ind(ctx)}${valV} = ${tR.valueVar}`,
2039
+ `${ind(ctx)}${endV} = ${litEnd}`
1986
2040
  );
1987
2041
  ctx.indent--;
1988
2042
  stmts.push(`${ind(ctx)}}`);
1989
2043
  }
1990
- stmts.push(`${ind(ctx)}else ${failArr({ ...ctx, indent: 0 }, allExpected, pos)}`);
2044
+ stmts.push(...emitElseFail(ctx, failArrBody(ctx, allExpected, pos)));
1991
2045
  return { stmts, valueVar: valV, endVar: endV };
1992
2046
  }
1993
2047
  function emitFirstMatch(def, allExpected, ctx, pos) {
@@ -2033,17 +2087,26 @@ function emitFirstMatch(def, allExpected, ctx, pos) {
2033
2087
  const rejectCond = autoNot.map(
2034
2088
  (check) => check.kind === "firstSet" ? firstSetCond(anCode, check.set) : `input.startsWith(${JSON.stringify(check.value)}, ${endVar})`
2035
2089
  ).join(" || ");
2036
- stmts.push(
2037
- `${ind0} if (${okVar}) { const ${anCode} = ${endVar} < input.length ? input.charCodeAt(${endVar}) : -1; if (!(${rejectCond})) { ${resValV} = ${valVar}; ${resEndV} = ${endVar}; ${resOkV} = true } }`
2038
- );
2090
+ stmts.push(`${ind0} if (${okVar}) {`);
2091
+ stmts.push(`${ind0} const ${anCode} = ${endVar} < input.length ? input.charCodeAt(${endVar}) : -1`);
2092
+ stmts.push(`${ind0} if (!(${rejectCond})) {`);
2093
+ stmts.push(`${ind0} ${resValV} = ${valVar}`);
2094
+ stmts.push(`${ind0} ${resEndV} = ${endVar}`);
2095
+ stmts.push(`${ind0} ${resOkV} = true`);
2096
+ stmts.push(`${ind0} }`);
2097
+ stmts.push(`${ind0} }`);
2039
2098
  if (rollback) stmts.push(`${ind0} if (!${resOkV}) { ${rollback} }`);
2040
2099
  } else {
2041
- stmts.push(`${ind0} if (${okVar}) { ${resValV} = ${valVar}; ${resEndV} = ${endVar}; ${resOkV} = true }`);
2100
+ stmts.push(`${ind0} if (${okVar}) {`);
2101
+ stmts.push(`${ind0} ${resValV} = ${valVar}`);
2102
+ stmts.push(`${ind0} ${resEndV} = ${endVar}`);
2103
+ stmts.push(`${ind0} ${resOkV} = true`);
2104
+ stmts.push(`${ind0} }`);
2042
2105
  if (rollback) stmts.push(`${ind0} else { ${rollback} }`);
2043
2106
  }
2044
2107
  stmts.push(`${ind0}}`);
2045
2108
  }
2046
- stmts.push(`${ind0}if (!${resOkV}) ${failArr({ ...ctx, indent: 0 }, allExpected, pos)}`);
2109
+ stmts.push(...emitIfFail(ctx, `!${resOkV}`, failArrBody(ctx, allExpected, pos)));
2047
2110
  return { stmts, valueVar: resValV, endVar: resEndV };
2048
2111
  }
2049
2112
  function emitNonDisjoint(def, strategy, allExpected, ctx, pos) {
@@ -2168,32 +2231,26 @@ function emitSepBy(_p, def, ctx, pos) {
2168
2231
  const markV = v(ctx, "_mk");
2169
2232
  const markTl = v(ctx, "_mktl");
2170
2233
  const markLog = v(ctx, "_mklg");
2234
+ const markLv = v(ctx, "_mklv");
2171
2235
  const spV = v(ctx, "_sp");
2172
2236
  stmts.push(
2173
2237
  `${ind(ctx)}const ${markV} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
2174
2238
  `${ind(ctx)}const ${markTl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
2175
2239
  `${ind(ctx)}const ${markLog} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
2240
+ `${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
2176
2241
  `${ind(ctx)}const ${spV} = ${capFn}(input, ${curV}, _ctx, 1)`
2177
2242
  );
2178
2243
  sepAtPos = spV;
2179
- const sepRollback = `if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${markV}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${markTl}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${markLog}; `;
2244
+ 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}; `;
2180
2245
  const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos);
2181
- stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${sepRollback}break }`);
2182
- const mark2V = v(ctx, "_mk2");
2183
- const mark2Tl = v(ctx, "_mktl2");
2184
- const mark2Log = v(ctx, "_mklg2");
2246
+ stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) { ${rollbackToSep}break }`);
2185
2247
  const npV = v(ctx, "_np");
2186
- stmts.push(
2187
- `${ind(ctx)}const ${mark2V} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`,
2188
- `${ind(ctx)}const ${mark2Tl} = _ctx._cstTriviaLog ? _ctx._cstTriviaLog.length : 0`,
2189
- `${ind(ctx)}const ${mark2Log} = _ctx._triviaLog ? _ctx._triviaLog.length : 0`,
2190
- `${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`
2191
- );
2192
- const nextRollback = `if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${mark2V}; if (_ctx._cstTriviaLog) _ctx._cstTriviaLog.length = ${mark2Tl}; if (_ctx._triviaLog) _ctx._triviaLog.length = ${mark2Log}; `;
2248
+ stmts.push(`${ind(ctx)}const ${npV} = ${capFn}(input, ${sepEnd}, _ctx, 1)`);
2193
2249
  const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, npV);
2194
2250
  stmts.push(
2195
2251
  ...nextStmts,
2196
- `${ind(ctx)}if (!${nextOk}) { ${nextRollback}break }`,
2252
+ // item failed → unwind the separator too, back to the end of the last item
2253
+ `${ind(ctx)}if (!${nextOk}) { ${rollbackToSep}break }`,
2197
2254
  `${ind(ctx)}${arrV}.push(${nextVal})`,
2198
2255
  `${ind(ctx)}${curV} = ${nextEnd}`
2199
2256
  );
@@ -2215,12 +2272,21 @@ function emitSepBy(_p, def, ctx, pos) {
2215
2272
  );
2216
2273
  }
2217
2274
  } else {
2275
+ const markLv = ctx.capturing ? v(ctx, "_mklv") : null;
2276
+ const markRw = ctx.capturing ? v(ctx, "_mkrw") : null;
2277
+ if (markLv) {
2278
+ stmts.push(
2279
+ `${ind(ctx)}const ${markLv} = _ctx._cstLeaves ? _ctx._cstLeaves.length : 0`,
2280
+ `${ind(ctx)}const ${markRw} = _ctx._cstRawChildren ? _ctx._cstRawChildren.length : 0`
2281
+ );
2282
+ }
2218
2283
  const { stmts: sepStmts, okVar: sepOk, endVar: sepEnd } = emitFallible(def.separator, ctx, sepAtPos);
2219
2284
  stmts.push(...sepStmts, `${ind(ctx)}if (!${sepOk}) break`);
2285
+ const nextRb = markLv ? `if (_ctx._cstLeaves) _ctx._cstLeaves.length = ${markLv}; if (_ctx._cstRawChildren) _ctx._cstRawChildren.length = ${markRw}; ` : "";
2220
2286
  const { stmts: nextStmts, okVar: nextOk, valVar: nextVal, endVar: nextEnd } = emitFallible(def.parser, ctx, sepEnd);
2221
2287
  stmts.push(
2222
2288
  ...nextStmts,
2223
- `${ind(ctx)}if (!${nextOk}) break`,
2289
+ `${ind(ctx)}if (!${nextOk}) { ${nextRb}break }`,
2224
2290
  `${ind(ctx)}${arrV}.push(${nextVal})`,
2225
2291
  `${ind(ctx)}${curV} = ${nextEnd}`
2226
2292
  );
@@ -2264,12 +2330,12 @@ function emitScanTo(def, ctx, pos) {
2264
2330
  if (!def.orEOF) {
2265
2331
  const sentDef = def.sentinel._def;
2266
2332
  const expectedStr = sentDef.tag === "literal" ? JSON.stringify([JSON.stringify(sentDef.value)]) : `["sentinel"]`;
2267
- stmts.push(`${ind(ctx)}if (!${foundV}) ${failArr({ ...ctx, indent: 0 }, expectedStr, pos)}`);
2333
+ stmts.push(...emitIfFail(ctx, `!${foundV}`, failArrBody(ctx, expectedStr, pos)));
2268
2334
  }
2269
2335
  const valV = v(ctx);
2270
2336
  stmts.push(`${ind(ctx)}const ${valV} = input.slice(${pos}, ${curV})`);
2271
2337
  if (ctx.capturing) {
2272
- const cap = emitLeafCapture(ctx, valV, pos, curV).map((s) => " " + s);
2338
+ const cap = reindentStmts(emitLeafCapture(ctx, valV, pos, curV), ctx.indent + 1);
2273
2339
  stmts.push(`${ind(ctx)}if (${curV} > ${pos}) {`, ...cap, `${ind(ctx)}}`);
2274
2340
  }
2275
2341
  return { stmts, valueVar: valV, endVar: curV };
@@ -2279,7 +2345,7 @@ function emitNot(def, ctx, pos) {
2279
2345
  return {
2280
2346
  stmts: [
2281
2347
  ...stmts,
2282
- `${ind(ctx)}if (${okVar}) ${failStmt({ ...ctx, indent: 0 }, '"not"', pos).trim()}`
2348
+ ...emitIfFail(ctx, okVar, failBody(ctx, '"not"', pos))
2283
2349
  ],
2284
2350
  valueVar: "null",
2285
2351
  endVar: pos
@@ -2306,7 +2372,7 @@ function emitNode(def, ctx, pos) {
2306
2372
  const { stmts: innerStmts, okVar, endVar } = emitFallible(def.parser, ctx, pos);
2307
2373
  stmts.push(...innerStmts);
2308
2374
  stmts.push(`${i}_ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx.captureTrivia = ${st}; _ctx._cstTriviaLog = ${stl}`);
2309
- stmts.push(`${i}if (!${okVar}) ${failStmt({ ...ctx, indent: 0 }, '"node"', pos).trim()}`);
2375
+ stmts.push(...emitIfFail(ctx, `!${okVar}`, failBody(ctx, '"node"', pos)));
2310
2376
  const stV = v(ctx, "_nst");
2311
2377
  stmts.push(`${i}const ${stV} = _ctx.state !== undefined ? Object.assign({}, _ctx.state) : undefined`);
2312
2378
  const ndV = v(ctx, "_nd");
@@ -2326,7 +2392,7 @@ function emitRuntimeFallback(parser2, ctx, pos) {
2326
2392
  const ev = v(ctx, "_rte");
2327
2393
  const stmts = [
2328
2394
  `${ind(ctx)}const ${rv} = _rp[${idx}].parse(input, ${pos}, _ctx)`,
2329
- `${ind(ctx)}if (!${rv}.ok) ${failStmt({ ...ctx, indent: 0 }, '"runtime"', pos).trim()}`,
2395
+ ...emitIfFail(ctx, `!${rv}.ok`, failBody(ctx, '"runtime"', pos)),
2330
2396
  `${ind(ctx)}const ${vv} = ${rv}.value`,
2331
2397
  `${ind(ctx)}const ${ev} = ${rv}.span.end`
2332
2398
  ];
@@ -2360,16 +2426,14 @@ function emitRecover(def, ctx, pos) {
2360
2426
  const ind0 = ind(ctx);
2361
2427
  const scanV = v(ctx, "_sc");
2362
2428
  const errV = v(ctx, "_err");
2363
- const savedIndent = ctx.indent;
2364
- ctx.indent += 2;
2429
+ const whileBodyLevels = ctx.indent + 2;
2365
2430
  const { stmts: sentStmts, okVar: sentOk } = emitFallible(def.sentinel, ctx, scanV);
2366
- ctx.indent = savedIndent;
2367
2431
  const stmts = [
2368
2432
  ...innerStmts,
2369
2433
  `${ind0}if (!${okVar}) {`,
2370
2434
  `${ind0} let ${scanV} = ${pos}`,
2371
2435
  `${ind0} while (${scanV} < input.length) {`,
2372
- ...sentStmts,
2436
+ ...reindentStmts(sentStmts, whileBodyLevels),
2373
2437
  `${ind0} if (${sentOk}) break`,
2374
2438
  `${ind0} ${scanV}++`,
2375
2439
  `${ind0} }`,
@@ -2451,7 +2515,7 @@ function emit(p, ctx, pos) {
2451
2515
  // try skipped; if fails, keep main end
2452
2516
  `${ind(ctx)}let ${endV} = ${mainR.endVar}`,
2453
2517
  `${ind(ctx)}try {`,
2454
- ...skipR.stmts.map((s) => " " + s),
2518
+ ...reindentStmts(skipR.stmts, ctx.indent + 1),
2455
2519
  `${ind(ctx)} ${endV} = ${skipR.endVar}`,
2456
2520
  `${ind(ctx)}} catch {}`
2457
2521
  ],
@@ -2468,7 +2532,10 @@ function emit(p, ctx, pos) {
2468
2532
  case "grammar": {
2469
2533
  const savedTrivia = ctx.activeTrivia;
2470
2534
  const savedKindLabels = ctx.triviaKindLabels;
2471
- if (def.triviaParser) {
2535
+ if (def.clearTrivia) {
2536
+ ctx.activeTrivia = void 0;
2537
+ ctx.triviaKindLabels = void 0;
2538
+ } else if (def.triviaParser) {
2472
2539
  ctx.activeTrivia = def.triviaParser;
2473
2540
  if (def.triviaParser._meta.triviaKindLabels) {
2474
2541
  ctx.triviaKindLabels = def.triviaParser._meta.triviaKindLabels;
@@ -2493,7 +2560,7 @@ function emit(p, ctx, pos) {
2493
2560
  const vv = v(ctx);
2494
2561
  return {
2495
2562
  stmts: [
2496
- `${ind(ctx)}if (!_mf[${fnIdx}](_ctx.state)) ${failStmt({ ...ctx, indent: 0 }, '"gate"', pos).trim()}`,
2563
+ ...emitIfFail(ctx, `!_mf[${fnIdx}](_ctx.state)`, failBody(ctx, '"gate"', pos)),
2497
2564
  `${ind(ctx)}const ${vv} = null`
2498
2565
  ],
2499
2566
  valueVar: vv,
@@ -2525,7 +2592,7 @@ function emit(p, ctx, pos) {
2525
2592
  stmts: [
2526
2593
  `${ind(ctx)}const ${rv} = { ..._ctx, state: _mf[${evIdx}]() }`,
2527
2594
  `${ind(ctx)}const ${vv} = ${fn}(input, ${pos}, ${rv})`,
2528
- `${ind(ctx)}if (${vv} === ${NAMED_FN_FAIL}) ${failStmt({ ...ctx, indent: 0 }, '"withCtx"', pos).trim()}`,
2595
+ ...emitIfFail(ctx, `${vv} === ${NAMED_FN_FAIL}`, failBody(ctx, '"withCtx"', pos)),
2529
2596
  `${ind(ctx)}const ${ev} = ${NAMED_FN_END}`
2530
2597
  ],
2531
2598
  valueVar: vv,
@@ -2602,7 +2669,7 @@ function compile(combinator, mapFnSources) {
2602
2669
  ...ctx.regexDecls,
2603
2670
  "",
2604
2671
  ...namedPrelude,
2605
- ...ctx.namedFnDecls,
2672
+ ctx.namedFnDecls.join("\n\n"),
2606
2673
  `${collatorDecl}function _parse(input, _pos, _rp, _mf, _build, _ctx) {`,
2607
2674
  ` let pos = _pos`,
2608
2675
  ...r.stmts,
@@ -2613,7 +2680,7 @@ function compile(combinator, mapFnSources) {
2613
2680
  ...ctx.regexDecls,
2614
2681
  collatorDecl,
2615
2682
  ...namedPrelude,
2616
- ...ctx.namedFnDecls,
2683
+ ...ctx.namedFnDecls.flatMap((decl, i) => i > 0 ? ["", decl] : [decl]),
2617
2684
  `let pos = _pos`,
2618
2685
  ...r.stmts,
2619
2686
  `return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`
@@ -2648,7 +2715,7 @@ function compile(combinator, mapFnSources) {
2648
2715
  function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources) {
2649
2716
  const bodyLines = [
2650
2717
  ` let pos = _pos`,
2651
- ...r.stmts.map((s) => ` ${s}`),
2718
+ ...r.stmts,
2652
2719
  ` return { ok: true, value: ${r.valueVar}, span: { start: _pos, end: ${r.endVar} } }`
2653
2720
  ];
2654
2721
  const innerFn = [
@@ -2661,17 +2728,23 @@ function buildInlineExpression(ctx, r, collatorDecl, mapFnSources, buildSources)
2661
2728
  const needsWrapper = ctx.regexDecls.length > 0 || !!collatorDecl || ctx.namedFnDecls.length > 0 || !!mfDecl || !!buildDecl;
2662
2729
  if (!needsWrapper) return innerFn;
2663
2730
  const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
2664
- return [
2665
- `/* @__PURE__ */ (() => {`,
2731
+ const hoistedDecls = [
2666
2732
  ...ctx.regexDecls.map((d) => ` ${d}`),
2667
2733
  collatorDecl ? ` ${collatorDecl.trim()}` : "",
2668
2734
  mfDecl,
2669
2735
  buildDecl,
2670
2736
  ...namedPrelude.map((l) => ` ${l}`),
2671
- ...ctx.namedFnDecls.flatMap((f) => f.split("\n").map((l) => ` ${l}`)),
2737
+ ...ctx.namedFnDecls.flatMap((decl, i) => {
2738
+ const lines = decl.split("\n").map((l) => ` ${l}`);
2739
+ return i > 0 ? ["", ...lines] : lines;
2740
+ })
2741
+ ].filter(Boolean);
2742
+ return [
2743
+ `/* @__PURE__ */ (() => {`,
2744
+ ...hoistedDecls,
2672
2745
  ` return ${innerFn}`,
2673
2746
  `})()`
2674
- ].filter(Boolean).join("\n");
2747
+ ].join("\n");
2675
2748
  }
2676
2749
 
2677
2750
  // src/combinators/scanTo.ts
@@ -2749,7 +2822,8 @@ var SUPPORTED = {
2749
2822
  optional: (...a) => optional(a[0]),
2750
2823
  sepBy: (...a) => sepBy(a[0], a[1]),
2751
2824
  trivia: (...a) => trivia(a[0]),
2752
- label: (...a) => label(a[0], a[1])
2825
+ label: (...a) => label(a[0], a[1]),
2826
+ noTrivia: (...a) => noTrivia(a[0])
2753
2827
  };
2754
2828
  function isScopeEntry(v2) {
2755
2829
  return !!v2 && typeof v2 === "object" && "combi" in v2 && "mfSrcs" in v2;
@@ -3205,7 +3279,9 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
3205
3279
  replacements.push({
3206
3280
  start: init.start,
3207
3281
  end: init.end,
3208
- replacement: `{ ${compiledRules.entries.map(([k, expr]) => `${k}: ${expr}`).join(", ")} }`
3282
+ replacement: `{
3283
+ ${compiledRules.entries.map(([k, expr]) => ` ${k}: ${expr}`).join(",\n")}
3284
+ }`
3209
3285
  });
3210
3286
  continue;
3211
3287
  }