parseman 0.50.6 → 0.50.7
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 +49 -46
- package/dist/analysis/diagnostics.js.map +2 -2
- package/dist/cli/index.js +49 -46
- package/dist/cli/index.js.map +2 -2
- package/dist/combinators/first-set.d.ts +2 -26
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +38 -27
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/index.js +50 -47
- package/dist/index.js.map +2 -2
- package/dist/plugin/index.js +50 -47
- package/dist/plugin/index.js.map +2 -2
- package/dist/spec/index.js +37 -36
- package/dist/spec/index.js.map +2 -2
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/index.js +49 -46
- package/dist/table/index.js.map +2 -2
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/combinators/first-set.ts +58 -36
- package/src/table/encode.ts +10 -8
- package/src/version.ts +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// src/combinators/first-set.ts
|
|
2
|
-
function classifyFinalChoice(arms, resolve) {
|
|
2
|
+
function classifyFinalChoice(arms, resolve, activeTrivia) {
|
|
3
3
|
const firstSets = [];
|
|
4
4
|
const nullable2 = [];
|
|
5
5
|
let exclusive = true;
|
|
6
6
|
for (const arm of arms) {
|
|
7
7
|
const empty2 = matchesEmpty(arm, /* @__PURE__ */ new Set(), resolve);
|
|
8
8
|
nullable2.push(empty2);
|
|
9
|
-
firstSets.push(empty2 ? { kind: "any" } : firstSetOf(arm, /* @__PURE__ */ new Set(), resolve));
|
|
9
|
+
firstSets.push(empty2 ? { kind: "any" } : firstSetOf(arm, /* @__PURE__ */ new Set(), resolve, activeTrivia));
|
|
10
10
|
if (empty2) exclusive = false;
|
|
11
11
|
}
|
|
12
12
|
if (exclusive) {
|
|
@@ -67,7 +67,7 @@ function intersects(a, b) {
|
|
|
67
67
|
return false;
|
|
68
68
|
}
|
|
69
69
|
function fromChar(code) {
|
|
70
|
-
return
|
|
70
|
+
return fromRange(code, code);
|
|
71
71
|
}
|
|
72
72
|
function startsFirstSet(combinator, input, pos) {
|
|
73
73
|
const fs = combinator._meta.firstSet;
|
|
@@ -160,11 +160,10 @@ function matchesEmptyBody(p, seen, resolve) {
|
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
function isZeroWidthAssertion(p) {
|
|
163
|
-
|
|
164
|
-
return tag === "not" || tag === "adjacency";
|
|
163
|
+
return p._tag === "not" || p._tag === "adjacency";
|
|
165
164
|
}
|
|
166
165
|
function isPositiveLookahead(p) {
|
|
167
|
-
return p.
|
|
166
|
+
return p._tag === "peek";
|
|
168
167
|
}
|
|
169
168
|
function narrowBy(acc, constraint) {
|
|
170
169
|
if (constraint.kind === "any") return acc;
|
|
@@ -180,34 +179,42 @@ function narrowBy(acc, constraint) {
|
|
|
180
179
|
return ranges.length === 0 ? { kind: "empty" } : { kind: "ranges", ranges };
|
|
181
180
|
}
|
|
182
181
|
function applyAssertion(fs, assertion) {
|
|
183
|
-
|
|
184
|
-
if (fs.kind === "empty") return assertion;
|
|
185
|
-
return narrowBy(fs, assertion) ?? fs;
|
|
182
|
+
return assertion === null ? fs : fs.kind === "empty" ? assertion : narrowBy(fs, assertion);
|
|
186
183
|
}
|
|
187
|
-
function
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
function sequenceSet(parsers, fs, empties, trivia2) {
|
|
185
|
+
const afterBoundary = (i) => {
|
|
186
|
+
const rest = at(i);
|
|
187
|
+
return trivia2 ? union(rest, fs(trivia2)) : rest;
|
|
188
|
+
};
|
|
189
|
+
const at = (i) => {
|
|
190
|
+
const p = parsers[i];
|
|
191
191
|
if (isPositiveLookahead(p)) {
|
|
192
|
-
|
|
193
|
-
|
|
192
|
+
const constraint = fs(p);
|
|
193
|
+
return i + 1 === parsers.length ? constraint : applyAssertion(afterBoundary(i + 1), constraint);
|
|
194
194
|
}
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
195
|
+
if (isZeroWidthAssertion(p)) {
|
|
196
|
+
return i + 1 === parsers.length ? empty() : afterBoundary(i + 1);
|
|
197
|
+
}
|
|
198
|
+
const first = fs(p);
|
|
199
|
+
if (!empties(p) || i + 1 === parsers.length) return first;
|
|
200
|
+
return union(first, afterBoundary(i + 1));
|
|
201
|
+
};
|
|
202
|
+
return at(0);
|
|
203
|
+
}
|
|
204
|
+
function sequenceFirstSet(parsers) {
|
|
205
|
+
return sequenceSet(parsers, (p) => p._meta.firstSet, matchesEmpty);
|
|
199
206
|
}
|
|
200
|
-
function firstSetOf(p, seen = /* @__PURE__ */ new Set(), resolve) {
|
|
207
|
+
function firstSetOf(p, seen = /* @__PURE__ */ new Set(), resolve, activeTrivia) {
|
|
201
208
|
if (seen.has(p)) return any();
|
|
202
209
|
seen.add(p);
|
|
203
210
|
try {
|
|
204
|
-
return firstSetBody(p, seen, resolve);
|
|
211
|
+
return firstSetBody(p, seen, resolve, activeTrivia);
|
|
205
212
|
} finally {
|
|
206
213
|
seen.delete(p);
|
|
207
214
|
}
|
|
208
215
|
}
|
|
209
|
-
function firstSetBody(p, seen, resolve) {
|
|
210
|
-
const fs = (c) => firstSetOf(c, seen, resolve);
|
|
216
|
+
function firstSetBody(p, seen, resolve, activeTrivia) {
|
|
217
|
+
const fs = (c) => firstSetOf(c, seen, resolve, activeTrivia);
|
|
211
218
|
const empties = (c) => matchesEmpty(c, /* @__PURE__ */ new Set(), resolve);
|
|
212
219
|
const d = p._def;
|
|
213
220
|
switch (d.tag) {
|
|
@@ -233,17 +240,7 @@ function firstSetBody(p, seen, resolve) {
|
|
|
233
240
|
return out;
|
|
234
241
|
}
|
|
235
242
|
case "sequence": {
|
|
236
|
-
|
|
237
|
-
let assertion = null;
|
|
238
|
-
for (const term of d.parsers) {
|
|
239
|
-
if (isPositiveLookahead(term)) {
|
|
240
|
-
assertion = narrowBy(assertion, fs(term));
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
if (!isZeroWidthAssertion(term)) out = union(out, fs(term));
|
|
244
|
-
if (!empties(term)) return applyAssertion(out, assertion);
|
|
245
|
-
}
|
|
246
|
-
return applyAssertion(out, assertion);
|
|
243
|
+
return sequenceSet(d.parsers, fs, empties, activeTrivia);
|
|
247
244
|
}
|
|
248
245
|
case "peek": {
|
|
249
246
|
const inner = d.parser;
|
|
@@ -258,12 +255,16 @@ function firstSetBody(p, seen, resolve) {
|
|
|
258
255
|
case "token":
|
|
259
256
|
case "leaf":
|
|
260
257
|
case "node":
|
|
261
|
-
case "grammar":
|
|
262
|
-
case "expect":
|
|
263
|
-
return fs(d.parser);
|
|
264
258
|
case "sepBy":
|
|
259
|
+
case "expect":
|
|
265
260
|
return fs(d.parser);
|
|
266
|
-
|
|
261
|
+
case "grammar":
|
|
262
|
+
return firstSetOf(
|
|
263
|
+
d.parser,
|
|
264
|
+
seen,
|
|
265
|
+
resolve,
|
|
266
|
+
d.clearTrivia ? null : d.triviaParser ?? activeTrivia
|
|
267
|
+
);
|
|
267
268
|
default:
|
|
268
269
|
return p._meta.firstSet;
|
|
269
270
|
}
|
|
@@ -6495,7 +6496,9 @@ var Encoder = class {
|
|
|
6495
6496
|
followClass(parsers, i) {
|
|
6496
6497
|
let fs = { kind: "empty" };
|
|
6497
6498
|
const rr = this.refResolver();
|
|
6498
|
-
for (let j = i + 1; j < parsers.length; j++)
|
|
6499
|
+
for (let j = i + 1; j < parsers.length; j++) {
|
|
6500
|
+
fs = union(fs, firstSetOf(parsers[j], /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
6501
|
+
}
|
|
6499
6502
|
return this.charClass(fs);
|
|
6500
6503
|
}
|
|
6501
6504
|
constant(v) {
|
|
@@ -6712,7 +6715,7 @@ var Encoder = class {
|
|
|
6712
6715
|
*/
|
|
6713
6716
|
subtree(c) {
|
|
6714
6717
|
const ip = this.node(c).ip;
|
|
6715
|
-
const fs = firstSetOf(c, /* @__PURE__ */ new Set(), this.refResolver());
|
|
6718
|
+
const fs = firstSetOf(c, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia);
|
|
6716
6719
|
return [ip, fs.kind === "empty" ? -2 : this.charClass(fs)];
|
|
6717
6720
|
}
|
|
6718
6721
|
/** Pool one scan spec. One per combinator: `node()` memoizes by identity. */
|
|
@@ -6931,12 +6934,12 @@ var Encoder = class {
|
|
|
6931
6934
|
return this.covWrap(gated, armCovIds?.[src], 1);
|
|
6932
6935
|
});
|
|
6933
6936
|
const rr = this.refResolver();
|
|
6934
|
-
const finalChoice = classifyFinalChoice(arms, rr);
|
|
6937
|
+
const finalChoice = classifyFinalChoice(arms, rr, this.activeTrivia);
|
|
6935
6938
|
const transactionalFirst = arms.map((arm, i) => {
|
|
6936
6939
|
if (!finalChoice.nullable[i]) return void 0;
|
|
6937
6940
|
const def = arm._def;
|
|
6938
6941
|
if (def.tag !== "attempt" || matchesEmpty(def.parser, /* @__PURE__ */ new Set(), rr)) return void 0;
|
|
6939
|
-
return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr);
|
|
6942
|
+
return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia);
|
|
6940
6943
|
});
|
|
6941
6944
|
const gateFirst = finalChoice.firstSets.map((first, i) => transactionalFirst[i] ?? first);
|
|
6942
6945
|
const classes = gateFirst.map((first, i) => finalChoice.nullable[i] && transactionalFirst[i] === void 0 ? -1 : this.charClass(first));
|
|
@@ -6983,7 +6986,7 @@ var Encoder = class {
|
|
|
6983
6986
|
case "oneOrMore": {
|
|
6984
6987
|
const child = this.node(d.parser).ip;
|
|
6985
6988
|
const rr = this.refResolver();
|
|
6986
|
-
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.existingCharClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr));
|
|
6989
|
+
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.existingCharClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
6987
6990
|
const op = d.valueUnused ? OP_REPV : OP_REP;
|
|
6988
6991
|
const min = d.tag === "many" ? 0 : d.min;
|
|
6989
6992
|
return this.rec ? this.emit(op, child, min, d.max ?? -1, -1, 0, this.expected(deriveExpected(d.parser)), itemClass) : this.emit(op, child, min, d.max ?? -1, -1, 0);
|
|
@@ -7001,7 +7004,7 @@ var Encoder = class {
|
|
|
7001
7004
|
sep,
|
|
7002
7005
|
flags,
|
|
7003
7006
|
this.expected(deriveExpected(d.parser)),
|
|
7004
|
-
this.charClass(firstSetOf(d.separator, /* @__PURE__ */ new Set(), this.refResolver()))
|
|
7007
|
+
this.charClass(firstSetOf(d.separator, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia))
|
|
7005
7008
|
);
|
|
7006
7009
|
}
|
|
7007
7010
|
return d.min >= 2 ? this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags, this.expected(deriveExpected(d.parser))) : this.emit(OP_REP, child, d.min, d.max ?? -1, sep, flags);
|
|
@@ -7056,7 +7059,7 @@ var Encoder = class {
|
|
|
7056
7059
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
7057
7060
|
);
|
|
7058
7061
|
if (matchesEmpty(d.parser)) return body;
|
|
7059
|
-
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
7062
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : d.parser._meta.firstSet;
|
|
7060
7063
|
if (fs.kind === "any") return body;
|
|
7061
7064
|
const cls = this.charClass(fs);
|
|
7062
7065
|
if (cls < 0) return body;
|
|
@@ -7170,7 +7173,7 @@ var Encoder = class {
|
|
|
7170
7173
|
case "attempt": {
|
|
7171
7174
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
|
|
7172
7175
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
7173
|
-
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
7176
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : d.parser._meta.firstSet;
|
|
7174
7177
|
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
7175
7178
|
const cls = this.charClass(fs);
|
|
7176
7179
|
if (cls < 0) return inner;
|