parseman 0.50.3 → 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/analysis/diagnostics.js +24 -10
- package/dist/analysis/diagnostics.js.map +2 -2
- package/dist/cli/index.js +24 -10
- package/dist/cli/index.js.map +2 -2
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +22 -8
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/index.js +55 -13
- package/dist/index.js.map +1 -1
- package/dist/plugin/index.js +55 -13
- package/dist/plugin/index.js.map +1 -1
- package/dist/spec/index.js +22 -8
- package/dist/spec/index.js.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/index.js +24 -10
- package/dist/table/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
- package/src/combinators/first-set.ts +33 -7
- package/src/compiler/ir-serialize.ts +41 -2
- package/src/table/encode.ts +14 -2
- package/src/version.ts +1 -1
package/dist/plugin/index.js
CHANGED
|
@@ -43,10 +43,20 @@ function classifyFinalChoice(arms, resolve3) {
|
|
|
43
43
|
}
|
|
44
44
|
return { exclusive, firstSets, nullable: nullable2 };
|
|
45
45
|
}
|
|
46
|
-
function
|
|
46
|
+
function winnerForRef(p, resolve3) {
|
|
47
47
|
if (resolve3 === void 0) return void 0;
|
|
48
48
|
const name = p._ruleName;
|
|
49
|
-
|
|
49
|
+
const w = name === void 0 ? void 0 : resolve3(name);
|
|
50
|
+
if (w === void 0 || w === p) return void 0;
|
|
51
|
+
let cur = w;
|
|
52
|
+
for (const seen = /* @__PURE__ */ new Set(); !seen.has(cur); ) {
|
|
53
|
+
if (cur === p) return void 0;
|
|
54
|
+
seen.add(cur);
|
|
55
|
+
const cd = cur._def;
|
|
56
|
+
if (cd.tag !== "grammar" && cd.tag !== "trivia") return w;
|
|
57
|
+
cur = cd.parser;
|
|
58
|
+
}
|
|
59
|
+
return w;
|
|
50
60
|
}
|
|
51
61
|
function union(a, b) {
|
|
52
62
|
if (a.kind === "any" || b.kind === "any") return { kind: "any" };
|
|
@@ -144,13 +154,15 @@ function matchesEmptyBody(p, seen, resolve3) {
|
|
|
144
154
|
case "grammar":
|
|
145
155
|
case "recover":
|
|
146
156
|
return me(d.parser);
|
|
147
|
-
case "lazy":
|
|
157
|
+
case "lazy": {
|
|
158
|
+
const w = winnerForRef(p, resolve3);
|
|
159
|
+
if (w !== void 0) return me(w);
|
|
148
160
|
try {
|
|
149
161
|
return me(d.thunk());
|
|
150
162
|
} catch {
|
|
151
|
-
|
|
152
|
-
return t ? me(t) : true;
|
|
163
|
+
return true;
|
|
153
164
|
}
|
|
165
|
+
}
|
|
154
166
|
default:
|
|
155
167
|
return true;
|
|
156
168
|
}
|
|
@@ -214,13 +226,15 @@ function firstSetBody(p, seen, resolve3) {
|
|
|
214
226
|
// terminals: no refs, cached set is exact
|
|
215
227
|
case "dispatch":
|
|
216
228
|
return fs3(d.selector);
|
|
217
|
-
case "lazy":
|
|
229
|
+
case "lazy": {
|
|
230
|
+
const w = winnerForRef(p, resolve3);
|
|
231
|
+
if (w !== void 0) return fs3(w);
|
|
218
232
|
try {
|
|
219
233
|
return fs3(d.thunk());
|
|
220
234
|
} catch {
|
|
221
|
-
|
|
222
|
-
return t ? fs3(t) : any();
|
|
235
|
+
return any();
|
|
223
236
|
}
|
|
237
|
+
}
|
|
224
238
|
case "choice": {
|
|
225
239
|
let out = empty();
|
|
226
240
|
for (const arm of d.parsers) out = union(out, fs3(arm));
|
|
@@ -7665,7 +7679,7 @@ var Encoder = class {
|
|
|
7665
7679
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
7666
7680
|
);
|
|
7667
7681
|
if (matchesEmpty(d.parser)) return body;
|
|
7668
|
-
const fs3 = d.parser._meta.firstSet;
|
|
7682
|
+
const fs3 = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
7669
7683
|
if (fs3.kind === "any") return body;
|
|
7670
7684
|
const cls = this.charClass(fs3);
|
|
7671
7685
|
if (cls < 0) return body;
|
|
@@ -7779,7 +7793,7 @@ var Encoder = class {
|
|
|
7779
7793
|
case "attempt": {
|
|
7780
7794
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
|
|
7781
7795
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
7782
|
-
const fs3 = d.parser._meta.firstSet;
|
|
7796
|
+
const fs3 = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
7783
7797
|
if (fs3.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
7784
7798
|
const cls = this.charClass(fs3);
|
|
7785
7799
|
if (cls < 0) return inner;
|
|
@@ -16555,6 +16569,32 @@ var Serializer = class {
|
|
|
16555
16569
|
body(c) {
|
|
16556
16570
|
return c._def.tag === "lazy" && ruleNameOf3(c) !== void 0 ? lazyTarget(c) ?? c : c;
|
|
16557
16571
|
}
|
|
16572
|
+
/**
|
|
16573
|
+
* The child a rule-entry grammar scope should serialize as its body, when that
|
|
16574
|
+
* scope merely WRAPS the rule's own named `lazy` proxy.
|
|
16575
|
+
*
|
|
16576
|
+
* `rules({ trackLines: true }, …)` wraps every rule VALUE — which is that rule's
|
|
16577
|
+
* own named lazy proxy — in a `grammarParser({ trackLines: true })` scope
|
|
16578
|
+
* (`parser.ts:229-242`). `body()` unwraps a BARE lazy entry to its defined target;
|
|
16579
|
+
* a lazy wrapped one level deep by that scope must be unwrapped INSIDE the scope
|
|
16580
|
+
* too. Left wrapped, the inner proxy serializes as a `g[name]` SELF-reference and
|
|
16581
|
+
* the rule's real body is dropped, so it re-lowers to `Name: parser(opts, g.Name)`
|
|
16582
|
+
* — a bodyless self-cycle the table encoder rejects with `alias cycle — lazy (rule
|
|
16583
|
+
* 'Name') encodes to its own recursion trampoline`. This is why the four
|
|
16584
|
+
* `*PositionsGrammar` exports fell back to a runtime `compose()` under trackLines.
|
|
16585
|
+
*
|
|
16586
|
+
* STRICT: only a scope that IS a rule entry (in `localRuleNames`) AND wraps ITS
|
|
16587
|
+
* OWN name unwraps. A scope wrapping another rule's ref (a genuine cross-rule
|
|
16588
|
+
* alias, `Name: parser(opts, g.Other)`) or a real body is untouched, so the
|
|
16589
|
+
* non-trackLines and non-self-wrap output stays byte-identical.
|
|
16590
|
+
*/
|
|
16591
|
+
scopeSelfBody(c) {
|
|
16592
|
+
const name = this.localRuleNames.get(c);
|
|
16593
|
+
if (name === void 0 || c._def.tag !== "grammar") return void 0;
|
|
16594
|
+
const inner = c._def.parser;
|
|
16595
|
+
if (inner._def.tag !== "lazy" || ruleNameOf3(inner) !== name) return void 0;
|
|
16596
|
+
return lazyTarget(inner) ?? void 0;
|
|
16597
|
+
}
|
|
16558
16598
|
run() {
|
|
16559
16599
|
for (const [, c] of this.ruleMap) this.analyze(this.body(c), /* @__PURE__ */ new Set());
|
|
16560
16600
|
for (const c of this.scanSkip) {
|
|
@@ -16624,7 +16664,9 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
16624
16664
|
return;
|
|
16625
16665
|
}
|
|
16626
16666
|
active.add(c);
|
|
16627
|
-
|
|
16667
|
+
const selfBody = def.tag === "grammar" ? this.scopeSelfBody(c) : void 0;
|
|
16668
|
+
const kids = selfBody === void 0 ? childrenOf3(def) : def.tag === "grammar" && def.triviaParser ? [selfBody, def.triviaParser] : [selfBody];
|
|
16669
|
+
for (const child of kids) this.analyze(child, active);
|
|
16628
16670
|
active.delete(c);
|
|
16629
16671
|
}
|
|
16630
16672
|
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
@@ -16790,7 +16832,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
16790
16832
|
const spec = classified && def.triviaParser ? analyzeLabeledTrivia(def.triviaParser) : null;
|
|
16791
16833
|
if (classified && !spec) throw new Unserializable("classified trivia without labeled arms");
|
|
16792
16834
|
const trivia2 = def.clearTrivia ? "null" : spec ? `classifiedTrivia({ ${spec.arms.map((arm) => `${JSON.stringify(arm.label)}: ${kid(arm.parser)}`).join(", ")} })` : def.triviaParser ? kid(def.triviaParser) : "undefined";
|
|
16793
|
-
return `parser({ trivia: ${trivia2}${def.captureTrivia ? ", captureTrivia: true" : ""}${def.rootCapture ? `, rootCapture: ${JSON.stringify(def.rootCapture)}` : ""}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(def.parser)})`;
|
|
16835
|
+
return `parser({ trivia: ${trivia2}${def.captureTrivia ? ", captureTrivia: true" : ""}${def.rootCapture ? `, rootCapture: ${JSON.stringify(def.rootCapture)}` : ""}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(this.scopeSelfBody(c) ?? def.parser)})`;
|
|
16794
16836
|
}
|
|
16795
16837
|
case "withCtx": {
|
|
16796
16838
|
if (def.extraSrc === void 0) throw new Unserializable("withCtx without extraSrc");
|
|
@@ -16926,7 +16968,7 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
16926
16968
|
}
|
|
16927
16969
|
|
|
16928
16970
|
// src/version.ts
|
|
16929
|
-
var PARSEMAN_VERSION = "0.50.
|
|
16971
|
+
var PARSEMAN_VERSION = "0.50.5";
|
|
16930
16972
|
|
|
16931
16973
|
// src/compiler/compile-linkable-table.ts
|
|
16932
16974
|
function isLocal(rule) {
|