parseman 0.60.6 → 0.61.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.
Files changed (40) hide show
  1. package/dist/analysis/diagnostics.js +47 -36
  2. package/dist/analysis/diagnostics.js.map +3 -3
  3. package/dist/cli/index.js +47 -36
  4. package/dist/cli/index.js.map +3 -3
  5. package/dist/combinators/choice.d.ts.map +1 -1
  6. package/dist/combinators/expect.d.ts.map +1 -1
  7. package/dist/combinators/link-scope.d.ts +7 -0
  8. package/dist/combinators/link-scope.d.ts.map +1 -0
  9. package/dist/combinators/node.d.ts.map +1 -1
  10. package/dist/combinators/parser.d.ts.map +1 -1
  11. package/dist/compiler/token-capability.js +1 -0
  12. package/dist/compiler/token-capability.js.map +1 -1
  13. package/dist/compiler/value-usage.d.ts.map +1 -1
  14. package/dist/functional/run.d.ts.map +1 -1
  15. package/dist/index.js +91 -66
  16. package/dist/index.js.map +3 -3
  17. package/dist/language-service/index.js +1 -1
  18. package/dist/language-service/index.js.map +1 -1
  19. package/dist/plugin/index.js +254 -229
  20. package/dist/plugin/index.js.map +3 -3
  21. package/dist/run/index.js +1 -1
  22. package/dist/run/index.js.map +1 -1
  23. package/dist/spec/index.js.map +1 -1
  24. package/dist/table/emit.d.ts.map +1 -1
  25. package/dist/table/index.js +11 -6
  26. package/dist/table/index.js.map +3 -3
  27. package/dist/table/program.d.ts +3 -1
  28. package/dist/table/program.d.ts.map +1 -1
  29. package/dist/version.d.ts +1 -1
  30. package/package.json +1 -1
  31. package/src/combinators/choice.ts +3 -1
  32. package/src/combinators/expect.ts +1 -0
  33. package/src/combinators/link-scope.ts +19 -0
  34. package/src/combinators/node.ts +11 -2
  35. package/src/combinators/parser.ts +37 -31
  36. package/src/compiler/value-usage.ts +16 -29
  37. package/src/functional/run.ts +3 -1
  38. package/src/table/emit.ts +5 -1
  39. package/src/table/program.ts +8 -2
  40. package/src/version.ts +1 -1
@@ -2258,15 +2258,20 @@ function markUnusedValues(root) {
2258
2258
  case "many":
2259
2259
  case "oneOrMore":
2260
2260
  mark(def, consumed);
2261
- visit(def.parser, consumed);
2262
- return;
2263
2261
  case "optional":
2262
+ // `optional` returns `inner | null` — no aggregate array/tuple to elide, so
2263
+ // it carries no valueUnused flag. Still descend so an inner many/sequence
2264
+ // under a node() is analyzed (it benefits even when its optional wrapper
2265
+ // doesn't).
2266
+ case "label":
2267
+ case "trivia":
2268
+ case "attempt":
2269
+ case "withCtx":
2270
+ case "expect":
2264
2271
  visit(def.parser, consumed);
2265
2272
  return;
2266
2273
  case "sequence":
2267
2274
  mark(def, consumed);
2268
- for (const p of def.parsers) visit(p, consumed);
2269
- return;
2270
2275
  case "choice":
2271
2276
  for (const p of def.parsers) visit(p, consumed);
2272
2277
  return;
@@ -2277,22 +2282,24 @@ function markUnusedValues(root) {
2277
2282
  if (def.otherwise) visit(def.otherwise, consumed);
2278
2283
  return;
2279
2284
  case "node":
2285
+ // builds from captured children, NOT the inner parser value.
2286
+ case "not":
2287
+ case "peek":
2288
+ // lookahead — value never observed
2289
+ case "token":
2280
2290
  visit(def.parser, false);
2281
2291
  return;
2282
2292
  case "transform":
2283
- visit(def.parser, true);
2284
- return;
2293
+ // the map fn reads the value → always consumed.
2285
2294
  case "field":
2295
+ // the field capture records the parsed value → always consumed.
2296
+ case "leaf":
2286
2297
  visit(def.parser, true);
2287
2298
  return;
2288
2299
  case "sepBy":
2289
2300
  visit(def.parser, true);
2290
2301
  visit(def.separator, false);
2291
2302
  return;
2292
- case "not":
2293
- case "peek":
2294
- visit(def.parser, false);
2295
- return;
2296
2303
  case "grammar":
2297
2304
  visit(def.parser, consumed);
2298
2305
  if (def.triviaParser) visit(def.triviaParser, false);
@@ -2301,19 +2308,6 @@ function markUnusedValues(root) {
2301
2308
  visit(def.parser, consumed);
2302
2309
  visit(def.sentinel, false);
2303
2310
  return;
2304
- case "token":
2305
- visit(def.parser, false);
2306
- return;
2307
- case "label":
2308
- case "trivia":
2309
- case "attempt":
2310
- case "withCtx":
2311
- case "expect":
2312
- visit(def.parser, consumed);
2313
- return;
2314
- case "leaf":
2315
- visit(def.parser, true);
2316
- return;
2317
2311
  case "lazy":
2318
2312
  return;
2319
2313
  default:
@@ -2676,6 +2670,7 @@ function derive(c, seen) {
2676
2670
  case "optional":
2677
2671
  case "many":
2678
2672
  case "oneOrMore":
2673
+ case "sepBy":
2679
2674
  case "transform":
2680
2675
  case "not":
2681
2676
  case "peek":
@@ -2823,7 +2818,7 @@ function choice(...args) {
2823
2818
  const result = parsers[idx].parse(input, pos, ctx);
2824
2819
  if (result.ok) return result;
2825
2820
  expected.push(...result.expected);
2826
- if (result.committed) return { ok: false, expected, span: { start: pos, end: pos }, committed: true };
2821
+ if (result.committed) return { ok: false, expected, span: result.span, committed: true };
2827
2822
  return { ok: false, expected, span: { start: pos, end: pos } };
2828
2823
  }
2829
2824
  if (ctx._probe !== void 0 || ctx._tolerant) for (const p of parsers) p.parse(input, pos, ctx);
@@ -4067,6 +4062,9 @@ function regex(pattern, flags = "") {
4067
4062
  };
4068
4063
  }
4069
4064
 
4065
+ // src/version.ts
4066
+ var PARSEMAN_VERSION = "0.61.0";
4067
+
4070
4068
  // src/table/lex-body.ts
4071
4069
  function buildLexBodyRecognizer(spec, constants) {
4072
4070
  const raw = constants[spec[0]];
@@ -4682,11 +4680,12 @@ function assemblyExtraIps(prog) {
4682
4680
  }
4683
4681
  function expandCompact(p) {
4684
4682
  if ("code" in p) return p;
4683
+ if (p.es === void 0) throw new Error(`parseman: this parser was printed by an earlier parseman; reprint it with parseman ${PARSEMAN_VERSION}`);
4685
4684
  return ownTableProgram({
4686
4685
  code: p.c,
4687
4686
  k: p.k,
4688
4687
  cc: p.x,
4689
- fx: p.e,
4688
+ fx: p.e.map((set) => set.map((i) => p.es[i])),
4690
4689
  disp: p.d,
4691
4690
  rules: p.r,
4692
4691
  fns: p.f,
@@ -6693,6 +6692,12 @@ var OP_NAMES = {
6693
6692
  [OP_STRICT]: "STRICT"
6694
6693
  };
6695
6694
 
6695
+ // src/combinators/link-scope.ts
6696
+ var scope;
6697
+ function afterLink(settle) {
6698
+ scope?.push(settle);
6699
+ }
6700
+
6696
6701
  // src/combinators/node.ts
6697
6702
  import { PlainNode, PlainSpan as PlainSpan7 } from "../cst/plain.js";
6698
6703
  function unwrapChild(child) {
@@ -6756,8 +6761,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
6756
6761
  const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || buildArity !== void 0 || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...buildArity !== void 0 ? { buildArity } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
6757
6762
  const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
6758
6763
  const readsState = build ? buildReadsState(def) : project === void 0;
6759
- const hasOwnFields = parserHasOwnFields(combinator);
6760
- const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
6764
+ let hasOwnFields = parserHasOwnFields(combinator);
6765
+ let capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
6766
+ if (!hasOwnFields) {
6767
+ afterLink(() => {
6768
+ hasOwnFields = parserHasOwnFields(combinator);
6769
+ capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
6770
+ });
6771
+ }
6761
6772
  const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
6762
6773
  let failExpected;
6763
6774
  return {
@@ -6863,7 +6874,7 @@ function selectOptionalSuffixLexBody(ir) {
6863
6874
  function reinstallsRuleTrivia(reference, target) {
6864
6875
  return (reference._meta.grammarTrivia ?? target._meta.grammarTrivia) !== void 0 && hasOwnTriviaBoundary(target);
6865
6876
  }
6866
- function directTokenBodyParser(parser2, resolve, scope) {
6877
+ function directTokenBodyParser(parser2, resolve, scope2) {
6867
6878
  const outer = parser2._def;
6868
6879
  if (outer.tag !== "token") return void 0;
6869
6880
  let body = outer.parser;
@@ -6873,7 +6884,7 @@ function directTokenBodyParser(parser2, resolve, scope) {
6873
6884
  const wrapper = body._def;
6874
6885
  if (wrapper.tag === "grammar") {
6875
6886
  if (wrapper.clearTrivia !== true || wrapper.triviaParser !== void 0 || wrapper.captureTrivia === true || wrapper.rootCapture === "opaque" || wrapper.constructionTrackLines !== "inherit" || wrapper.constructionCaptureTriviaKinds !== void 0) return void 0;
6876
- if (scope !== void 0) scope.cleared = true;
6887
+ if (scope2 !== void 0) scope2.cleared = true;
6877
6888
  body = wrapper.parser;
6878
6889
  continue;
6879
6890
  }
@@ -7130,10 +7141,10 @@ function directFixedLexNode(parser2, resolve, active, pureOnly = false, cleared
7130
7141
  }
7131
7142
  }
7132
7143
  function directFixedTokenBody(parser2, resolve) {
7133
- const scope = { cleared: false };
7134
- const body = directTokenBodyParser(parser2, resolve, scope);
7144
+ const scope2 = { cleared: false };
7145
+ const body = directTokenBodyParser(parser2, resolve, scope2);
7135
7146
  if (body === void 0) return void 0;
7136
- const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set(), false, scope.cleared);
7147
+ const root = directFixedLexNode(body, resolve, /* @__PURE__ */ new Set(), false, scope2.cleared);
7137
7148
  return root === void 0 ? void 0 : { kind: "fixed-tree", root };
7138
7149
  }
7139
7150
  function directBalancedTokenBody(parser2, resolve) {
@@ -13285,9 +13296,6 @@ function clearOf(ranges, input, from, to) {
13285
13296
  return true;
13286
13297
  }
13287
13298
 
13288
- // src/version.ts
13289
- var PARSEMAN_VERSION = "0.60.6";
13290
-
13291
13299
  // src/table/assemble.ts
13292
13300
  import { PlainBuf as PlainBuf2, PlainField, PlainLeaf as PlainLeaf9, PlainNode as PlainNode2, PlainSpan as PlainSpan10 } from "../cst/plain.js";
13293
13301
 
@@ -17271,12 +17279,15 @@ function assertPrintable(prog, who) {
17271
17279
  }
17272
17280
  }
17273
17281
  function programFields(prog, fns, opts = {}) {
17282
+ const tokens = [...new Set(prog.fx.flat())];
17283
+ const tokenAt = new Map(tokens.map((token2, i) => [token2, i]));
17274
17284
  return [
17275
17285
  ...emitAssemblies(prog, opts.assemblies ?? []),
17276
17286
  `c:[${prog.code.join(",")}],`,
17277
17287
  `k:[${prog.k.map(emitConst).join(",")}],`,
17278
17288
  `x:${emitClassPool(prog.cc)},`,
17279
- `e:[${prog.fx.map((f) => `[${f.map(jsString).join(",")}]`).join(",")}],`,
17289
+ `e:[${prog.fx.map((f) => `[${f.map((token2) => tokenAt.get(token2)).join(",")}]`).join(",")}],`,
17290
+ `es:[${tokens.map(jsString).join(",")}],`,
17280
17291
  `d:[${prog.disp.map((a) => `[${a.join(",")}]`).join(",")}],`,
17281
17292
  `r:${JSON.stringify(prog.rules)},`,
17282
17293
  ...prog.lines === 1 ? ["l:1,"] : [],