parseman 0.50.4 → 0.50.5
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/dist/index.js +31 -3
- package/dist/index.js.map +1 -1
- package/dist/plugin/index.js +31 -3
- package/dist/plugin/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/compiler/ir-serialize.ts +41 -2
- package/src/version.ts +1 -1
package/dist/version.d.ts
CHANGED
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
* Kept in sync with `package.json` by `test/unit/version-sync.test.ts`, which fails
|
|
14
14
|
* the build if this constant drifts from the published version.
|
|
15
15
|
*/
|
|
16
|
-
export declare const PARSEMAN_VERSION = "0.50.
|
|
16
|
+
export declare const PARSEMAN_VERSION = "0.50.5";
|
|
17
17
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -321,6 +321,33 @@ class Serializer {
|
|
|
321
321
|
return c._def.tag === 'lazy' && ruleNameOf(c) !== undefined ? (lazyTarget(c) ?? c) : c
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
+
/**
|
|
325
|
+
* The child a rule-entry grammar scope should serialize as its body, when that
|
|
326
|
+
* scope merely WRAPS the rule's own named `lazy` proxy.
|
|
327
|
+
*
|
|
328
|
+
* `rules({ trackLines: true }, …)` wraps every rule VALUE — which is that rule's
|
|
329
|
+
* own named lazy proxy — in a `grammarParser({ trackLines: true })` scope
|
|
330
|
+
* (`parser.ts:229-242`). `body()` unwraps a BARE lazy entry to its defined target;
|
|
331
|
+
* a lazy wrapped one level deep by that scope must be unwrapped INSIDE the scope
|
|
332
|
+
* too. Left wrapped, the inner proxy serializes as a `g[name]` SELF-reference and
|
|
333
|
+
* the rule's real body is dropped, so it re-lowers to `Name: parser(opts, g.Name)`
|
|
334
|
+
* — a bodyless self-cycle the table encoder rejects with `alias cycle — lazy (rule
|
|
335
|
+
* 'Name') encodes to its own recursion trampoline`. This is why the four
|
|
336
|
+
* `*PositionsGrammar` exports fell back to a runtime `compose()` under trackLines.
|
|
337
|
+
*
|
|
338
|
+
* STRICT: only a scope that IS a rule entry (in `localRuleNames`) AND wraps ITS
|
|
339
|
+
* OWN name unwraps. A scope wrapping another rule's ref (a genuine cross-rule
|
|
340
|
+
* alias, `Name: parser(opts, g.Other)`) or a real body is untouched, so the
|
|
341
|
+
* non-trackLines and non-self-wrap output stays byte-identical.
|
|
342
|
+
*/
|
|
343
|
+
private scopeSelfBody(c: Comb): Comb | undefined {
|
|
344
|
+
const name = this.localRuleNames.get(c)
|
|
345
|
+
if (name === undefined || c._def.tag !== 'grammar') return undefined
|
|
346
|
+
const inner = c._def.parser
|
|
347
|
+
if (inner._def.tag !== 'lazy' || ruleNameOf(inner) !== name) return undefined
|
|
348
|
+
return lazyTarget(inner) ?? undefined
|
|
349
|
+
}
|
|
350
|
+
|
|
324
351
|
run(): string {
|
|
325
352
|
for (const [, c] of this.ruleMap) this.analyze(this.body(c), new Set())
|
|
326
353
|
for (const c of this.scanSkip) { this.assertNoRuleRef(c, new Set()); this.analyze(c, new Set()) }
|
|
@@ -415,7 +442,19 @@ class Serializer {
|
|
|
415
442
|
return
|
|
416
443
|
}
|
|
417
444
|
active.add(c)
|
|
418
|
-
|
|
445
|
+
// When a rule-entry scope wraps its own named lazy, substitute the lazy's
|
|
446
|
+
// unwrapped body for `def.parser` — but keep the scope's OTHER children (its
|
|
447
|
+
// `triviaParser`) in the analysis, exactly as `childrenOf('grammar')` returns
|
|
448
|
+
// both. Dropping the trivia parser here would leave a recursive/shared trivia
|
|
449
|
+
// unanalysed, so its const/self-ref hoisting would be missing when `expr` emits
|
|
450
|
+
// it via `kid(def.triviaParser)`. selfBody is non-undefined only for `'grammar'`.
|
|
451
|
+
const selfBody = def.tag === 'grammar' ? this.scopeSelfBody(c) : undefined
|
|
452
|
+
const kids = selfBody === undefined
|
|
453
|
+
? childrenOf(def)
|
|
454
|
+
: def.tag === 'grammar' && def.triviaParser
|
|
455
|
+
? [selfBody, def.triviaParser]
|
|
456
|
+
: [selfBody]
|
|
457
|
+
for (const child of kids) this.analyze(child, active)
|
|
419
458
|
active.delete(c)
|
|
420
459
|
}
|
|
421
460
|
|
|
@@ -602,7 +641,7 @@ class Serializer {
|
|
|
602
641
|
: spec
|
|
603
642
|
? `classifiedTrivia({ ${spec.arms.map(arm => `${JSON.stringify(arm.label)}: ${kid(arm.parser)}`).join(', ')} })`
|
|
604
643
|
: def.triviaParser ? kid(def.triviaParser) : 'undefined'
|
|
605
|
-
return `parser({ trivia: ${trivia}${def.captureTrivia ? ', captureTrivia: true' : ''}${def.rootCapture ? `, rootCapture: ${JSON.stringify(def.rootCapture)}` : ''}${def.trackLines ? ', trackLines: true' : ''} }, ${kid(def.parser)})`
|
|
644
|
+
return `parser({ trivia: ${trivia}${def.captureTrivia ? ', captureTrivia: true' : ''}${def.rootCapture ? `, rootCapture: ${JSON.stringify(def.rootCapture)}` : ''}${def.trackLines ? ', trackLines: true' : ''} }, ${kid(this.scopeSelfBody(c) ?? def.parser)})`
|
|
606
645
|
}
|
|
607
646
|
case 'withCtx': {
|
|
608
647
|
// A `withCtx` round-trips through `_wc`, which rebuilds it AND re-attaches
|
package/src/version.ts
CHANGED