parseman 0.17.0 → 0.18.1

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;AA2VhE,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;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAM9B;AAiED;;;;;;;;;;;;;;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,CAiGzC;AAED,oEAAoE;AACpE,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG;IAAE,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,CAAA;AAQlF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,GACX,YAAY,GAAG,IAAI,CAQrB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAoBT;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;AA4VhE,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;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAM9B;AAiED;;;;;;;;;;;;;;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,CAiGzC;AAED,oEAAoE;AACpE,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG;IAAE,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;CAAE,CAAA;AAQlF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,GACX,YAAY,GAAG,IAAI,CAQrB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAoBT;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAcnF"}
@@ -100,6 +100,7 @@ function matchesEmpty(p, seen = /* @__PURE__ */ new Set()) {
100
100
  case "transform":
101
101
  case "label":
102
102
  case "trivia":
103
+ case "token":
103
104
  case "expect":
104
105
  case "withCtx":
105
106
  case "node":
@@ -162,6 +163,7 @@ function firstSetOf(p, seen = /* @__PURE__ */ new Set()) {
162
163
  case "transform":
163
164
  case "label":
164
165
  case "trivia":
166
+ case "token":
165
167
  case "node":
166
168
  case "grammar":
167
169
  case "expect":
@@ -1285,6 +1287,7 @@ function markUnusedValues(root) {
1285
1287
  return;
1286
1288
  case "label":
1287
1289
  case "trivia":
1290
+ case "token":
1288
1291
  case "withCtx":
1289
1292
  case "expect":
1290
1293
  visit(def.parser, consumed);
@@ -1486,7 +1489,11 @@ function label(name, combinator) {
1486
1489
  _tag: combinator._tag,
1487
1490
  _meta: combinator._meta,
1488
1491
  _def: { tag: "label", label: name, parser: combinator },
1489
- parse: combinator.parse.bind(combinator)
1492
+ parse(input, pos, ctx) {
1493
+ const result = combinator.parse(input, pos, ctx);
1494
+ if (!result.ok) return { ...result, expected: [name] };
1495
+ return result;
1496
+ }
1490
1497
  };
1491
1498
  }
1492
1499
 
@@ -1562,8 +1569,60 @@ function noTrivia(root) {
1562
1569
  return parser({ trivia: null }, root);
1563
1570
  }
1564
1571
 
1572
+ // src/combinators/token.ts
1573
+ function token(root) {
1574
+ const meta = {
1575
+ firstSet: root._meta.firstSet,
1576
+ canMatchNewline: root._meta.canMatchNewline,
1577
+ isTrivia: false
1578
+ };
1579
+ return {
1580
+ _tag: "token",
1581
+ _meta: meta,
1582
+ _def: { tag: "token", parser: root },
1583
+ parse(input, pos, ctx) {
1584
+ const savedTrivia = ctx.trivia;
1585
+ const savedKinds = ctx.triviaKindLabels;
1586
+ const savedBuf = ctx._cstBuf;
1587
+ const savedChildren = ctx._cstChildren;
1588
+ const savedLeaves = ctx._cstLeaves;
1589
+ const savedRaw = ctx._cstRawChildren;
1590
+ const savedTriviaLog = ctx._cstTriviaLog;
1591
+ const savedOuterTriviaLog = ctx._triviaLog;
1592
+ const wasCapturing = cstCaptureActive(ctx);
1593
+ ctx.trivia = void 0;
1594
+ ctx.triviaKindLabels = void 0;
1595
+ ctx._cstBuf = void 0;
1596
+ ctx._cstChildren = void 0;
1597
+ ctx._cstLeaves = void 0;
1598
+ ctx._cstRawChildren = void 0;
1599
+ ctx._cstTriviaLog = void 0;
1600
+ delete ctx._triviaLog;
1601
+ let result;
1602
+ try {
1603
+ result = root.parse(input, pos, ctx);
1604
+ } finally {
1605
+ ctx.trivia = savedTrivia;
1606
+ ctx.triviaKindLabels = savedKinds;
1607
+ ctx._cstBuf = savedBuf;
1608
+ ctx._cstChildren = savedChildren;
1609
+ ctx._cstLeaves = savedLeaves;
1610
+ ctx._cstRawChildren = savedRaw;
1611
+ ctx._cstTriviaLog = savedTriviaLog;
1612
+ if (savedOuterTriviaLog === void 0) delete ctx._triviaLog;
1613
+ else ctx._triviaLog = savedOuterTriviaLog;
1614
+ }
1615
+ if (!result.ok) return result;
1616
+ const span = result.span;
1617
+ const value = input.slice(pos, span.end);
1618
+ if (wasCapturing) pushCstLeaf(ctx, { _tag: "leaf", value, span });
1619
+ return { ok: true, value, span };
1620
+ }
1621
+ };
1622
+ }
1623
+
1565
1624
  // src/combinators/expect.ts
1566
- function staticExpected(c) {
1625
+ function deriveExpected(c) {
1567
1626
  const def = c._def;
1568
1627
  switch (def.tag) {
1569
1628
  case "literal":
@@ -1575,22 +1634,23 @@ function staticExpected(c) {
1575
1634
  case "label":
1576
1635
  return [def.label];
1577
1636
  case "choice":
1578
- return def.parsers.flatMap(staticExpected);
1637
+ return def.parsers.flatMap(deriveExpected);
1579
1638
  case "sequence":
1580
- return def.parsers.length > 0 ? staticExpected(def.parsers[0]) : [];
1639
+ return def.parsers.length > 0 ? deriveExpected(def.parsers[0]) : [];
1581
1640
  case "node":
1582
1641
  case "grammar":
1583
1642
  case "trivia":
1643
+ case "token":
1584
1644
  case "optional":
1585
1645
  case "many":
1586
1646
  case "oneOrMore":
1587
1647
  case "transform":
1588
1648
  case "not":
1589
- return staticExpected(def.parser);
1649
+ return deriveExpected(def.parser);
1590
1650
  case "lazy": {
1591
1651
  const name = c._ruleName;
1592
1652
  try {
1593
- return staticExpected(def.thunk());
1653
+ return deriveExpected(def.thunk());
1594
1654
  } catch {
1595
1655
  return name ? [name] : [];
1596
1656
  }
@@ -1600,7 +1660,7 @@ function staticExpected(c) {
1600
1660
  }
1601
1661
  }
1602
1662
  function expect(combinator, label2) {
1603
- const expected = label2 !== void 0 ? [label2] : staticExpected(combinator);
1663
+ const expected = label2 !== void 0 ? [label2] : deriveExpected(combinator);
1604
1664
  const meta = {
1605
1665
  firstSet: combinator._meta.firstSet,
1606
1666
  canMatchNewline: combinator._meta.canMatchNewline,
@@ -3260,6 +3320,7 @@ function mayLeavePartialCapture(p, seen = /* @__PURE__ */ new Set()) {
3260
3320
  case "guard":
3261
3321
  case "not":
3262
3322
  case "trivia":
3323
+ case "token":
3263
3324
  case "scanTo":
3264
3325
  case "unknown":
3265
3326
  return false;
@@ -3321,6 +3382,7 @@ function capturesLeaf(p, seen = /* @__PURE__ */ new Set()) {
3321
3382
  case "regex":
3322
3383
  case "keywords":
3323
3384
  case "node":
3385
+ case "token":
3324
3386
  return true;
3325
3387
  case "not":
3326
3388
  case "guard":
@@ -3599,9 +3661,9 @@ function emitSeq(def, ctx, pos) {
3599
3661
  stmts.push(`${ind(ctx)}const ${arrV} = [${valueVars.join(", ")}]`);
3600
3662
  return { stmts, valueVar: arrV, endVar };
3601
3663
  }
3602
- function staticExpectedArr(parsers) {
3664
+ function deriveExpectedArr(parsers) {
3603
3665
  return JSON.stringify(parsers.flatMap((p) => {
3604
- const e = staticExpected(p);
3666
+ const e = deriveExpected(p);
3605
3667
  return e.length > 0 ? e : [p._tag];
3606
3668
  }));
3607
3669
  }
@@ -3622,7 +3684,7 @@ function failsAtStart(p) {
3622
3684
  }
3623
3685
  }
3624
3686
  function armStaticExpected(ctx, p) {
3625
- return hoistExpected(ctx, staticExpectedArr([p]));
3687
+ return hoistExpected(ctx, deriveExpectedArr([p]));
3626
3688
  }
3627
3689
  function canMatchEmptyAtStart(p) {
3628
3690
  const d = p._def;
@@ -3660,7 +3722,7 @@ function emitDisjointArm(p, ctx, pos, valV, endV) {
3660
3722
  ];
3661
3723
  }
3662
3724
  function emitChoice(def, ctx, pos) {
3663
- const allExpected = staticExpectedArr(def.parsers);
3725
+ const allExpected = deriveExpectedArr(def.parsers);
3664
3726
  if (def.disjoint) {
3665
3727
  const codeV = v(ctx, "_code");
3666
3728
  const valV = v(ctx, "_chv");
@@ -3721,7 +3783,7 @@ function emitGreedyClassify(def, superIndex, ctx, pos) {
3721
3783
  const wordV = v(ctx, "_gw");
3722
3784
  const endV = v(ctx, "_ge");
3723
3785
  const valV = v(ctx, "_gcv");
3724
- const regexExpected = JSON.stringify(staticExpected(superParser));
3786
+ const regexExpected = JSON.stringify(deriveExpected(superParser));
3725
3787
  const stmts = [
3726
3788
  `${ind(ctx)}${reVar}.lastIndex = ${pos}`,
3727
3789
  `${ind(ctx)}const ${matchV} = ${reVar}.exec(input)`,
@@ -4113,6 +4175,116 @@ function emitNot(def, ctx, pos) {
4113
4175
  endVar: pos
4114
4176
  };
4115
4177
  }
4178
+ function escapeTokenLiteral(value) {
4179
+ return value.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
4180
+ }
4181
+ function regexMatchesEmpty(source, flags) {
4182
+ try {
4183
+ return new RegExp(`^(?:${source})$`, flags).test("");
4184
+ } catch {
4185
+ return true;
4186
+ }
4187
+ }
4188
+ function tokenTerminalSource(p) {
4189
+ const def = p._def;
4190
+ switch (def.tag) {
4191
+ case "literal":
4192
+ if (def.value.length === 0) return null;
4193
+ return {
4194
+ source: escapeTokenLiteral(def.value),
4195
+ caseInsensitive: def.caseInsensitive,
4196
+ rawCaseSensitive: def.caseInsensitive ? "" : def.value
4197
+ };
4198
+ case "regex": {
4199
+ if (def.flags.replace(/i/g, "") !== "") return null;
4200
+ if (regexMatchesEmpty(def.source, def.flags)) return null;
4201
+ return {
4202
+ source: `(?:${def.source})`,
4203
+ caseInsensitive: def.flags.includes("i"),
4204
+ rawCaseSensitive: def.flags.includes("i") ? "" : def.source
4205
+ };
4206
+ }
4207
+ default:
4208
+ return null;
4209
+ }
4210
+ }
4211
+ function tokenSequenceSource(p) {
4212
+ const def = p._def;
4213
+ const parts = def.tag === "sequence" ? def.parsers.map(tokenTerminalSource) : [tokenTerminalSource(p)];
4214
+ if (parts.some((part) => part === null)) return null;
4215
+ const typed = parts;
4216
+ const flags = typed.some((part) => part.caseInsensitive) ? "i" : "";
4217
+ if (flags.includes("i") && typed.some((part) => /[A-Za-z]/.test(part.rawCaseSensitive))) return null;
4218
+ return {
4219
+ source: typed.map((part) => part.source).join(""),
4220
+ flags,
4221
+ hasCaseSensitiveLetters: typed.some((part) => /[A-Za-z]/.test(part.rawCaseSensitive))
4222
+ };
4223
+ }
4224
+ function combineTokenRegexSources(parts) {
4225
+ const flags = parts.some((part) => part.flags.includes("i")) ? "i" : "";
4226
+ if (flags.includes("i") && parts.some((part) => part.flags === "" && part.hasCaseSensitiveLetters)) return null;
4227
+ return { source: parts.map((part) => part.source).join(""), flags };
4228
+ }
4229
+ function tokenNullableRegex(def) {
4230
+ const inner = def.parser._def;
4231
+ if (inner.tag === "many") {
4232
+ const seq = tokenSequenceSource(inner.parser);
4233
+ if (!seq) return null;
4234
+ return { tag: "regex", source: `(?:${seq.source})*`, flags: seq.flags };
4235
+ }
4236
+ if (inner.tag === "optional") {
4237
+ const seq = tokenSequenceSource(inner.parser);
4238
+ if (!seq) return null;
4239
+ return { tag: "regex", source: `(?:${seq.source})?`, flags: seq.flags };
4240
+ }
4241
+ if (inner.tag === "sepBy") {
4242
+ const item = tokenSequenceSource(inner.parser);
4243
+ const sep = tokenSequenceSource(inner.separator);
4244
+ if (!item || !sep) return null;
4245
+ const combined = combineTokenRegexSources([item, sep]);
4246
+ if (!combined) return null;
4247
+ return { tag: "regex", source: `(?:${item.source}(?:${sep.source}${item.source})*)?`, flags: combined.flags };
4248
+ }
4249
+ return null;
4250
+ }
4251
+ function emitToken(def, ctx, pos) {
4252
+ const lowered = tokenNullableRegex(def);
4253
+ if (lowered) return emitRegex(lowered, ctx, pos);
4254
+ const savedTrivia = ctx.activeTrivia;
4255
+ const savedKindLabels = ctx.triviaKindLabels;
4256
+ ctx.activeTrivia = void 0;
4257
+ ctx.triviaKindLabels = void 0;
4258
+ const inner = emitFallible(def.parser, ctx, pos);
4259
+ ctx.activeTrivia = savedTrivia;
4260
+ ctx.triviaKindLabels = savedKindLabels;
4261
+ const i = ind(ctx);
4262
+ const sc = v(ctx, "_tokCh");
4263
+ const sl = v(ctx, "_tokLv");
4264
+ const sr = v(ctx, "_tokRaw");
4265
+ const sv = v(ctx, "_tokTr");
4266
+ const sk = v(ctx, "_tokKinds");
4267
+ const stl = v(ctx, "_tokTl");
4268
+ const sol = v(ctx, "_tokLog");
4269
+ const sb = v(ctx, "_tokBuf");
4270
+ const valV = v(ctx, "_tok");
4271
+ return {
4272
+ stmts: [
4273
+ `${i}const ${sc} = _ctx._cstChildren, ${sl} = _ctx._cstLeaves, ${sr} = _ctx._cstRawChildren, ${sv} = _ctx.trivia, ${sk} = _ctx.triviaKindLabels, ${stl} = _ctx._cstTriviaLog, ${sol} = _ctx._triviaLog, ${sb} = _ctx._cstBuf`,
4274
+ `${i}_ctx.trivia = undefined; _ctx.triviaKindLabels = undefined; _ctx._cstChildren = undefined; _ctx._cstLeaves = undefined; _ctx._cstRawChildren = undefined; _ctx._cstTriviaLog = undefined; _ctx._triviaLog = undefined; _ctx._cstBuf = undefined`,
4275
+ `${i}try {`,
4276
+ ...reindentStmts(inner.stmts, ctx.indent + 1).map((stmt) => stmt.replace(/^(\s*)(?:const|let)\s+/, "$1var ")),
4277
+ `${i}} finally {`,
4278
+ `${i} _ctx.trivia = ${sv}; _ctx.triviaKindLabels = ${sk}; _ctx._cstChildren = ${sc}; _ctx._cstLeaves = ${sl}; _ctx._cstRawChildren = ${sr}; _ctx._cstTriviaLog = ${stl}; _ctx._triviaLog = ${sol}; _ctx._cstBuf = ${sb}`,
4279
+ `${i}}`,
4280
+ ...emitIfFail(ctx, `!${inner.okVar}`, propagateFailBody(ctx)),
4281
+ `${i}const ${valV} = input.slice(${pos}, ${inner.endVar})`,
4282
+ ...emitLeafCapture(ctx, valV, pos, inner.endVar)
4283
+ ],
4284
+ valueVar: valV,
4285
+ endVar: inner.endVar
4286
+ };
4287
+ }
4116
4288
  function emitNode(def, ctx, pos) {
4117
4289
  const structural = def.build === void 0;
4118
4290
  const mkType = structural ? null : analyzeMkInlineBuild(def);
@@ -4232,7 +4404,7 @@ function emitRecover(def, ctx, pos) {
4232
4404
  `${ind0} if (${sentOk}) break`,
4233
4405
  `${ind0} ${scanV}++`,
4234
4406
  `${ind0} }`,
4235
- `${ind0} const ${errV} = { _tag: 'parseError', span: { start: ${pos}, end: ${scanV} }, expected: ${JSON.stringify(staticExpected(def.parser))} }`,
4407
+ `${ind0} const ${errV} = { _tag: 'parseError', span: { start: ${pos}, end: ${scanV} }, expected: ${JSON.stringify(deriveExpected(def.parser))} }`,
4236
4408
  `${ind0} if (_ctx._errors) _ctx._errors.push(${errV})`,
4237
4409
  `${ind0} ${valVar} = ${errV}`,
4238
4410
  `${ind0} ${endVar} = ${scanV}`,
@@ -4362,8 +4534,19 @@ function emitDispatch(p, ctx, pos) {
4362
4534
  return emitLazy(p, def, ctx, pos);
4363
4535
  case "trivia":
4364
4536
  return emit(def.parser, ctx, pos);
4365
- case "label":
4366
- return emit(def.parser, ctx, pos);
4537
+ case "token":
4538
+ return emitToken(def, ctx, pos);
4539
+ case "label": {
4540
+ const inner = emitFallible(def.parser, ctx, pos);
4541
+ return {
4542
+ stmts: [
4543
+ ...inner.stmts,
4544
+ ...emitIfFail(ctx, `!${inner.okVar}`, failBody(ctx, JSON.stringify(def.label), "_ctx._fe"))
4545
+ ],
4546
+ valueVar: inner.valVar,
4547
+ endVar: inner.endVar
4548
+ };
4549
+ }
4367
4550
  case "grammar": {
4368
4551
  const savedTrivia = ctx.activeTrivia;
4369
4552
  const savedKindLabels = ctx.triviaKindLabels;
@@ -4463,6 +4646,7 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
4463
4646
  }
4464
4647
  case "grammar":
4465
4648
  case "trivia":
4649
+ case "token":
4466
4650
  case "label":
4467
4651
  case "optional":
4468
4652
  case "many":
@@ -4498,6 +4682,7 @@ function childrenOf(def) {
4498
4682
  case "optional":
4499
4683
  case "transform":
4500
4684
  case "trivia":
4685
+ case "token":
4501
4686
  case "label":
4502
4687
  case "grammar":
4503
4688
  case "not":
@@ -5081,7 +5266,7 @@ function balanced(open, close, options = {}) {
5081
5266
  const content = bounded ? regex(new RegExp(`[^${cls}]+`)) : regex(new RegExp(`[^${escapeClassChar(open)}${escapeClassChar(close)}]`));
5082
5267
  const inner = many(choice(self, ...skips, content));
5083
5268
  const combi = transform(
5084
- sequence(literal(open), inner, expect(literal(close), close)),
5269
+ sequence(literal(open), inner, expect(literal(close))),
5085
5270
  // parts: strings (content/self) or arrays (a sequence-shaped skip) or a
5086
5271
  // ParseError (recovered close). `c` is the close string or a ParseError.
5087
5272
  ([o, parts, c]) => o + parts.map((p) => typeof p === "string" ? p : Array.isArray(p) ? p.join("") : "").join("") + (typeof c === "string" ? c : "")
@@ -5118,6 +5303,7 @@ function childrenOf2(def) {
5118
5303
  case "optional":
5119
5304
  case "transform":
5120
5305
  case "trivia":
5306
+ case "token":
5121
5307
  case "label":
5122
5308
  case "not":
5123
5309
  case "node":
@@ -5199,6 +5385,7 @@ function evalRuleMapIR(ir) {
5199
5385
  "node",
5200
5386
  "parser",
5201
5387
  "scanTo",
5388
+ "token",
5202
5389
  "transform",
5203
5390
  "skip",
5204
5391
  "trivia",
@@ -5224,6 +5411,7 @@ function evalRuleMapIR(ir) {
5224
5411
  node,
5225
5412
  parser,
5226
5413
  scanTo,
5414
+ token,
5227
5415
  transform,
5228
5416
  skip,
5229
5417
  trivia,
@@ -5357,6 +5545,8 @@ ${body}
5357
5545
  return `not(${kid(def.parser)})`;
5358
5546
  case "trivia":
5359
5547
  return `trivia(${kid(def.parser)})`;
5548
+ case "token":
5549
+ return `token(${kid(def.parser)})`;
5360
5550
  case "label":
5361
5551
  return `label(${JSON.stringify(def.label)}, ${kid(def.parser)})`;
5362
5552
  case "expect":
@@ -5479,6 +5669,7 @@ var SUPPORTED = {
5479
5669
  trivia: (...a) => trivia(a[0]),
5480
5670
  label: (...a) => label(a[0], a[1]),
5481
5671
  noTrivia: (...a) => noTrivia(a[0]),
5672
+ token: (...a) => token(a[0]),
5482
5673
  expect: (...a) => expect(a[0], a[1])
5483
5674
  };
5484
5675
  function isScopeEntry(v2) {