parseman 0.50.5 → 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/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.js +53 -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/plugin/evaluator.ts +13 -0
- package/src/table/encode.ts +10 -8
- 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
|
}
|
|
@@ -7519,7 +7520,9 @@ var Encoder = class {
|
|
|
7519
7520
|
followClass(parsers, i) {
|
|
7520
7521
|
let fs = { kind: "empty" };
|
|
7521
7522
|
const rr = this.refResolver();
|
|
7522
|
-
for (let j = i + 1; j < parsers.length; j++)
|
|
7523
|
+
for (let j = i + 1; j < parsers.length; j++) {
|
|
7524
|
+
fs = union(fs, firstSetOf(parsers[j], /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
7525
|
+
}
|
|
7523
7526
|
return this.charClass(fs);
|
|
7524
7527
|
}
|
|
7525
7528
|
constant(v) {
|
|
@@ -7736,7 +7739,7 @@ var Encoder = class {
|
|
|
7736
7739
|
*/
|
|
7737
7740
|
subtree(c) {
|
|
7738
7741
|
const ip = this.node(c).ip;
|
|
7739
|
-
const fs = firstSetOf(c, /* @__PURE__ */ new Set(), this.refResolver());
|
|
7742
|
+
const fs = firstSetOf(c, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia);
|
|
7740
7743
|
return [ip, fs.kind === "empty" ? -2 : this.charClass(fs)];
|
|
7741
7744
|
}
|
|
7742
7745
|
/** Pool one scan spec. One per combinator: `node()` memoizes by identity. */
|
|
@@ -7955,12 +7958,12 @@ var Encoder = class {
|
|
|
7955
7958
|
return this.covWrap(gated, armCovIds?.[src], 1);
|
|
7956
7959
|
});
|
|
7957
7960
|
const rr = this.refResolver();
|
|
7958
|
-
const finalChoice = classifyFinalChoice(arms, rr);
|
|
7961
|
+
const finalChoice = classifyFinalChoice(arms, rr, this.activeTrivia);
|
|
7959
7962
|
const transactionalFirst = arms.map((arm, i) => {
|
|
7960
7963
|
if (!finalChoice.nullable[i]) return void 0;
|
|
7961
7964
|
const def = arm._def;
|
|
7962
7965
|
if (def.tag !== "attempt" || matchesEmpty(def.parser, /* @__PURE__ */ new Set(), rr)) return void 0;
|
|
7963
|
-
return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr);
|
|
7966
|
+
return firstSetOf(def.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia);
|
|
7964
7967
|
});
|
|
7965
7968
|
const gateFirst = finalChoice.firstSets.map((first, i) => transactionalFirst[i] ?? first);
|
|
7966
7969
|
const classes = gateFirst.map((first, i) => finalChoice.nullable[i] && transactionalFirst[i] === void 0 ? -1 : this.charClass(first));
|
|
@@ -8007,7 +8010,7 @@ var Encoder = class {
|
|
|
8007
8010
|
case "oneOrMore": {
|
|
8008
8011
|
const child = this.node(d.parser).ip;
|
|
8009
8012
|
const rr = this.refResolver();
|
|
8010
|
-
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.existingCharClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr));
|
|
8013
|
+
const itemClass = matchesEmpty(d.parser, /* @__PURE__ */ new Set(), rr) ? -1 : this.existingCharClass(firstSetOf(d.parser, /* @__PURE__ */ new Set(), rr, this.activeTrivia));
|
|
8011
8014
|
const op = d.valueUnused ? OP_REPV : OP_REP;
|
|
8012
8015
|
const min = d.tag === "many" ? 0 : d.min;
|
|
8013
8016
|
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 +8028,7 @@ var Encoder = class {
|
|
|
8025
8028
|
sep,
|
|
8026
8029
|
flags,
|
|
8027
8030
|
this.expected(deriveExpected(d.parser)),
|
|
8028
|
-
this.charClass(firstSetOf(d.separator, /* @__PURE__ */ new Set(), this.refResolver()))
|
|
8031
|
+
this.charClass(firstSetOf(d.separator, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia))
|
|
8029
8032
|
);
|
|
8030
8033
|
}
|
|
8031
8034
|
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 +8083,7 @@ var Encoder = class {
|
|
|
8080
8083
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
8081
8084
|
);
|
|
8082
8085
|
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;
|
|
8086
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : d.parser._meta.firstSet;
|
|
8084
8087
|
if (fs.kind === "any") return body;
|
|
8085
8088
|
const cls = this.charClass(fs);
|
|
8086
8089
|
if (cls < 0) return body;
|
|
@@ -8194,7 +8197,7 @@ var Encoder = class {
|
|
|
8194
8197
|
case "attempt": {
|
|
8195
8198
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
|
|
8196
8199
|
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;
|
|
8200
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : d.parser._meta.firstSet;
|
|
8198
8201
|
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
8199
8202
|
const cls = this.charClass(fs);
|
|
8200
8203
|
if (cls < 0) return inner;
|
|
@@ -17385,7 +17388,7 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
17385
17388
|
}
|
|
17386
17389
|
|
|
17387
17390
|
// src/version.ts
|
|
17388
|
-
var PARSEMAN_VERSION = "0.50.
|
|
17391
|
+
var PARSEMAN_VERSION = "0.50.7";
|
|
17389
17392
|
|
|
17390
17393
|
// src/compiler/compile-linkable-table.ts
|
|
17391
17394
|
function isLocal(rule) {
|