parseman 0.37.0 → 0.38.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.
@@ -15,8 +15,9 @@ export type Scope = Map<string, ScopeEntry>;
15
15
  type WordFactoryEntry = {
16
16
  tag: 'wordFactory';
17
17
  boundary: string;
18
+ caseInsensitive: boolean;
18
19
  };
19
- /** Evaluate makeWord(boundary?) to a factory entry (not a combinator). */
20
+ /** Evaluate makeWord(boundary?, opts?) to a factory entry (not a combinator). */
20
21
  export declare function evaluateWordFactory(node: Expression, scope: Scope, code?: string): WordFactoryEntry | null;
21
22
  /** Evaluate a single combinator expression. Returns null if unresolvable. */
22
23
  export declare function evaluateExpr(node: Expression, scope: Scope, code?: string, mapFnSources?: string[]): Combinator<unknown> | null;
@@ -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;AA4E7C,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;AA6hBhE,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,CAqGzC;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;AA4E7C,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,CAAC;IAAC,eAAe,EAAE,OAAO,CAAA;CAAE,CAAA;AAojB1F,iFAAiF;AACjF,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,gBAAgB,GAAG,IAAI,CAKzB;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,CA8GzC;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"}
@@ -2393,6 +2393,16 @@ function tagRule(r, key) {
2393
2393
  r._ruleName = key;
2394
2394
  if (r._def.tag === "node" && r._def.type === void 0) r._def.type = key;
2395
2395
  }
2396
+ function isDefinableRef(v2) {
2397
+ return !!v2 && typeof v2 === "object" && "_def" in v2 && v2._def.tag === "lazy" && typeof v2.define === "function";
2398
+ }
2399
+ function ruleNameOf(r) {
2400
+ return r._ruleName;
2401
+ }
2402
+ function isNamedRuleRefForAnotherRule(r, key) {
2403
+ const name = r._def.tag === "lazy" ? ruleNameOf(r) : void 0;
2404
+ return name !== void 0 && name !== key;
2405
+ }
2396
2406
  function rules(a, b) {
2397
2407
  const factory = typeof a === "function" ? a : b;
2398
2408
  const options = typeof a === "function" ? b : a;
@@ -2413,11 +2423,21 @@ function rules(a, b) {
2413
2423
  for (const key of Object.keys(definitions)) {
2414
2424
  const placeholder = cache[key];
2415
2425
  const parser2 = definitions[key];
2416
- if (placeholder !== void 0 && typeof placeholder.define === "function") {
2417
- tagRule(parser2, key);
2426
+ if (placeholder === parser2) {
2427
+ throw new Error(`rules(): rule "${key}" cannot be a direct alias to itself`);
2428
+ }
2429
+ if (isDefinableRef(placeholder)) {
2430
+ if (!isNamedRuleRefForAnotherRule(parser2, key)) tagRule(parser2, key);
2418
2431
  placeholder.define(parser2);
2419
2432
  placeholder._meta.firstSet = parser2._meta.firstSet;
2420
2433
  placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
2434
+ } else if (isNamedRuleRefForAnotherRule(parser2, key)) {
2435
+ const alias = ref();
2436
+ tagRule(alias, key);
2437
+ alias.define(parser2);
2438
+ alias._meta.firstSet = parser2._meta.firstSet;
2439
+ alias._meta.canMatchNewline = parser2._meta.canMatchNewline;
2440
+ cache[key] = alias;
2421
2441
  } else {
2422
2442
  tagRule(parser2, key);
2423
2443
  cache[key] = parser2;
@@ -3043,7 +3063,7 @@ function leaf(root, fn) {
3043
3063
  }
3044
3064
 
3045
3065
  // src/version.ts
3046
- var PARSEMAN_VERSION = "0.37.0";
3066
+ var PARSEMAN_VERSION = "0.38.0";
3047
3067
 
3048
3068
  // src/cst/host-mode.ts
3049
3069
  var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
@@ -3097,7 +3117,7 @@ function firstSetToString(fs2) {
3097
3117
  if (fs2.kind === "empty") return "(empty)";
3098
3118
  return fs2.ranges.map((r) => r.lo === r.hi ? ch(r.lo) : `${ch(r.lo)}-${ch(r.hi)}`).join(",");
3099
3119
  }
3100
- var ruleNameOf = (p) => p._ruleName;
3120
+ var ruleNameOf2 = (p) => p._ruleName;
3101
3121
  var SUGGESTIONS = {
3102
3122
  "broad-recognizer": "if this arm leads with a keyword regex, use word('kw', boundary) / keywords([...]) \u2014 they expose an EXACT, gating first-set and lower to the same charCodeAt scan. A genuine scanTo fallback is fine; accept it in the gating snapshot if intentional.",
3103
3123
  "leading-not": "let the arm lead with its actual consuming terminal (first-sets gate it automatically); keep not(...) only as a TRAILING boundary. Do not hand-roll not(not(...)) to fake gating \u2014 use peek(X), which is zero-width AND carries X first-set.",
@@ -3255,7 +3275,7 @@ function detectAntiPatterns(rule, arms) {
3255
3275
  return out;
3256
3276
  }
3257
3277
  function analyzeGating(entry, opts) {
3258
- return analyzeGatingRules([[ruleNameOf(entry) ?? opts?.entryName ?? "<entry>", entry]], opts);
3278
+ return analyzeGatingRules([[ruleNameOf2(entry) ?? opts?.entryName ?? "<entry>", entry]], opts);
3259
3279
  }
3260
3280
  function analyzeGatingRules(ruleMap, opts) {
3261
3281
  const raw = [];
@@ -3288,7 +3308,7 @@ function analyzeGatingRules(ruleMap, opts) {
3288
3308
  return;
3289
3309
  }
3290
3310
  const d = def;
3291
- const rule = ruleNameOf(p) ?? enclosingRule;
3311
+ const rule = ruleNameOf2(p) ?? enclosingRule;
3292
3312
  if (d.tag === "choice") {
3293
3313
  raw.push({ g: analyzeChoice(p, d, rule, opts?.resolveRef), rule });
3294
3314
  antiPatterns.push(...detectAntiPatterns(rule, d.parsers));
@@ -3307,7 +3327,7 @@ function analyzeGatingRules(ruleMap, opts) {
3307
3327
  }
3308
3328
  for (const k of kids) visit(k, rule);
3309
3329
  };
3310
- for (const [name, root] of ruleMap) visit(root, ruleNameOf(root) ?? name);
3330
+ for (const [name, root] of ruleMap) visit(root, ruleNameOf2(root) ?? name);
3311
3331
  const perRule = /* @__PURE__ */ new Map();
3312
3332
  for (const r of raw) perRule.set(r.rule, (perRule.get(r.rule) ?? 0) + 1);
3313
3333
  const seenInRule = /* @__PURE__ */ new Map();
@@ -3431,7 +3451,7 @@ function childrenOf(d) {
3431
3451
  }
3432
3452
  }
3433
3453
  }
3434
- var ruleNameOf2 = (p) => p._ruleName;
3454
+ var ruleNameOf3 = (p) => p._ruleName;
3435
3455
  var fnKey = (src, fn) => src ?? (typeof fn === "function" ? String(fn) : "");
3436
3456
  function payloadKey(p, d) {
3437
3457
  switch (d.tag) {
@@ -3442,7 +3462,7 @@ function payloadKey(p, d) {
3442
3462
  case "keywords":
3443
3463
  return `keywords\0${[...d.words].join("")}\0${d.caseInsensitive}\0${d.boundary ?? ""}`;
3444
3464
  case "lazy": {
3445
- const n = ruleNameOf2(p);
3465
+ const n = ruleNameOf3(p);
3446
3466
  return n === void 0 ? `ref\0#${anonId(p)}` : `ref\0${n}`;
3447
3467
  }
3448
3468
  case "label":
@@ -3509,7 +3529,7 @@ var Interner = class {
3509
3529
  var MAX_RENDER = 160;
3510
3530
  function render(p, depth = 3) {
3511
3531
  const d = p._def;
3512
- const name = ruleNameOf2(p);
3532
+ const name = ruleNameOf3(p);
3513
3533
  switch (d.tag) {
3514
3534
  case "literal":
3515
3535
  return `literal('${d.value}')`;
@@ -3688,7 +3708,7 @@ function keywordAlternationHazards(words, boundary) {
3688
3708
  return out;
3689
3709
  }
3690
3710
  function analyzeDuplication(entry, opts) {
3691
- return analyzeDuplicationRules([[ruleNameOf2(entry) ?? opts?.entryName ?? "<entry>", entry]], opts);
3711
+ return analyzeDuplicationRules([[ruleNameOf3(entry) ?? opts?.entryName ?? "<entry>", entry]], opts);
3692
3712
  }
3693
3713
  function assertAnalyzable(ruleMap) {
3694
3714
  for (const [name, rule] of ruleMap) {
@@ -3729,7 +3749,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
3729
3749
  const visit = (p, rule, path2, enclosingNode, enclosingReducer) => {
3730
3750
  if (visited.has(p)) return;
3731
3751
  const d = p._def;
3732
- const own = ruleNameOf2(p);
3752
+ const own = ruleNameOf3(p);
3733
3753
  const here = own !== void 0 && own !== rule ? { rule: own, path: "" } : { rule, path: path2 };
3734
3754
  visited.set(p, { p, d, site: here, shape: shapeOf(p), size: sizeOf(p), enclosingNode, enclosingReducer });
3735
3755
  const inner = d.tag === "node" ? d.type ?? "(anonymous)" : enclosingNode;
@@ -3742,12 +3762,12 @@ function analyzeDuplicationRules(ruleMap, opts) {
3742
3762
  if (d.tag === "lazy") {
3743
3763
  try {
3744
3764
  const target = d.thunk();
3745
- visit(target, ruleNameOf2(target) ?? ruleNameOf2(p) ?? here.rule, "", null, false);
3765
+ visit(target, ruleNameOf3(target) ?? ruleNameOf3(p) ?? here.rule, "", null, false);
3746
3766
  } catch {
3747
3767
  }
3748
3768
  }
3749
3769
  };
3750
- for (const [name, root] of ruleMap) visit(root, ruleNameOf2(root) ?? name, "", null, false);
3770
+ for (const [name, root] of ruleMap) visit(root, ruleNameOf3(root) ?? name, "", null, false);
3751
3771
  const accept = new Set(opts?.accept ?? []);
3752
3772
  const used = /* @__PURE__ */ new Set();
3753
3773
  const keep = (f) => {
@@ -8602,7 +8622,7 @@ function ruleDependencies(ruleMap) {
8602
8622
  const seen = /* @__PURE__ */ new Set();
8603
8623
  const walk2 = (p, isRoot) => {
8604
8624
  const def = p._def;
8605
- const boundary = def.tag === "lazy" ? p._ruleName ?? nameOf.get(p) : nameOf.get(p);
8625
+ const boundary = def.tag === "lazy" ? nameOf.get(p) ?? p._ruleName : nameOf.get(p);
8606
8626
  if (!isRoot && boundary !== void 0) {
8607
8627
  found.add(boundary);
8608
8628
  return;
@@ -9367,7 +9387,7 @@ function childrenOf3(def) {
9367
9387
  return [];
9368
9388
  }
9369
9389
  }
9370
- var ruleNameOf3 = (c) => c._ruleName;
9390
+ var ruleNameOf4 = (c) => c._ruleName;
9371
9391
  function lazyTarget(c) {
9372
9392
  if (c._def.tag !== "lazy") return null;
9373
9393
  try {
@@ -9549,12 +9569,16 @@ var Serializer = class {
9549
9569
  emitted = /* @__PURE__ */ new Set();
9550
9570
  decls = [];
9551
9571
  ruleValues = /* @__PURE__ */ new Set();
9572
+ localRuleNames = /* @__PURE__ */ new Map();
9552
9573
  ruleMap;
9553
9574
  scanSkip;
9554
9575
  constructor(ruleMap, scanSkip = []) {
9555
9576
  this.ruleMap = ruleMap;
9556
9577
  this.scanSkip = scanSkip;
9557
- for (const [, c] of ruleMap) this.ruleValues.add(this.body(c));
9578
+ for (const [name, c] of ruleMap) {
9579
+ this.localRuleNames.set(c, name);
9580
+ this.ruleValues.add(this.body(c));
9581
+ }
9558
9582
  }
9559
9583
  /** A grammar-level `scanSkip` unit is an opaque TERMINAL (a string, a balanced
9560
9584
  * bracket) — it must not reach a grammar-rule ref (`g[name]`), because the
@@ -9565,7 +9589,7 @@ var Serializer = class {
9565
9589
  if (seen.has(c)) return;
9566
9590
  seen.add(c);
9567
9591
  if (c._def.tag === "lazy") {
9568
- if (ruleNameOf3(c) !== void 0) throw new Unserializable("scanSkip unit references a grammar rule");
9592
+ if (ruleNameOf4(c) !== void 0) throw new Unserializable("scanSkip unit references a grammar rule");
9569
9593
  const target = lazyTarget(c);
9570
9594
  if (target) this.assertNoRuleRef(target, seen);
9571
9595
  return;
@@ -9576,7 +9600,7 @@ var Serializer = class {
9576
9600
  * its target (compileLinkable unwraps the same way). A ref INSIDE a body stays a
9577
9601
  * `g[name]` ref — only the top-level entry is unwrapped. */
9578
9602
  body(c) {
9579
- return c._def.tag === "lazy" && ruleNameOf3(c) !== void 0 ? lazyTarget(c) ?? c : c;
9603
+ return c._def.tag === "lazy" && ruleNameOf4(c) !== void 0 ? lazyTarget(c) ?? c : c;
9580
9604
  }
9581
9605
  run() {
9582
9606
  for (const [, c] of this.ruleMap) this.analyze(this.body(c), /* @__PURE__ */ new Set());
@@ -9618,7 +9642,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
9618
9642
  analyze(c, active) {
9619
9643
  const def = c._def;
9620
9644
  if (def.tag === "lazy") {
9621
- if (ruleNameOf3(c) !== void 0) return;
9645
+ if (ruleNameOf4(c) !== void 0) return;
9622
9646
  const target = lazyTarget(c);
9623
9647
  if (!target) throw new Unserializable("unresolved unnamed ref");
9624
9648
  if (active.has(target)) {
@@ -9670,7 +9694,8 @@ ${outerDecls.map((d) => " " + d).join("\n")}
9670
9694
  const kid = (x) => this.ref(x, selfOf);
9671
9695
  switch (def.tag) {
9672
9696
  case "lazy": {
9673
- if (ruleNameOf3(c) !== void 0) return `g[${JSON.stringify(ruleNameOf3(c))}]`;
9697
+ const name = this.localRuleNames.get(c) ?? ruleNameOf4(c);
9698
+ if (name !== void 0) return `g[${JSON.stringify(name)}]`;
9674
9699
  const target = lazyTarget(c);
9675
9700
  if (selfOf && target === selfOf.comb) return selfOf.var;
9676
9701
  return this.ref(target, selfOf);
@@ -10180,6 +10205,25 @@ function stripTsFromSource(node2, code) {
10180
10205
  function isWordFactory(v2) {
10181
10206
  return !!v2 && typeof v2 === "object" && v2.tag === "wordFactory";
10182
10207
  }
10208
+ function wordFactoryFromArgs(args, scope, code, mfs) {
10209
+ const [boundaryOrOptsArg, optsArg] = args;
10210
+ if (boundaryOrOptsArg?.type === "SpreadElement" || optsArg?.type === "SpreadElement") return null;
10211
+ const rawBoundaryOrOpts = boundaryOrOptsArg === void 0 ? void 0 : anyValue(boundaryOrOptsArg, scope, code, mfs);
10212
+ const boundaryOrOpts = rawBoundaryOrOpts === void 0 ? "_0-9A-Za-z" : rawBoundaryOrOpts;
10213
+ const opts = optsArg === void 0 ? void 0 : anyValue(optsArg, scope, code, mfs);
10214
+ if (typeof boundaryOrOpts === "string") {
10215
+ if (opts !== void 0 && (typeof opts !== "object" || opts === null || Array.isArray(opts))) return null;
10216
+ const caseInsensitive2 = typeof opts === "object" && opts !== null && "caseInsensitive" in opts ? opts.caseInsensitive : false;
10217
+ if (typeof caseInsensitive2 !== "boolean") return null;
10218
+ return { tag: "wordFactory", boundary: boundaryOrOpts, caseInsensitive: caseInsensitive2 };
10219
+ }
10220
+ if (typeof boundaryOrOpts !== "object" || boundaryOrOpts === null || Array.isArray(boundaryOrOpts) || opts !== void 0) {
10221
+ return null;
10222
+ }
10223
+ const caseInsensitive = "caseInsensitive" in boundaryOrOpts ? boundaryOrOpts.caseInsensitive : false;
10224
+ if (typeof caseInsensitive !== "boolean") return null;
10225
+ return { tag: "wordFactory", boundary: "_0-9A-Za-z", caseInsensitive };
10226
+ }
10183
10227
  var SUPPORTED = {
10184
10228
  literal: (...a) => literal(a[0], a[1]),
10185
10229
  regex: (...a) => regex(a[0], a[1]),
@@ -10263,14 +10307,13 @@ function exprToCombi(node2, scope, code, mfs) {
10263
10307
  if (node2.type !== "CallExpression") return null;
10264
10308
  const callee = node2.callee;
10265
10309
  if (callee.type === "CallExpression" && callee.callee.type === "Identifier" && callee.callee.name === "makeWord") {
10266
- const boundaryArg = callee.arguments[0];
10267
10310
  const strArg = node2.arguments[0];
10268
10311
  if (!strArg || strArg.type === "SpreadElement") return null;
10269
- const boundary = boundaryArg && boundaryArg.type !== "SpreadElement" ? anyValue(boundaryArg, scope, code, mfs) : "_0-9A-Za-z";
10312
+ const factory2 = wordFactoryFromArgs(callee.arguments, scope, code, mfs);
10270
10313
  const str = anyValue(strArg, scope, code, mfs);
10271
- if (typeof boundary !== "string" || typeof str !== "string") return null;
10314
+ if (factory2 === null || typeof str !== "string") return null;
10272
10315
  try {
10273
- return word(str, boundary);
10316
+ return word(str, factory2.boundary, { caseInsensitive: factory2.caseInsensitive });
10274
10317
  } catch {
10275
10318
  return null;
10276
10319
  }
@@ -10283,7 +10326,7 @@ function exprToCombi(node2, scope, code, mfs) {
10283
10326
  const str = anyValue(strArg, scope, code, mfs);
10284
10327
  if (typeof str !== "string") return null;
10285
10328
  try {
10286
- return word(str, factory2.boundary);
10329
+ return word(str, factory2.boundary, { caseInsensitive: factory2.caseInsensitive });
10287
10330
  } catch {
10288
10331
  return null;
10289
10332
  }
@@ -10593,10 +10636,7 @@ function anyValue(node2, scope, code, mfs) {
10593
10636
  if (node2.type === "CallExpression") {
10594
10637
  const callee = node2.callee;
10595
10638
  if (callee.type === "Identifier" && callee.name === "makeWord") {
10596
- const boundaryArg = node2.arguments[0];
10597
- const boundary = boundaryArg && boundaryArg.type !== "SpreadElement" ? anyValue(boundaryArg, scope, code, mfs) : "_0-9A-Za-z";
10598
- if (typeof boundary !== "string") return null;
10599
- return { tag: "wordFactory", boundary };
10639
+ return wordFactoryFromArgs(node2.arguments, scope, code, mfs);
10600
10640
  }
10601
10641
  return exprToCombi(node2, scope, code, mfs);
10602
10642
  }
@@ -10606,10 +10646,7 @@ function evaluateWordFactory(node2, scope, code) {
10606
10646
  if (node2.type !== "CallExpression") return null;
10607
10647
  const callee = node2.callee;
10608
10648
  if (callee.type !== "Identifier" || callee.name !== "makeWord") return null;
10609
- const boundaryArg = node2.arguments[0];
10610
- const boundary = boundaryArg && boundaryArg.type !== "SpreadElement" ? anyValue(boundaryArg, scope, code) : "_0-9A-Za-z";
10611
- if (typeof boundary !== "string") return null;
10612
- return { tag: "wordFactory", boundary };
10649
+ return wordFactoryFromArgs(node2.arguments, scope, code);
10613
10650
  }
10614
10651
  function evaluateExpr(node2, scope, code, mapFnSources) {
10615
10652
  return exprToCombi(node2, scope, code, mapFnSources);
@@ -10704,6 +10741,11 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources) {
10704
10741
  r._ruleName = name;
10705
10742
  if (r._def.tag === "node" && r._def.type === void 0) r._def.type = name;
10706
10743
  };
10744
+ const ruleNameOf5 = (r) => r._ruleName;
10745
+ const isNamedRuleRefForAnotherRule2 = (r, key) => {
10746
+ const name = r._def.tag === "lazy" ? ruleNameOf5(r) : void 0;
10747
+ return name !== void 0 && name !== key;
10748
+ };
10707
10749
  for (const key of keys) {
10708
10750
  if (!ruleRefs.has(key)) {
10709
10751
  const r = ref();
@@ -10734,12 +10776,15 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources) {
10734
10776
  for (const [key, e] of finalByKey) {
10735
10777
  const val = anyValue(e.value, e.scope, e.code, mapFnSources);
10736
10778
  if (!isCombinator(val)) return null;
10737
- tagRef(val, key);
10779
+ if (val === ruleRefs.get(key)) return null;
10780
+ if (!isNamedRuleRefForAnotherRule2(val, key)) {
10781
+ tagRef(val, key);
10782
+ }
10738
10783
  ruleRefs.get(key).define(val);
10739
10784
  }
10740
10785
  return ruleRefs;
10741
10786
  }
10742
- function isDefinableRef(v2) {
10787
+ function isDefinableRef2(v2) {
10743
10788
  return isCombinator(v2) && typeof v2.define === "function" && v2._def.tag === "lazy";
10744
10789
  }
10745
10790
  function evaluateRefDeclaration(init, name, scope) {
@@ -10761,7 +10806,7 @@ function applyDefineStatement(callExpr, scope, code) {
10761
10806
  if (mem.object.type !== "Identifier" || !mem.object.name) return false;
10762
10807
  const target = scope.get(mem.object.name);
10763
10808
  const refCombi = isScopeEntry(target) ? target.combi : isCombinator(target) ? target : null;
10764
- if (!refCombi || !isDefinableRef(refCombi)) return false;
10809
+ if (!refCombi || !isDefinableRef2(refCombi)) return false;
10765
10810
  const args = callExpr.arguments;
10766
10811
  if (args.length !== 1 || args[0].type === "SpreadElement") return false;
10767
10812
  const inner = anyValue(args[0], scope, code, []);