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/index.js
CHANGED
|
@@ -35,10 +35,20 @@ function classifyFinalChoice(arms, resolve) {
|
|
|
35
35
|
}
|
|
36
36
|
return { exclusive, firstSets, nullable: nullable2 };
|
|
37
37
|
}
|
|
38
|
-
function
|
|
38
|
+
function winnerForRef(p, resolve) {
|
|
39
39
|
if (resolve === void 0) return void 0;
|
|
40
40
|
const name = p._ruleName;
|
|
41
|
-
|
|
41
|
+
const w = name === void 0 ? void 0 : resolve(name);
|
|
42
|
+
if (w === void 0 || w === p) return void 0;
|
|
43
|
+
let cur = w;
|
|
44
|
+
for (const seen = /* @__PURE__ */ new Set(); !seen.has(cur); ) {
|
|
45
|
+
if (cur === p) return void 0;
|
|
46
|
+
seen.add(cur);
|
|
47
|
+
const cd = cur._def;
|
|
48
|
+
if (cd.tag !== "grammar" && cd.tag !== "trivia") return w;
|
|
49
|
+
cur = cd.parser;
|
|
50
|
+
}
|
|
51
|
+
return w;
|
|
42
52
|
}
|
|
43
53
|
function union(a, b) {
|
|
44
54
|
if (a.kind === "any" || b.kind === "any") return { kind: "any" };
|
|
@@ -136,13 +146,15 @@ function matchesEmptyBody(p, seen, resolve) {
|
|
|
136
146
|
case "grammar":
|
|
137
147
|
case "recover":
|
|
138
148
|
return me(d.parser);
|
|
139
|
-
case "lazy":
|
|
149
|
+
case "lazy": {
|
|
150
|
+
const w = winnerForRef(p, resolve);
|
|
151
|
+
if (w !== void 0) return me(w);
|
|
140
152
|
try {
|
|
141
153
|
return me(d.thunk());
|
|
142
154
|
} catch {
|
|
143
|
-
|
|
144
|
-
return t ? me(t) : true;
|
|
155
|
+
return true;
|
|
145
156
|
}
|
|
157
|
+
}
|
|
146
158
|
default:
|
|
147
159
|
return true;
|
|
148
160
|
}
|
|
@@ -206,13 +218,15 @@ function firstSetBody(p, seen, resolve) {
|
|
|
206
218
|
// terminals: no refs, cached set is exact
|
|
207
219
|
case "dispatch":
|
|
208
220
|
return fs(d.selector);
|
|
209
|
-
case "lazy":
|
|
221
|
+
case "lazy": {
|
|
222
|
+
const w = winnerForRef(p, resolve);
|
|
223
|
+
if (w !== void 0) return fs(w);
|
|
210
224
|
try {
|
|
211
225
|
return fs(d.thunk());
|
|
212
226
|
} catch {
|
|
213
|
-
|
|
214
|
-
return t ? fs(t) : any();
|
|
227
|
+
return any();
|
|
215
228
|
}
|
|
229
|
+
}
|
|
216
230
|
case "choice": {
|
|
217
231
|
let out = empty();
|
|
218
232
|
for (const arm of d.parsers) out = union(out, fs(arm));
|
|
@@ -8066,7 +8080,7 @@ var Encoder = class {
|
|
|
8066
8080
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
8067
8081
|
);
|
|
8068
8082
|
if (matchesEmpty(d.parser)) return body;
|
|
8069
|
-
const fs = d.parser._meta.firstSet;
|
|
8083
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
8070
8084
|
if (fs.kind === "any") return body;
|
|
8071
8085
|
const cls = this.charClass(fs);
|
|
8072
8086
|
if (cls < 0) return body;
|
|
@@ -8180,7 +8194,7 @@ var Encoder = class {
|
|
|
8180
8194
|
case "attempt": {
|
|
8181
8195
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
|
|
8182
8196
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
8183
|
-
const fs = d.parser._meta.firstSet;
|
|
8197
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
8184
8198
|
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
8185
8199
|
const cls = this.charClass(fs);
|
|
8186
8200
|
if (cls < 0) return inner;
|
|
@@ -16972,6 +16986,32 @@ var Serializer = class {
|
|
|
16972
16986
|
body(c) {
|
|
16973
16987
|
return c._def.tag === "lazy" && ruleNameOf4(c) !== void 0 ? lazyTarget(c) ?? c : c;
|
|
16974
16988
|
}
|
|
16989
|
+
/**
|
|
16990
|
+
* The child a rule-entry grammar scope should serialize as its body, when that
|
|
16991
|
+
* scope merely WRAPS the rule's own named `lazy` proxy.
|
|
16992
|
+
*
|
|
16993
|
+
* `rules({ trackLines: true }, …)` wraps every rule VALUE — which is that rule's
|
|
16994
|
+
* own named lazy proxy — in a `grammarParser({ trackLines: true })` scope
|
|
16995
|
+
* (`parser.ts:229-242`). `body()` unwraps a BARE lazy entry to its defined target;
|
|
16996
|
+
* a lazy wrapped one level deep by that scope must be unwrapped INSIDE the scope
|
|
16997
|
+
* too. Left wrapped, the inner proxy serializes as a `g[name]` SELF-reference and
|
|
16998
|
+
* the rule's real body is dropped, so it re-lowers to `Name: parser(opts, g.Name)`
|
|
16999
|
+
* — a bodyless self-cycle the table encoder rejects with `alias cycle — lazy (rule
|
|
17000
|
+
* 'Name') encodes to its own recursion trampoline`. This is why the four
|
|
17001
|
+
* `*PositionsGrammar` exports fell back to a runtime `compose()` under trackLines.
|
|
17002
|
+
*
|
|
17003
|
+
* STRICT: only a scope that IS a rule entry (in `localRuleNames`) AND wraps ITS
|
|
17004
|
+
* OWN name unwraps. A scope wrapping another rule's ref (a genuine cross-rule
|
|
17005
|
+
* alias, `Name: parser(opts, g.Other)`) or a real body is untouched, so the
|
|
17006
|
+
* non-trackLines and non-self-wrap output stays byte-identical.
|
|
17007
|
+
*/
|
|
17008
|
+
scopeSelfBody(c) {
|
|
17009
|
+
const name = this.localRuleNames.get(c);
|
|
17010
|
+
if (name === void 0 || c._def.tag !== "grammar") return void 0;
|
|
17011
|
+
const inner = c._def.parser;
|
|
17012
|
+
if (inner._def.tag !== "lazy" || ruleNameOf4(inner) !== name) return void 0;
|
|
17013
|
+
return lazyTarget(inner) ?? void 0;
|
|
17014
|
+
}
|
|
16975
17015
|
run() {
|
|
16976
17016
|
for (const [, c] of this.ruleMap) this.analyze(this.body(c), /* @__PURE__ */ new Set());
|
|
16977
17017
|
for (const c of this.scanSkip) {
|
|
@@ -17041,7 +17081,9 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
17041
17081
|
return;
|
|
17042
17082
|
}
|
|
17043
17083
|
active.add(c);
|
|
17044
|
-
|
|
17084
|
+
const selfBody = def.tag === "grammar" ? this.scopeSelfBody(c) : void 0;
|
|
17085
|
+
const kids = selfBody === void 0 ? childrenOf3(def) : def.tag === "grammar" && def.triviaParser ? [selfBody, def.triviaParser] : [selfBody];
|
|
17086
|
+
for (const child of kids) this.analyze(child, active);
|
|
17045
17087
|
active.delete(c);
|
|
17046
17088
|
}
|
|
17047
17089
|
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
@@ -17207,7 +17249,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
17207
17249
|
const spec = classified && def.triviaParser ? analyzeLabeledTrivia(def.triviaParser) : null;
|
|
17208
17250
|
if (classified && !spec) throw new Unserializable("classified trivia without labeled arms");
|
|
17209
17251
|
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";
|
|
17210
|
-
return `parser({ trivia: ${trivia2}${def.captureTrivia ? ", captureTrivia: true" : ""}${def.rootCapture ? `, rootCapture: ${JSON.stringify(def.rootCapture)}` : ""}${def.trackLines ? ", trackLines: true" : ""} }, ${kid(def.parser)})`;
|
|
17252
|
+
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)})`;
|
|
17211
17253
|
}
|
|
17212
17254
|
case "withCtx": {
|
|
17213
17255
|
if (def.extraSrc === void 0) throw new Unserializable("withCtx without extraSrc");
|
|
@@ -17343,7 +17385,7 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
17343
17385
|
}
|
|
17344
17386
|
|
|
17345
17387
|
// src/version.ts
|
|
17346
|
-
var PARSEMAN_VERSION = "0.50.
|
|
17388
|
+
var PARSEMAN_VERSION = "0.50.5";
|
|
17347
17389
|
|
|
17348
17390
|
// src/compiler/compile-linkable-table.ts
|
|
17349
17391
|
function isLocal(rule) {
|