parseman 0.50.6 → 0.51.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.
- package/dist/analysis/choice-cost.d.ts.map +1 -1
- package/dist/analysis/commitment.d.ts.map +1 -1
- package/dist/analysis/diagnostics.js +214 -67
- package/dist/analysis/diagnostics.js.map +2 -2
- package/dist/analysis/duplication.d.ts.map +1 -1
- package/dist/analysis/gating.d.ts.map +1 -1
- package/dist/cli/index.js +220 -68
- package/dist/cli/index.js.map +2 -2
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/combinators/first-set.d.ts +2 -26
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/combinators/scanTo.d.ts +23 -1
- package/dist/combinators/scanTo.d.ts.map +1 -1
- package/dist/compiler/fields.d.ts.map +1 -1
- package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +40 -29
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/coverage.d.ts.map +1 -1
- package/dist/cst/reflection.d.ts.map +1 -1
- package/dist/index.js +241 -74
- package/dist/index.js.map +2 -2
- package/dist/plugin/index.js +228 -71
- package/dist/plugin/index.js.map +2 -2
- package/dist/spec/index.js +164 -48
- package/dist/spec/index.js.map +2 -2
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/index.js +220 -68
- package/dist/table/index.js.map +2 -2
- package/dist/table/program.d.ts +2 -0
- package/dist/table/program.d.ts.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/analysis/choice-cost.ts +6 -1
- package/src/analysis/commitment.ts +10 -2
- package/src/analysis/duplication.ts +7 -2
- package/src/analysis/gating.ts +6 -1
- package/src/analysis/rebuild.ts +1 -1
- package/src/combinators/dispatch.ts +4 -1
- package/src/combinators/first-set.ts +58 -36
- package/src/combinators/scanTo.ts +163 -9
- package/src/compiler/fields.ts +8 -2
- package/src/compiler/grammar-coverage-ids.ts +6 -1
- package/src/compiler/ir-serialize.ts +7 -2
- package/src/compiler/token-alphabet.ts +1 -1
- package/src/coverage.ts +7 -1
- package/src/cst/reflection.ts +6 -1
- package/src/table/assemble.ts +11 -1
- package/src/table/emit.ts +4 -0
- package/src/table/encode.ts +16 -8
- package/src/table/exec.ts +7 -1
- package/src/table/program.ts +2 -0
- package/src/types.ts +1 -1
- package/src/version.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -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
|
}
|
|
@@ -3313,7 +3314,7 @@ function parserUsesRouted(parser2, seen = /* @__PURE__ */ new Set()) {
|
|
|
3313
3314
|
case "grammar":
|
|
3314
3315
|
return parserUsesRouted(def.parser, seen) || (def.triviaParser ? parserUsesRouted(def.triviaParser, seen) : false);
|
|
3315
3316
|
case "scanTo":
|
|
3316
|
-
return parserUsesRouted(def.sentinel, seen) || def.skip.some((entry) => parserUsesRouted(entry, seen));
|
|
3317
|
+
return parserUsesRouted(def.sentinel, seen) || def.skip.some((entry) => parserUsesRouted(entry, seen)) || def.recoverAt !== void 0 && parserUsesRouted(def.recoverAt, seen) || def.stopAt !== void 0 && parserUsesRouted(def.stopAt, seen);
|
|
3317
3318
|
case "recover":
|
|
3318
3319
|
return parserUsesRouted(def.parser, seen) || parserUsesRouted(def.sentinel, seen);
|
|
3319
3320
|
case "lazy":
|
|
@@ -4341,7 +4342,12 @@ function childrenOf(def) {
|
|
|
4341
4342
|
case "sepBy":
|
|
4342
4343
|
return [def.parser, def.separator];
|
|
4343
4344
|
case "scanTo":
|
|
4344
|
-
return [
|
|
4345
|
+
return [
|
|
4346
|
+
def.sentinel,
|
|
4347
|
+
...def.skip,
|
|
4348
|
+
...def.recoverAt === void 0 ? [] : [def.recoverAt],
|
|
4349
|
+
...def.stopAt === void 0 ? [] : [def.stopAt]
|
|
4350
|
+
];
|
|
4345
4351
|
case "routed":
|
|
4346
4352
|
return def.fallback ? [def.fallback] : [];
|
|
4347
4353
|
case "literal":
|
|
@@ -4862,7 +4868,7 @@ function parserHasOwnFields(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4862
4868
|
case "grammar":
|
|
4863
4869
|
return parserHasOwnFields(d.parser, seen) || (d.triviaParser ? parserHasOwnFields(d.triviaParser, seen) : false);
|
|
4864
4870
|
case "scanTo":
|
|
4865
|
-
return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen));
|
|
4871
|
+
return parserHasOwnFields(d.sentinel, seen) || d.skip.some((x) => parserHasOwnFields(x, seen)) || d.recoverAt !== void 0 && parserHasOwnFields(d.recoverAt, seen) || d.stopAt !== void 0 && parserHasOwnFields(d.stopAt, seen);
|
|
4866
4872
|
case "recover":
|
|
4867
4873
|
return parserHasOwnFields(d.parser, seen) || parserHasOwnFields(d.sentinel, seen);
|
|
4868
4874
|
case "routed":
|
|
@@ -5245,7 +5251,12 @@ function childrenOf2(d) {
|
|
|
5245
5251
|
case "recover":
|
|
5246
5252
|
return [d.parser, d.sentinel];
|
|
5247
5253
|
case "scanTo":
|
|
5248
|
-
return [
|
|
5254
|
+
return [
|
|
5255
|
+
d.sentinel,
|
|
5256
|
+
...d.skip,
|
|
5257
|
+
...d.recoverAt === void 0 ? [] : [d.recoverAt],
|
|
5258
|
+
...d.stopAt === void 0 ? [] : [d.stopAt]
|
|
5259
|
+
];
|
|
5249
5260
|
case "grammar":
|
|
5250
5261
|
return d.triviaParser ? [d.parser, d.triviaParser] : [d.parser];
|
|
5251
5262
|
case "routed":
|
|
@@ -5892,7 +5903,7 @@ function hasNodeDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
5892
5903
|
case "sepBy":
|
|
5893
5904
|
return hasNodeDef(d.parser, seen) || hasNodeDef(d.separator, seen);
|
|
5894
5905
|
case "scanTo":
|
|
5895
|
-
return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen));
|
|
5906
|
+
return hasNodeDef(d.sentinel, seen) || d.skip.some((x) => hasNodeDef(x, seen)) || d.recoverAt !== void 0 && hasNodeDef(d.recoverAt, seen) || d.stopAt !== void 0 && hasNodeDef(d.stopAt, seen);
|
|
5896
5907
|
case "recover":
|
|
5897
5908
|
return hasNodeDef(d.parser, seen) || hasNodeDef(d.sentinel, seen);
|
|
5898
5909
|
case "expect":
|
|
@@ -5941,7 +5952,7 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
5941
5952
|
case "sepBy":
|
|
5942
5953
|
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.separator, seen);
|
|
5943
5954
|
case "scanTo":
|
|
5944
|
-
return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen));
|
|
5955
|
+
return hasDirectBuildDef(d.sentinel, seen) || d.skip.some((x) => hasDirectBuildDef(x, seen)) || d.recoverAt !== void 0 && hasDirectBuildDef(d.recoverAt, seen) || d.stopAt !== void 0 && hasDirectBuildDef(d.stopAt, seen);
|
|
5945
5956
|
case "recover":
|
|
5946
5957
|
return hasDirectBuildDef(d.parser, seen) || hasDirectBuildDef(d.sentinel, seen);
|
|
5947
5958
|
case "routed":
|
|
@@ -5978,7 +5989,7 @@ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve) {
|
|
|
5978
5989
|
case "withCtx":
|
|
5979
5990
|
return mayCommitFailure(d.parser, seen, resolve);
|
|
5980
5991
|
case "scanTo":
|
|
5981
|
-
return mayCommitFailure(d.sentinel, seen, resolve) || d.skip.some((x) => mayCommitFailure(x, seen, resolve));
|
|
5992
|
+
return mayCommitFailure(d.sentinel, seen, resolve) || d.skip.some((x) => mayCommitFailure(x, seen, resolve)) || d.recoverAt !== void 0 && mayCommitFailure(d.recoverAt, seen, resolve) || d.stopAt !== void 0 && mayCommitFailure(d.stopAt, seen, resolve);
|
|
5982
5993
|
case "lazy": {
|
|
5983
5994
|
try {
|
|
5984
5995
|
return mayCommitFailure(d.thunk(), seen, resolve);
|
|
@@ -7519,7 +7530,9 @@ var Encoder = class {
|
|
|
7519
7530
|
followClass(parsers, i) {
|
|
7520
7531
|
let fs = { kind: "empty" };
|
|
7521
7532
|
const rr = this.refResolver();
|
|
7522
|
-
for (let j = i + 1; j < parsers.length; j++)
|
|
7533
|
+
for (let j = i + 1; j < parsers.length; j++) {
|
|
7534
|
+
fs = union(fs, firstSetOf(parsers[j], /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
7535
|
+
}
|
|
7523
7536
|
return this.charClass(fs);
|
|
7524
7537
|
}
|
|
7525
7538
|
constant(v) {
|
|
@@ -7736,7 +7749,7 @@ var Encoder = class {
|
|
|
7736
7749
|
*/
|
|
7737
7750
|
subtree(c) {
|
|
7738
7751
|
const ip = this.node(c).ip;
|
|
7739
|
-
const fs = firstSetOf(c, /* @__PURE__ */ new Set(), this.refResolver());
|
|
7752
|
+
const fs = firstSetOf(c, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia);
|
|
7740
7753
|
return [ip, fs.kind === "empty" ? -2 : this.charClass(fs)];
|
|
7741
7754
|
}
|
|
7742
7755
|
/** Pool one scan spec. One per combinator: `node()` memoizes by identity. */
|
|
@@ -7882,6 +7895,8 @@ var Encoder = class {
|
|
|
7882
7895
|
flags: (d.raw ? 1 : 0) | (d.orEOF ? 2 : 0),
|
|
7883
7896
|
skip: d.skip.map((c) => this.subtree(c)),
|
|
7884
7897
|
sentinel: this.subtree(d.sentinel),
|
|
7898
|
+
...d.recoverAt === void 0 ? {} : { recoverAt: this.subtree(d.recoverAt) },
|
|
7899
|
+
...d.stopAt === void 0 ? {} : { stopAt: this.subtree(d.stopAt) },
|
|
7885
7900
|
sent: sentDef.tag === "literal" ? sentDef.value : null
|
|
7886
7901
|
}));
|
|
7887
7902
|
}
|
|
@@ -7955,12 +7970,12 @@ var Encoder = class {
|
|
|
7955
7970
|
return this.covWrap(gated, armCovIds?.[src], 1);
|
|
7956
7971
|
});
|
|
7957
7972
|
const rr = this.refResolver();
|
|
7958
|
-
const finalChoice = classifyFinalChoice(arms, rr);
|
|
7973
|
+
const finalChoice = classifyFinalChoice(arms, rr, this.activeTrivia);
|
|
7959
7974
|
const transactionalFirst = arms.map((arm, i) => {
|
|
7960
7975
|
if (!finalChoice.nullable[i]) return void 0;
|
|
7961
7976
|
const def = arm._def;
|
|
7962
7977
|
if (def.tag !== "attempt" || matchesEmpty(def.parser, /* @__PURE__ */ new Set(), rr)) return void 0;
|
|
7963
|
-
return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr);
|
|
7978
|
+
return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia);
|
|
7964
7979
|
});
|
|
7965
7980
|
const gateFirst = finalChoice.firstSets.map((first, i) => transactionalFirst[i] ?? first);
|
|
7966
7981
|
const classes = gateFirst.map((first, i) => finalChoice.nullable[i] && transactionalFirst[i] === void 0 ? -1 : this.charClass(first));
|
|
@@ -8007,7 +8022,7 @@ var Encoder = class {
|
|
|
8007
8022
|
case "oneOrMore": {
|
|
8008
8023
|
const child = this.node(d.parser).ip;
|
|
8009
8024
|
const rr = this.refResolver();
|
|
8010
|
-
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.existingCharClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr));
|
|
8025
|
+
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.existingCharClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
8011
8026
|
const op = d.valueUnused ? OP_REPV : OP_REP;
|
|
8012
8027
|
const min = d.tag === "many" ? 0 : d.min;
|
|
8013
8028
|
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);
|
|
@@ -8025,7 +8040,7 @@ var Encoder = class {
|
|
|
8025
8040
|
sep,
|
|
8026
8041
|
flags,
|
|
8027
8042
|
this.expected(deriveExpected(d.parser)),
|
|
8028
|
-
this.charClass(firstSetOf(d.separator, /* @__PURE__ */ new Set(), this.refResolver()))
|
|
8043
|
+
this.charClass(firstSetOf(d.separator, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia))
|
|
8029
8044
|
);
|
|
8030
8045
|
}
|
|
8031
8046
|
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);
|
|
@@ -8080,7 +8095,7 @@ var Encoder = class {
|
|
|
8080
8095
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
8081
8096
|
);
|
|
8082
8097
|
if (matchesEmpty(d.parser)) return body;
|
|
8083
|
-
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
8098
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : d.parser._meta.firstSet;
|
|
8084
8099
|
if (fs.kind === "any") return body;
|
|
8085
8100
|
const cls = this.charClass(fs);
|
|
8086
8101
|
if (cls < 0) return body;
|
|
@@ -8194,7 +8209,7 @@ var Encoder = class {
|
|
|
8194
8209
|
case "attempt": {
|
|
8195
8210
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
|
|
8196
8211
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
8197
|
-
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
8212
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : d.parser._meta.firstSet;
|
|
8198
8213
|
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
8199
8214
|
const cls = this.charClass(fs);
|
|
8200
8215
|
if (cls < 0) return inner;
|
|
@@ -8315,6 +8330,8 @@ var Encoder = class {
|
|
|
8315
8330
|
const refs = [];
|
|
8316
8331
|
for (const s of this.scans) {
|
|
8317
8332
|
if (s.sentinel !== void 0) refs.push(s.sentinel);
|
|
8333
|
+
if (s.recoverAt !== void 0) refs.push(s.recoverAt);
|
|
8334
|
+
if (s.stopAt !== void 0) refs.push(s.stopAt);
|
|
8318
8335
|
refs.push(...s.skip);
|
|
8319
8336
|
}
|
|
8320
8337
|
for (const set of this.scanSkipSets) refs.push(...set);
|
|
@@ -8334,7 +8351,9 @@ var Encoder = class {
|
|
|
8334
8351
|
this.scans = this.scans.map((s) => ({
|
|
8335
8352
|
...s,
|
|
8336
8353
|
skip: s.skip.map(res),
|
|
8337
|
-
...s.sentinel === void 0 ? {} : { sentinel: res(s.sentinel) }
|
|
8354
|
+
...s.sentinel === void 0 ? {} : { sentinel: res(s.sentinel) },
|
|
8355
|
+
...s.recoverAt === void 0 ? {} : { recoverAt: res(s.recoverAt) },
|
|
8356
|
+
...s.stopAt === void 0 ? {} : { stopAt: res(s.stopAt) }
|
|
8338
8357
|
}));
|
|
8339
8358
|
this.scanSkipSets = this.scanSkipSets.map((set) => set.map(res));
|
|
8340
8359
|
}
|
|
@@ -11581,7 +11600,7 @@ function resolveScanSkip(explicitSkip, raw, ctx) {
|
|
|
11581
11600
|
out.push(...explicitSkip);
|
|
11582
11601
|
return out;
|
|
11583
11602
|
}
|
|
11584
|
-
function scanTo(sentinel, { skip, raw = false, orEOF = false } = {}) {
|
|
11603
|
+
function scanTo(sentinel, { skip, raw = false, orEOF = false, recoverAt, stopAt } = {}) {
|
|
11585
11604
|
const meta = {
|
|
11586
11605
|
firstSet: any(),
|
|
11587
11606
|
canMatchNewline: true,
|
|
@@ -11591,7 +11610,15 @@ function scanTo(sentinel, { skip, raw = false, orEOF = false } = {}) {
|
|
|
11591
11610
|
return {
|
|
11592
11611
|
_tag: "scanTo",
|
|
11593
11612
|
_meta: meta,
|
|
11594
|
-
_def: {
|
|
11613
|
+
_def: {
|
|
11614
|
+
tag: "scanTo",
|
|
11615
|
+
sentinel,
|
|
11616
|
+
skip: explicitSkip,
|
|
11617
|
+
raw,
|
|
11618
|
+
orEOF,
|
|
11619
|
+
...recoverAt === void 0 ? {} : { recoverAt },
|
|
11620
|
+
...stopAt === void 0 ? {} : { stopAt }
|
|
11621
|
+
},
|
|
11595
11622
|
parse(input, pos, ctx) {
|
|
11596
11623
|
let cur = pos;
|
|
11597
11624
|
const skip2 = resolveScanSkip(explicitSkip, raw, ctx);
|
|
@@ -11603,28 +11630,130 @@ function scanTo(sentinel, { skip, raw = false, orEOF = false } = {}) {
|
|
|
11603
11630
|
pushCstLeaf(ctx, leaf2);
|
|
11604
11631
|
}
|
|
11605
11632
|
};
|
|
11606
|
-
|
|
11607
|
-
|
|
11608
|
-
|
|
11633
|
+
if (recoverAt === void 0 && stopAt === void 0) {
|
|
11634
|
+
while (cur < input.length) {
|
|
11635
|
+
const s = sentinel.parse(input, cur, probeCtx);
|
|
11636
|
+
if (s.ok) {
|
|
11637
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
11638
|
+
emit(cur);
|
|
11639
|
+
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
11640
|
+
}
|
|
11641
|
+
let advanced = false;
|
|
11642
|
+
for (const skipper of skip2) {
|
|
11643
|
+
const r = skipper.parse(input, cur, probeCtx);
|
|
11644
|
+
if (r.ok && r.span.end > cur) {
|
|
11645
|
+
cur = r.span.end;
|
|
11646
|
+
advanced = true;
|
|
11647
|
+
break;
|
|
11648
|
+
}
|
|
11649
|
+
}
|
|
11650
|
+
if (!advanced) cur++;
|
|
11651
|
+
}
|
|
11652
|
+
if (orEOF) {
|
|
11609
11653
|
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, cur);
|
|
11610
11654
|
emit(cur);
|
|
11611
11655
|
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
11612
11656
|
}
|
|
11657
|
+
const sentDef2 = sentinel._def;
|
|
11658
|
+
const expected2 = sentDef2.tag === "literal" ? [JSON.stringify(sentDef2.value)] : ["sentinel"];
|
|
11659
|
+
return { ok: false, expected: expected2, span: { start: pos, end: cur } };
|
|
11660
|
+
}
|
|
11661
|
+
let recovery = -1;
|
|
11662
|
+
let firstSentinel = -1;
|
|
11663
|
+
let sentinelCount = 0;
|
|
11664
|
+
let recoveryErrorCount = -1;
|
|
11665
|
+
let sentinelErrorCount = -1;
|
|
11666
|
+
const succeed = (end) => {
|
|
11667
|
+
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, pos, end);
|
|
11668
|
+
emit(end);
|
|
11669
|
+
return { ok: true, value: input.slice(pos, end), span: { start: pos, end } };
|
|
11670
|
+
};
|
|
11671
|
+
const recoveredEnd = () => {
|
|
11672
|
+
const acceptSentinel = firstSentinel >= 0 && (sentinelCount & 1) === 1;
|
|
11673
|
+
const errors = ctx._errors;
|
|
11674
|
+
if (errors !== void 0) {
|
|
11675
|
+
const keep = acceptSentinel ? sentinelErrorCount : recoveryErrorCount;
|
|
11676
|
+
if (keep >= 0 && errors.length > keep) errors.length = keep;
|
|
11677
|
+
}
|
|
11678
|
+
return acceptSentinel ? firstSentinel : recovery;
|
|
11679
|
+
};
|
|
11680
|
+
while (cur < input.length) {
|
|
11681
|
+
const sentinelProbeErrorCount = ctx._errors?.length ?? -1;
|
|
11682
|
+
const s = sentinel.parse(input, cur, probeCtx);
|
|
11683
|
+
const sentinelProbeErrors = ctx._errors;
|
|
11684
|
+
if (sentinelProbeErrors !== void 0 && sentinelProbeErrorCount >= 0 && sentinelProbeErrors.length > sentinelProbeErrorCount) {
|
|
11685
|
+
sentinelProbeErrors.length = sentinelProbeErrorCount;
|
|
11686
|
+
}
|
|
11687
|
+
if (s.ok) {
|
|
11688
|
+
if (recovery < 0) return succeed(cur);
|
|
11689
|
+
if (s.span.end <= cur) {
|
|
11690
|
+
throw new TypeError("scanTo recovery requires a sentinel that consumes input");
|
|
11691
|
+
}
|
|
11692
|
+
if (firstSentinel < 0) {
|
|
11693
|
+
firstSentinel = cur;
|
|
11694
|
+
sentinelErrorCount = sentinelProbeErrorCount;
|
|
11695
|
+
}
|
|
11696
|
+
sentinelCount++;
|
|
11697
|
+
cur = s.span.end;
|
|
11698
|
+
continue;
|
|
11699
|
+
}
|
|
11700
|
+
if (stopAt !== void 0) {
|
|
11701
|
+
const errorCount = ctx._errors?.length ?? -1;
|
|
11702
|
+
const stop = stopAt.parse(input, cur, probeCtx);
|
|
11703
|
+
const errors = ctx._errors;
|
|
11704
|
+
if (errors !== void 0 && errorCount >= 0 && errors.length > errorCount) {
|
|
11705
|
+
errors.length = errorCount;
|
|
11706
|
+
}
|
|
11707
|
+
if (stop.ok) {
|
|
11708
|
+
if (recovery < 0) {
|
|
11709
|
+
recovery = cur;
|
|
11710
|
+
recoveryErrorCount = errorCount;
|
|
11711
|
+
}
|
|
11712
|
+
return succeed(recoveredEnd());
|
|
11713
|
+
}
|
|
11714
|
+
}
|
|
11613
11715
|
let advanced = false;
|
|
11614
11716
|
for (const skipper of skip2) {
|
|
11717
|
+
const errorCount = ctx._errors?.length ?? -1;
|
|
11615
11718
|
const r = skipper.parse(input, cur, probeCtx);
|
|
11616
11719
|
if (r.ok && r.span.end > cur) {
|
|
11617
11720
|
cur = r.span.end;
|
|
11618
11721
|
advanced = true;
|
|
11619
11722
|
break;
|
|
11620
11723
|
}
|
|
11724
|
+
const errors = ctx._errors;
|
|
11725
|
+
if (errors !== void 0 && errorCount >= 0 && errors.length > errorCount) {
|
|
11726
|
+
errors.length = errorCount;
|
|
11727
|
+
}
|
|
11621
11728
|
}
|
|
11622
|
-
if (
|
|
11729
|
+
if (advanced) continue;
|
|
11730
|
+
if (recoverAt !== void 0) {
|
|
11731
|
+
const errorCount = ctx._errors?.length ?? -1;
|
|
11732
|
+
const recover = recoverAt.parse(input, cur, probeCtx);
|
|
11733
|
+
const errors = ctx._errors;
|
|
11734
|
+
if (errors !== void 0 && errorCount >= 0 && errors.length > errorCount) {
|
|
11735
|
+
errors.length = errorCount;
|
|
11736
|
+
}
|
|
11737
|
+
if (recover.ok) {
|
|
11738
|
+
if (recover.span.end <= cur) {
|
|
11739
|
+
throw new TypeError("scanTo recoverAt must consume input");
|
|
11740
|
+
}
|
|
11741
|
+
if (recovery < 0) {
|
|
11742
|
+
recovery = cur;
|
|
11743
|
+
recoveryErrorCount = errorCount;
|
|
11744
|
+
}
|
|
11745
|
+
if (firstSentinel >= 0 && (sentinelCount & 1) === 1) {
|
|
11746
|
+
return succeed(recoveredEnd());
|
|
11747
|
+
}
|
|
11748
|
+
cur = recover.span.end;
|
|
11749
|
+
continue;
|
|
11750
|
+
}
|
|
11751
|
+
}
|
|
11752
|
+
cur++;
|
|
11623
11753
|
}
|
|
11754
|
+
if (recovery >= 0) return succeed(recoveredEnd());
|
|
11624
11755
|
if (orEOF) {
|
|
11625
|
-
|
|
11626
|
-
emit(cur);
|
|
11627
|
-
return { ok: true, value: input.slice(pos, cur), span: { start: pos, end: cur } };
|
|
11756
|
+
return succeed(cur);
|
|
11628
11757
|
}
|
|
11629
11758
|
const sentDef = sentinel._def;
|
|
11630
11759
|
const expected = sentDef.tag === "literal" ? [JSON.stringify(sentDef.value)] : ["sentinel"];
|
|
@@ -11925,6 +12054,8 @@ function assemble(t, prog, cfg) {
|
|
|
11925
12054
|
for (const s of prog.scans ?? []) {
|
|
11926
12055
|
for (const r of s.skip) labelExtraIps.push(r[0]);
|
|
11927
12056
|
if (s.sentinel !== void 0) labelExtraIps.push(s.sentinel[0]);
|
|
12057
|
+
if (s.recoverAt !== void 0) labelExtraIps.push(s.recoverAt[0]);
|
|
12058
|
+
if (s.stopAt !== void 0) labelExtraIps.push(s.stopAt[0]);
|
|
11928
12059
|
}
|
|
11929
12060
|
for (const set of prog.scanSkip ?? []) for (const r of set) labelExtraIps.push(r[0]);
|
|
11930
12061
|
const closureLabels = computeSiteLabels(
|
|
@@ -14610,6 +14741,8 @@ function assemble(t, prog, cfg) {
|
|
|
14610
14741
|
for (const s of prog.scans ?? []) {
|
|
14611
14742
|
for (const r of s.skip) extraIps.push(r[0]);
|
|
14612
14743
|
if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
|
|
14744
|
+
if (s.recoverAt !== void 0) extraIps.push(s.recoverAt[0]);
|
|
14745
|
+
if (s.stopAt !== void 0) extraIps.push(s.stopAt[0]);
|
|
14613
14746
|
}
|
|
14614
14747
|
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
14615
14748
|
const roots = [...Object.values(prog.rules), ...extraIps];
|
|
@@ -14821,7 +14954,13 @@ function assemble(t, prog, cfg) {
|
|
|
14821
14954
|
continue;
|
|
14822
14955
|
}
|
|
14823
14956
|
const sentDef = typeof s.sent === "string" ? { tag: "literal", value: s.sent, caseInsensitive: false } : void 0;
|
|
14824
|
-
scansArr.push(scanTo(subtreeComb(s.sentinel, sentDef), {
|
|
14957
|
+
scansArr.push(scanTo(subtreeComb(s.sentinel, sentDef), {
|
|
14958
|
+
skip,
|
|
14959
|
+
raw,
|
|
14960
|
+
orEOF: (s.flags & 2) !== 0,
|
|
14961
|
+
...s.recoverAt === void 0 ? {} : { recoverAt: subtreeComb(s.recoverAt) },
|
|
14962
|
+
...s.stopAt === void 0 ? {} : { stopAt: subtreeComb(s.stopAt) }
|
|
14963
|
+
}));
|
|
14825
14964
|
}
|
|
14826
14965
|
const scans = scansArr;
|
|
14827
14966
|
const scanSkip = (prog.scanSkip ?? []).map((set) => set.map((r) => subtreeComb(r)));
|
|
@@ -15038,6 +15177,8 @@ function emitRef(r) {
|
|
|
15038
15177
|
function emitScanSpec(s) {
|
|
15039
15178
|
const parts = [`kind:${s.kind}`, `flags:${s.flags}`, `skip:[${s.skip.map(emitRef).join(",")}]`];
|
|
15040
15179
|
if (s.sentinel !== void 0) parts.push(`sentinel:${emitRef(s.sentinel)}`);
|
|
15180
|
+
if (s.recoverAt !== void 0) parts.push(`recoverAt:${emitRef(s.recoverAt)}`);
|
|
15181
|
+
if (s.stopAt !== void 0) parts.push(`stopAt:${emitRef(s.stopAt)}`);
|
|
15041
15182
|
if (s.sent !== void 0) parts.push(`sent:${s.sent === null ? "null" : jsString(s.sent)}`);
|
|
15042
15183
|
if (s.open !== void 0) parts.push(`open:${jsString(s.open)}`);
|
|
15043
15184
|
if (s.close !== void 0) parts.push(`close:${jsString(s.close)}`);
|
|
@@ -15064,6 +15205,8 @@ function emitAssemblies(prog, cfgs) {
|
|
|
15064
15205
|
for (const s of prog.scans ?? []) {
|
|
15065
15206
|
for (const r of s.skip) extraIps.push(r[0]);
|
|
15066
15207
|
if (s.sentinel !== void 0) extraIps.push(s.sentinel[0]);
|
|
15208
|
+
if (s.recoverAt !== void 0) extraIps.push(s.recoverAt[0]);
|
|
15209
|
+
if (s.stopAt !== void 0) extraIps.push(s.stopAt[0]);
|
|
15067
15210
|
}
|
|
15068
15211
|
for (const set of prog.scanSkip ?? []) for (const r of set) extraIps.push(r[0]);
|
|
15069
15212
|
const out = [];
|
|
@@ -15206,7 +15349,12 @@ function children(def, winners) {
|
|
|
15206
15349
|
case "sepBy":
|
|
15207
15350
|
return [def.parser, def.separator];
|
|
15208
15351
|
case "scanTo":
|
|
15209
|
-
return [
|
|
15352
|
+
return [
|
|
15353
|
+
def.sentinel,
|
|
15354
|
+
...def.skip,
|
|
15355
|
+
...def.recoverAt === void 0 ? [] : [def.recoverAt],
|
|
15356
|
+
...def.stopAt === void 0 ? [] : [def.stopAt]
|
|
15357
|
+
];
|
|
15210
15358
|
case "lazy": {
|
|
15211
15359
|
let resolved;
|
|
15212
15360
|
try {
|
|
@@ -15319,7 +15467,7 @@ function payloadKey(p, d) {
|
|
|
15319
15467
|
case "expect":
|
|
15320
15468
|
return `expect\0${d.label ?? ""}\0${d.expected.join("")}`;
|
|
15321
15469
|
case "scanTo":
|
|
15322
|
-
return `scanTo\0${d.raw}\0${d.orEOF}`;
|
|
15470
|
+
return `scanTo\0${d.raw}\0${d.orEOF}\0${d.recoverAt !== void 0}\0${d.stopAt !== void 0}`;
|
|
15323
15471
|
case "guard":
|
|
15324
15472
|
return `guard\0${fnKey(d.predSrc, d.predicate)}`;
|
|
15325
15473
|
case "adjacency":
|
|
@@ -15434,8 +15582,12 @@ function segment(d, index) {
|
|
|
15434
15582
|
return index === 0 ? "sepBy.item" : "sepBy.sep";
|
|
15435
15583
|
case "recover":
|
|
15436
15584
|
return index === 0 ? "recover.body" : "recover.sentinel";
|
|
15437
|
-
case "scanTo":
|
|
15438
|
-
|
|
15585
|
+
case "scanTo": {
|
|
15586
|
+
if (index === 0) return "scanTo.sentinel";
|
|
15587
|
+
if (index <= d.skip.length) return `scanTo.skip[${index - 1}]`;
|
|
15588
|
+
if (d.recoverAt !== void 0 && index === d.skip.length + 1) return "scanTo.recoverAt";
|
|
15589
|
+
return "scanTo.stopAt";
|
|
15590
|
+
}
|
|
15439
15591
|
default:
|
|
15440
15592
|
return d.tag;
|
|
15441
15593
|
}
|
|
@@ -16711,7 +16863,12 @@ function childrenOf3(def) {
|
|
|
16711
16863
|
case "sepBy":
|
|
16712
16864
|
return [def.parser, def.separator];
|
|
16713
16865
|
case "scanTo":
|
|
16714
|
-
return [
|
|
16866
|
+
return [
|
|
16867
|
+
def.sentinel,
|
|
16868
|
+
...def.skip,
|
|
16869
|
+
...def.recoverAt === void 0 ? [] : [def.recoverAt],
|
|
16870
|
+
...def.stopAt === void 0 ? [] : [def.stopAt]
|
|
16871
|
+
];
|
|
16715
16872
|
case "routed":
|
|
16716
16873
|
return def.fallback ? [def.fallback] : [];
|
|
16717
16874
|
case "lazy":
|
|
@@ -17205,7 +17362,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
17205
17362
|
case "expect":
|
|
17206
17363
|
return `expect(${kid(def.parser)}${def.label !== void 0 ? `, ${JSON.stringify(def.label)}` : ""})`;
|
|
17207
17364
|
case "scanTo":
|
|
17208
|
-
return `scanTo(${kid(def.sentinel)}, { skip: [${def.skip.map(kid).join(", ")}]${def.raw ? ", raw: true" : ""}, orEOF: ${def.orEOF} })`;
|
|
17365
|
+
return `scanTo(${kid(def.sentinel)}, { skip: [${def.skip.map(kid).join(", ")}]${def.raw ? ", raw: true" : ""}, orEOF: ${def.orEOF}${def.recoverAt === void 0 ? "" : `, recoverAt: ${kid(def.recoverAt)}`}${def.stopAt === void 0 ? "" : `, stopAt: ${kid(def.stopAt)}`} })`;
|
|
17209
17366
|
case "transform": {
|
|
17210
17367
|
if (def.fnSrc === void 0) throw new Unserializable("transform without fnSrc");
|
|
17211
17368
|
return `_tf(${kid(def.parser)}, ${JSON.stringify(def.fnSrc)}${def.recognitionOnly ? ", true" : ""})`;
|
|
@@ -17385,7 +17542,7 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
17385
17542
|
}
|
|
17386
17543
|
|
|
17387
17544
|
// src/version.ts
|
|
17388
|
-
var PARSEMAN_VERSION = "0.
|
|
17545
|
+
var PARSEMAN_VERSION = "0.51.0";
|
|
17389
17546
|
|
|
17390
17547
|
// src/compiler/compile-linkable-table.ts
|
|
17391
17548
|
function isLocal(rule) {
|
|
@@ -18451,8 +18608,12 @@ function slotLabel(d, index) {
|
|
|
18451
18608
|
return index === 0 ? "sepBy.item" : "sepBy.sep";
|
|
18452
18609
|
case "recover":
|
|
18453
18610
|
return index === 0 ? "recover.parser" : "recover.sentinel";
|
|
18454
|
-
case "scanTo":
|
|
18455
|
-
|
|
18611
|
+
case "scanTo": {
|
|
18612
|
+
if (index === 0) return "scanTo.sentinel";
|
|
18613
|
+
if (index <= d.skip.length) return `scanTo.skip[${index - 1}]`;
|
|
18614
|
+
if (d.recoverAt !== void 0 && index === d.skip.length + 1) return "scanTo.recoverAt";
|
|
18615
|
+
return "scanTo.stopAt";
|
|
18616
|
+
}
|
|
18456
18617
|
case "grammar":
|
|
18457
18618
|
return index === 0 ? "grammar" : "grammar.trivia";
|
|
18458
18619
|
case "node":
|
|
@@ -20118,7 +20279,13 @@ function coverageEntry(entry, collector, maps, trace) {
|
|
|
20118
20279
|
case "expect":
|
|
20119
20280
|
return expect(build(def.parser), def.label);
|
|
20120
20281
|
case "scanTo":
|
|
20121
|
-
return scanTo(build(def.sentinel), {
|
|
20282
|
+
return scanTo(build(def.sentinel), {
|
|
20283
|
+
skip: def.skip.map(build),
|
|
20284
|
+
raw: def.raw,
|
|
20285
|
+
orEOF: def.orEOF,
|
|
20286
|
+
...def.recoverAt === void 0 ? {} : { recoverAt: build(def.recoverAt) },
|
|
20287
|
+
...def.stopAt === void 0 ? {} : { stopAt: build(def.stopAt) }
|
|
20288
|
+
});
|
|
20122
20289
|
// Zero-width assertion with no coverage-bearing child; reuse it verbatim so
|
|
20123
20290
|
// the rebuilt sequence still recognises the boundary marker.
|
|
20124
20291
|
case "adjacency":
|