@thomasfosterau/effect-parse 0.4.1 → 0.6.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/CHANGELOG.md +202 -0
- package/README.md +56 -14
- package/dist/Ascii.d.ts +11 -4
- package/dist/Ascii.d.ts.map +1 -1
- package/dist/Ascii.js +12 -4
- package/dist/Ascii.js.map +1 -1
- package/dist/Binary.d.ts +5 -2
- package/dist/Binary.d.ts.map +1 -1
- package/dist/Binary.js +83 -37
- package/dist/Binary.js.map +1 -1
- package/dist/Bits.d.ts.map +1 -1
- package/dist/Bits.js +11 -4
- package/dist/Bits.js.map +1 -1
- package/dist/Compiler.d.ts +74 -2
- package/dist/Compiler.d.ts.map +1 -1
- package/dist/Compiler.js +78 -1
- package/dist/Compiler.js.map +1 -1
- package/dist/Expression.d.ts.map +1 -1
- package/dist/Expression.js +86 -74
- package/dist/Expression.js.map +1 -1
- package/dist/Input.d.ts +56 -5
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +70 -1
- package/dist/Input.js.map +1 -1
- package/dist/Nom.d.ts +5 -15
- package/dist/Nom.d.ts.map +1 -1
- package/dist/Nom.js.map +1 -1
- package/dist/ParseError.d.ts +69 -11
- package/dist/ParseError.d.ts.map +1 -1
- package/dist/ParseError.js +129 -28
- package/dist/ParseError.js.map +1 -1
- package/dist/Parser.d.ts +375 -29
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +394 -37
- package/dist/Parser.js.map +1 -1
- package/dist/ParserSchema.d.ts.map +1 -1
- package/dist/ParserSchema.js +2 -3
- package/dist/ParserSchema.js.map +1 -1
- package/dist/ParserStream.d.ts +122 -14
- package/dist/ParserStream.d.ts.map +1 -1
- package/dist/ParserStream.js +293 -62
- package/dist/ParserStream.js.map +1 -1
- package/dist/Syntax.d.ts +23 -5
- package/dist/Syntax.d.ts.map +1 -1
- package/dist/Syntax.js +1 -1
- package/dist/Syntax.js.map +1 -1
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +21 -15
- package/dist/Text.js.map +1 -1
- package/dist/Token.d.ts +65 -11
- package/dist/Token.d.ts.map +1 -1
- package/dist/Token.js +73 -26
- package/dist/Token.js.map +1 -1
- package/dist/internal/compiler/closure.d.ts +1 -1
- package/dist/internal/compiler/closure.d.ts.map +1 -1
- package/dist/internal/compiler/closure.js +263 -113
- package/dist/internal/compiler/closure.js.map +1 -1
- package/dist/internal/compiler/entries.d.ts +3 -1
- package/dist/internal/compiler/entries.d.ts.map +1 -1
- package/dist/internal/compiler/entries.js +3 -2
- package/dist/internal/compiler/entries.js.map +1 -1
- package/dist/internal/compiler/first.d.ts.map +1 -1
- package/dist/internal/compiler/first.js +9 -2
- package/dist/internal/compiler/first.js.map +1 -1
- package/dist/internal/compiler/graph.d.ts +39 -0
- package/dist/internal/compiler/graph.d.ts.map +1 -0
- package/dist/internal/compiler/graph.js +78 -0
- package/dist/internal/compiler/graph.js.map +1 -0
- package/dist/internal/compiler/jit.d.ts +5 -0
- package/dist/internal/compiler/jit.d.ts.map +1 -1
- package/dist/internal/compiler/jit.js +208 -106
- package/dist/internal/compiler/jit.js.map +1 -1
- package/dist/internal/compiler/registry.d.ts +11 -3
- package/dist/internal/compiler/registry.d.ts.map +1 -1
- package/dist/internal/compiler/registry.js.map +1 -1
- package/dist/internal/compiler/search.d.ts +32 -0
- package/dist/internal/compiler/search.d.ts.map +1 -0
- package/dist/internal/compiler/search.js +68 -0
- package/dist/internal/compiler/search.js.map +1 -0
- package/dist/internal/compiler/sets.d.ts.map +1 -1
- package/dist/internal/compiler/sets.js +1 -1
- package/dist/internal/compiler/sets.js.map +1 -1
- package/dist/internal/compiler/wasm.d.ts +8 -0
- package/dist/internal/compiler/wasm.d.ts.map +1 -0
- package/dist/internal/compiler/wasm.js +2840 -0
- package/dist/internal/compiler/wasm.js.map +1 -0
- package/dist/internal/compiler/wasmAsm.d.ts +199 -0
- package/dist/internal/compiler/wasmAsm.d.ts.map +1 -0
- package/dist/internal/compiler/wasmAsm.js +427 -0
- package/dist/internal/compiler/wasmAsm.js.map +1 -0
- package/dist/internal/entries.d.ts +3 -1
- package/dist/internal/entries.d.ts.map +1 -1
- package/dist/internal/entries.js.map +1 -1
- package/dist/internal/node.d.ts +77 -3
- package/dist/internal/node.d.ts.map +1 -1
- package/dist/internal/node.js +54 -10
- package/dist/internal/node.js.map +1 -1
- package/dist/internal/numbers.d.ts.map +1 -1
- package/dist/internal/numbers.js.map +1 -1
- package/dist/internal/run.d.ts +14 -0
- package/dist/internal/run.d.ts.map +1 -1
- package/dist/internal/run.js +53 -11
- package/dist/internal/run.js.map +1 -1
- package/dist/internal/stack.d.ts +14 -0
- package/dist/internal/stack.d.ts.map +1 -1
- package/dist/internal/stack.js +24 -2
- package/dist/internal/stack.js.map +1 -1
- package/dist/internal/syntax.d.ts +4 -4
- package/dist/internal/syntax.d.ts.map +1 -1
- package/dist/internal/syntax.js +18 -10
- package/dist/internal/syntax.js.map +1 -1
- package/dist/internal/text.d.ts +32 -0
- package/dist/internal/text.d.ts.map +1 -1
- package/dist/internal/text.js +68 -14
- package/dist/internal/text.js.map +1 -1
- package/dist/internal/tokens.d.ts +20 -0
- package/dist/internal/tokens.d.ts.map +1 -1
- package/dist/internal/tokens.js +72 -39
- package/dist/internal/tokens.js.map +1 -1
- package/dist/internal/tuple.d.ts +6 -0
- package/dist/internal/tuple.d.ts.map +1 -0
- package/dist/internal/tuple.js +170 -0
- package/dist/internal/tuple.js.map +1 -0
- package/package.json +18 -10
- package/src/Ascii.ts +47 -12
- package/src/Binary.ts +174 -73
- package/src/Bits.ts +16 -6
- package/src/Compiler.ts +101 -10
- package/src/Expression.ts +94 -81
- package/src/Input.ts +99 -7
- package/src/Nom.ts +15 -5
- package/src/ParseError.ts +209 -52
- package/src/Parser.ts +684 -143
- package/src/ParserSchema.ts +1 -2
- package/src/ParserStream.ts +361 -68
- package/src/Syntax.ts +60 -36
- package/src/Text.ts +32 -27
- package/src/Token.ts +152 -34
- package/src/internal/compiler/closure.ts +371 -153
- package/src/internal/compiler/entries.ts +4 -2
- package/src/internal/compiler/first.ts +16 -0
- package/src/internal/compiler/graph.ts +96 -0
- package/src/internal/compiler/jit.ts +319 -169
- package/src/internal/compiler/registry.ts +10 -2
- package/src/internal/compiler/search.ts +68 -0
- package/src/internal/compiler/sets.ts +7 -3
- package/src/internal/compiler/wasm.ts +3276 -0
- package/src/internal/compiler/wasmAsm.ts +484 -0
- package/src/internal/entries.ts +8 -2
- package/src/internal/node.ts +103 -7
- package/src/internal/numbers.ts +3 -1
- package/src/internal/run.ts +73 -12
- package/src/internal/stack.ts +25 -1
- package/src/internal/syntax.ts +39 -18
- package/src/internal/text.ts +97 -9
- package/src/internal/tokens.ts +106 -14
- package/src/internal/tuple.ts +141 -0
|
@@ -3,14 +3,16 @@ import * as Result from "effect/Result";
|
|
|
3
3
|
import { Fail } from "../../Input.js";
|
|
4
4
|
import { floatScan, floatTexts, scanFloatBytes, scanFloatString, toFloat } from "../numbers.js";
|
|
5
5
|
import { Key } from "../key.js";
|
|
6
|
+
import { Defer, nodeOf, scansFloat } from "../node.js";
|
|
6
7
|
import * as Resume from "../resume.js";
|
|
7
|
-
import { countTokens, indexOf } from "../tokens.js";
|
|
8
|
+
import { countTokens, indexOf, indexOfAny } from "../tokens.js";
|
|
8
9
|
import * as Option from "effect/Option";
|
|
9
|
-
import { charOf, fastLimit, firstCodePoint, fold, utf16be, utf16le, validate } from "../text.js";
|
|
10
|
+
import { charOf, fastLimit, firstCodePoint, fold, textIn, utf16be, utf16le, utf8, utf8Text, validate } from "../text.js";
|
|
10
11
|
import { addEntry, flushEntries, fromEntries, isPlainKey } from "../entries.js";
|
|
11
|
-
import {
|
|
12
|
+
import { tupleStep } from "../tuple.js";
|
|
12
13
|
import { buildsEntries, pairOf } from "./entries.js";
|
|
13
14
|
import { FirstSets, planAlt } from "./first.js";
|
|
15
|
+
import { SearchHead, StopCache, nextStop, stopChars } from "./search.js";
|
|
14
16
|
import { TableSize, acceptTable, kindOfEncoding, textSet, tokenSet } from "./sets.js";
|
|
15
17
|
// src/internal/compiler/closure.ts
|
|
16
18
|
/**
|
|
@@ -110,6 +112,8 @@ var Compiler = class {
|
|
|
110
112
|
build(p, node, used) {
|
|
111
113
|
switch (node._tag) {
|
|
112
114
|
case "Opaque": return this.fallback(p, node, "not describable (Parser.make, gen, ...)");
|
|
115
|
+
case "Fixed": return p.step;
|
|
116
|
+
case "Combinator": return node.build(node.parsers.map((q) => this.compile(q, true)));
|
|
113
117
|
case "Succeed": {
|
|
114
118
|
const value = node.value;
|
|
115
119
|
return () => value;
|
|
@@ -130,10 +134,7 @@ var Compiler = class {
|
|
|
130
134
|
s.mode = BT;
|
|
131
135
|
return Fail;
|
|
132
136
|
}
|
|
133
|
-
if (s.partial)
|
|
134
|
-
s.mode = INC;
|
|
135
|
-
return Fail;
|
|
136
|
-
}
|
|
137
|
+
if (s.partial) return s.incomplete(1);
|
|
137
138
|
};
|
|
138
139
|
case "Location": return (s) => s.pos;
|
|
139
140
|
case "RestLen": return (s) => s.end - s.pos;
|
|
@@ -144,9 +145,10 @@ var Compiler = class {
|
|
|
144
145
|
case "Take":
|
|
145
146
|
case "TakeWhile":
|
|
146
147
|
case "TakeUntil":
|
|
148
|
+
case "TakeUntilAny":
|
|
147
149
|
case "Rest":
|
|
148
150
|
if (!this.native(node.encoding)) return this.fallback(p, node, "token parser on array input");
|
|
149
|
-
return this.partialSafe(p, node.encoding === void 0 ? this.token(p, node, used) : this.text(p, node, node.encoding, used),
|
|
151
|
+
return this.partialSafe(p, node.encoding === void 0 ? this.token(p, node, used) : this.text(p, node, node.encoding, used), marginOf(node));
|
|
150
152
|
case "TillLineEnding":
|
|
151
153
|
case "Identifier":
|
|
152
154
|
case "Bom": return this.fallback(p, node, "leaf parser without a compiled form");
|
|
@@ -159,7 +161,7 @@ var Compiler = class {
|
|
|
159
161
|
const step = this.float(node);
|
|
160
162
|
if (step !== void 0) return step;
|
|
161
163
|
}
|
|
162
|
-
if (node.f === fromEntries &&
|
|
164
|
+
if (node.f === fromEntries && buildsEntries(node.self)) return this.entries(node.self);
|
|
163
165
|
const c = this.compile(node.self, true);
|
|
164
166
|
const f = node.f;
|
|
165
167
|
return (s) => {
|
|
@@ -206,6 +208,28 @@ var Compiler = class {
|
|
|
206
208
|
return Fail;
|
|
207
209
|
};
|
|
208
210
|
}
|
|
211
|
+
case "FastPath": {
|
|
212
|
+
const c = this.compile(node.self, used);
|
|
213
|
+
const fast = node.fast;
|
|
214
|
+
return (s) => {
|
|
215
|
+
const start = s.pos;
|
|
216
|
+
const a = fast(s);
|
|
217
|
+
if (a !== Defer) return a;
|
|
218
|
+
s.pos = start;
|
|
219
|
+
return c(s);
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
case "MapOrFail": {
|
|
223
|
+
const c = this.compile(node.self, true);
|
|
224
|
+
const f = node.f;
|
|
225
|
+
return (s) => {
|
|
226
|
+
const a = c(s);
|
|
227
|
+
if (a === Fail) return Fail;
|
|
228
|
+
const b = f(a);
|
|
229
|
+
if (b === Fail) s.mode = BT;
|
|
230
|
+
return b;
|
|
231
|
+
};
|
|
232
|
+
}
|
|
209
233
|
case "Filter": {
|
|
210
234
|
const c = this.compile(node.self, true);
|
|
211
235
|
const predicate = node.predicate;
|
|
@@ -237,6 +261,16 @@ var Compiler = class {
|
|
|
237
261
|
return a === Fail ? Fail : [a, s.slice(start, s.pos)];
|
|
238
262
|
};
|
|
239
263
|
}
|
|
264
|
+
case "MapSpan": {
|
|
265
|
+
const c = this.compile(node.self, used);
|
|
266
|
+
if (!used) return c;
|
|
267
|
+
const f = node.f;
|
|
268
|
+
return (s) => {
|
|
269
|
+
const start = s.pos;
|
|
270
|
+
const a = c(s);
|
|
271
|
+
return a === Fail ? Fail : f(a, start, s.pos);
|
|
272
|
+
};
|
|
273
|
+
}
|
|
240
274
|
case "Span": {
|
|
241
275
|
const c = this.compile(node.self, false);
|
|
242
276
|
if (!used) return c;
|
|
@@ -271,6 +305,7 @@ var Compiler = class {
|
|
|
271
305
|
}
|
|
272
306
|
case "Context":
|
|
273
307
|
case "Expected":
|
|
308
|
+
case "Quiet":
|
|
274
309
|
case "MapError":
|
|
275
310
|
case "OrFail":
|
|
276
311
|
case "Trace":
|
|
@@ -336,6 +371,11 @@ var Compiler = class {
|
|
|
336
371
|
return out;
|
|
337
372
|
};
|
|
338
373
|
}
|
|
374
|
+
case "SeqWith": {
|
|
375
|
+
const steps = node.parsers.map((q) => this.compile(q, used));
|
|
376
|
+
if (!used) return this.chain(steps);
|
|
377
|
+
return this.seqWith(steps, node.f);
|
|
378
|
+
}
|
|
339
379
|
case "ZipWith": {
|
|
340
380
|
const c1 = this.compile(node.self, used);
|
|
341
381
|
const c2 = this.compile(node.that, used);
|
|
@@ -351,7 +391,22 @@ var Compiler = class {
|
|
|
351
391
|
case "Alt": return this.alt(node, used);
|
|
352
392
|
case "Dispatch": return this.dispatch(p, node, used);
|
|
353
393
|
case "Repeat":
|
|
354
|
-
case "Fold":
|
|
394
|
+
case "Fold": {
|
|
395
|
+
const element = Predicate.isTagged(node, "Repeat") && !used ? nodeOf(node.self) : void 0;
|
|
396
|
+
if (element !== void 0 && Predicate.isTagged(element, "OneOf") && this.kind !== 2 && this.native(element.encoding)) {
|
|
397
|
+
const { encoding, negate, set } = element;
|
|
398
|
+
const run = {
|
|
399
|
+
_tag: "TakeWhile",
|
|
400
|
+
set,
|
|
401
|
+
negate,
|
|
402
|
+
encoding,
|
|
403
|
+
min: node.min,
|
|
404
|
+
max: node.max
|
|
405
|
+
};
|
|
406
|
+
return this.partialSafe(p, encoding === void 0 ? this.token(p, run, false) : this.text(p, run, encoding, false), Margin);
|
|
407
|
+
}
|
|
408
|
+
return this.repeat(node, used);
|
|
409
|
+
}
|
|
355
410
|
case "RepeatTill": return this.repeatTill(node);
|
|
356
411
|
case "Separated": return this.separated(node, used);
|
|
357
412
|
case "SeparatedFold": return this.separatedFold(node);
|
|
@@ -359,13 +414,47 @@ var Compiler = class {
|
|
|
359
414
|
case "Provide": return this.fallback(p, node, "services stay interpreted");
|
|
360
415
|
}
|
|
361
416
|
}
|
|
417
|
+
/** `seqWith`: up to three parsers without an array of values. */
|
|
418
|
+
seqWith(steps, f) {
|
|
419
|
+
const n = steps.length;
|
|
420
|
+
if (n === 0) return () => f();
|
|
421
|
+
const [c1, c2, c3] = steps;
|
|
422
|
+
if (n === 1) return (s) => {
|
|
423
|
+
const a = c1(s);
|
|
424
|
+
return a === Fail ? Fail : f(a);
|
|
425
|
+
};
|
|
426
|
+
if (n === 2) return (s) => {
|
|
427
|
+
const a = c1(s);
|
|
428
|
+
if (a === Fail) return Fail;
|
|
429
|
+
const b = c2(s);
|
|
430
|
+
return b === Fail ? Fail : f(a, b);
|
|
431
|
+
};
|
|
432
|
+
if (n === 3) return (s) => {
|
|
433
|
+
const a = c1(s);
|
|
434
|
+
if (a === Fail) return Fail;
|
|
435
|
+
const b = c2(s);
|
|
436
|
+
if (b === Fail) return Fail;
|
|
437
|
+
const c = c3(s);
|
|
438
|
+
return c === Fail ? Fail : f(a, b, c);
|
|
439
|
+
};
|
|
440
|
+
return (s) => {
|
|
441
|
+
const values = new Array(n);
|
|
442
|
+
for (let i = 0; i < n; i++) {
|
|
443
|
+
const a = steps[i](s);
|
|
444
|
+
if (a === Fail) return Fail;
|
|
445
|
+
values[i] = a;
|
|
446
|
+
}
|
|
447
|
+
return f(...values);
|
|
448
|
+
};
|
|
449
|
+
}
|
|
362
450
|
/** Runs steps in order, for their effect on the cursor only. */
|
|
363
451
|
chain(steps) {
|
|
364
452
|
const n = steps.length;
|
|
365
453
|
if (n === 0) return () => void 0;
|
|
366
454
|
if (n === 1) return steps[0];
|
|
367
455
|
if (n === 2) {
|
|
368
|
-
const
|
|
456
|
+
const a = steps[0];
|
|
457
|
+
const b = steps[1];
|
|
369
458
|
return (s) => a(s) === Fail ? Fail : b(s);
|
|
370
459
|
}
|
|
371
460
|
return (s) => {
|
|
@@ -378,18 +467,11 @@ var Compiler = class {
|
|
|
378
467
|
const steps = node.parsers.map((q, i) => this.compile(q, keep(i)));
|
|
379
468
|
const n = steps.length;
|
|
380
469
|
if (!used) return this.chain(steps);
|
|
381
|
-
if (output === "tuple") return (
|
|
382
|
-
const out = new Array(n);
|
|
383
|
-
for (let i = 0; i < n; i++) {
|
|
384
|
-
const a = steps[i](s);
|
|
385
|
-
if (a === Fail) return Fail;
|
|
386
|
-
out[i] = a;
|
|
387
|
-
}
|
|
388
|
-
return out;
|
|
389
|
-
};
|
|
470
|
+
if (output === "tuple") return tupleStep(steps);
|
|
390
471
|
if (Predicate.isNumber(output)) {
|
|
391
472
|
if (n === 2) {
|
|
392
|
-
const
|
|
473
|
+
const a = steps[0];
|
|
474
|
+
const b = steps[1];
|
|
393
475
|
return output === 0 ? (s) => {
|
|
394
476
|
const x = a(s);
|
|
395
477
|
if (x === Fail) return Fail;
|
|
@@ -486,9 +568,9 @@ var Compiler = class {
|
|
|
486
568
|
this.note(p, node, "the parser returned by the function of cases runs interpreted");
|
|
487
569
|
return general;
|
|
488
570
|
}
|
|
489
|
-
|
|
490
|
-
const peek = Predicate.isTagged(
|
|
491
|
-
|
|
571
|
+
const top = nodeOf(node.selector);
|
|
572
|
+
const peek = Predicate.isTagged(top, "Peek");
|
|
573
|
+
const sel = peek ? nodeOf(top.self) : top;
|
|
492
574
|
if (!Predicate.isTagged(sel, "Any") || !this.native(sel.encoding)) return general;
|
|
493
575
|
const enc = sel.encoding;
|
|
494
576
|
const limit = enc === void 0 ? this.kind === 0 ? 55296 : TableSize : Math.min(fastLimit(enc), 55296);
|
|
@@ -521,7 +603,6 @@ var Compiler = class {
|
|
|
521
603
|
}
|
|
522
604
|
repeat(node, used) {
|
|
523
605
|
const { max, min } = node;
|
|
524
|
-
const checkLoop = max === Infinity;
|
|
525
606
|
const isFold = Predicate.isTagged(node, "Fold");
|
|
526
607
|
const cond = isFold ? node.while : void 0;
|
|
527
608
|
const c = this.compile(node.self, used);
|
|
@@ -566,7 +647,7 @@ var Compiler = class {
|
|
|
566
647
|
s.pos = start;
|
|
567
648
|
return resumed ? Resume.done(s, key, entry, true, acc) : acc;
|
|
568
649
|
}
|
|
569
|
-
if (
|
|
650
|
+
if (s.pos === start) {
|
|
570
651
|
s.mode = CUT;
|
|
571
652
|
return Fail;
|
|
572
653
|
}
|
|
@@ -581,42 +662,39 @@ var Compiler = class {
|
|
|
581
662
|
*/
|
|
582
663
|
entries(p) {
|
|
583
664
|
const node = nodeOf(p);
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
const
|
|
613
|
-
return (
|
|
614
|
-
|
|
615
|
-
return a === Fail ? Fail : fromEntries(a);
|
|
616
|
-
};
|
|
617
|
-
}
|
|
618
|
-
default: return this.entries(node.self);
|
|
665
|
+
if (Predicate.isTagged(node, "Mode")) {
|
|
666
|
+
const c = this.entries(node.self);
|
|
667
|
+
const from = node.from;
|
|
668
|
+
const to = node.to;
|
|
669
|
+
return (s) => {
|
|
670
|
+
const a = c(s);
|
|
671
|
+
if (a === Fail && s.mode === from) s.mode = to;
|
|
672
|
+
return a;
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
if (Predicate.isTagged(node, "Seq")) {
|
|
676
|
+
const i = node.output;
|
|
677
|
+
const steps = node.parsers.map((q, j) => j === i ? this.entries(q) : this.compile(q, false));
|
|
678
|
+
return (s) => {
|
|
679
|
+
let out;
|
|
680
|
+
for (let j = 0; j < steps.length; j++) {
|
|
681
|
+
const a = steps[j](s);
|
|
682
|
+
if (a === Fail) return Fail;
|
|
683
|
+
if (j === i) out = a;
|
|
684
|
+
}
|
|
685
|
+
return out;
|
|
686
|
+
};
|
|
687
|
+
}
|
|
688
|
+
if (Predicate.isTagged(node, "Repeat") || Predicate.isTagged(node, "Separated")) {
|
|
689
|
+
const pair = pairOf(node.self);
|
|
690
|
+
if (pair !== void 0) return this.entriesLoop(node, pair);
|
|
691
|
+
const c = this.compile(p, true);
|
|
692
|
+
return (s) => {
|
|
693
|
+
const a = c(s);
|
|
694
|
+
return a === Fail ? Fail : fromEntries(a);
|
|
695
|
+
};
|
|
619
696
|
}
|
|
697
|
+
return this.entries(node.self);
|
|
620
698
|
}
|
|
621
699
|
entriesLoop(node, pair) {
|
|
622
700
|
const parts = pair.parsers.map((q, j) => this.compile(q, j === pair.key || j === pair.value));
|
|
@@ -634,10 +712,15 @@ var Compiler = class {
|
|
|
634
712
|
return true;
|
|
635
713
|
};
|
|
636
714
|
const { max, min } = node;
|
|
637
|
-
const
|
|
715
|
+
const resumable = this.resumable;
|
|
716
|
+
const site = new Key();
|
|
638
717
|
if (Predicate.isTagged(node, "Repeat")) return (s) => {
|
|
639
|
-
const
|
|
640
|
-
|
|
718
|
+
const at = s.pos;
|
|
719
|
+
const cp = resumable && s.resume !== void 0 ? resumeEntries(s, site, at) : void 0;
|
|
720
|
+
if (cp instanceof Resume.Done) return cp.value;
|
|
721
|
+
const resumed = cp !== void 0;
|
|
722
|
+
const acc = cp?.acc ?? new EntriesAcc();
|
|
723
|
+
for (let count = cp?.count ?? 0; count < max; count++) {
|
|
641
724
|
const start = s.pos;
|
|
642
725
|
let key;
|
|
643
726
|
let value;
|
|
@@ -651,50 +734,44 @@ var Compiler = class {
|
|
|
651
734
|
if (j === ki) key = a;
|
|
652
735
|
else if (j === vi) value = a;
|
|
653
736
|
}
|
|
654
|
-
if (!ok)
|
|
655
|
-
|
|
656
|
-
s.pos = start;
|
|
657
|
-
return acc.result();
|
|
658
|
-
}
|
|
659
|
-
if (checkLoop && s.pos === start) {
|
|
737
|
+
if (!ok) return stopEntries(s, site, at, resumed, acc, count, start, min);
|
|
738
|
+
if (s.pos === start) {
|
|
660
739
|
s.mode = CUT;
|
|
661
740
|
return Fail;
|
|
662
741
|
}
|
|
663
742
|
acc.add(key, value);
|
|
664
743
|
}
|
|
665
|
-
return acc
|
|
744
|
+
return entriesDone(s, site, at, resumed, acc);
|
|
666
745
|
};
|
|
667
746
|
const sep = this.compile(node.separator, false);
|
|
668
747
|
return (s) => {
|
|
669
|
-
const
|
|
670
|
-
|
|
671
|
-
if (
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
return acc.result();
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
start = s.pos;
|
|
681
|
-
if (sep(s) === Fail) {
|
|
682
|
-
if (s.mode !== BT || count < min) return Fail;
|
|
748
|
+
const at = s.pos;
|
|
749
|
+
const cp = resumable && s.resume !== void 0 ? resumeEntries(s, site, at) : void 0;
|
|
750
|
+
if (cp instanceof Resume.Done) return cp.value;
|
|
751
|
+
const resumed = cp !== void 0;
|
|
752
|
+
const acc = cp?.acc ?? new EntriesAcc();
|
|
753
|
+
let count = cp?.count ?? 0;
|
|
754
|
+
if (!resumed) {
|
|
755
|
+
if (max === 0) return acc.result();
|
|
756
|
+
const start = s.pos;
|
|
757
|
+
if (!entry(s, acc)) {
|
|
758
|
+
if (s.mode !== BT || min > 0) return Fail;
|
|
683
759
|
s.pos = start;
|
|
684
760
|
return acc.result();
|
|
685
761
|
}
|
|
686
|
-
|
|
762
|
+
count++;
|
|
763
|
+
}
|
|
764
|
+
while (count < max) {
|
|
765
|
+
const start = s.pos;
|
|
766
|
+
if (sep(s) === Fail) return stopEntries(s, site, at, resumed, acc, count, start, min);
|
|
767
|
+
if (s.pos === start) {
|
|
687
768
|
s.mode = CUT;
|
|
688
769
|
return Fail;
|
|
689
770
|
}
|
|
690
|
-
if (!entry(s, acc))
|
|
691
|
-
if (s.mode !== BT || count < min) return Fail;
|
|
692
|
-
s.pos = start;
|
|
693
|
-
return acc.result();
|
|
694
|
-
}
|
|
771
|
+
if (!entry(s, acc)) return stopEntries(s, site, at, resumed, acc, count, start, min);
|
|
695
772
|
count++;
|
|
696
773
|
}
|
|
697
|
-
return acc
|
|
774
|
+
return entriesDone(s, site, at, resumed, acc);
|
|
698
775
|
};
|
|
699
776
|
}
|
|
700
777
|
repeatTill(node) {
|
|
@@ -724,7 +801,6 @@ var Compiler = class {
|
|
|
724
801
|
}
|
|
725
802
|
separated(node, used) {
|
|
726
803
|
const { max, min } = node;
|
|
727
|
-
const checkLoop = max === Infinity;
|
|
728
804
|
const c = this.compile(node.self, used);
|
|
729
805
|
const sep = this.compile(node.separator, false);
|
|
730
806
|
const resumable = this.resumable;
|
|
@@ -772,7 +848,7 @@ var Compiler = class {
|
|
|
772
848
|
s.pos = start;
|
|
773
849
|
return resumed ? Resume.done(s, key, entry, true, acc) : acc;
|
|
774
850
|
}
|
|
775
|
-
if (
|
|
851
|
+
if (s.pos === start) {
|
|
776
852
|
s.mode = CUT;
|
|
777
853
|
return Fail;
|
|
778
854
|
}
|
|
@@ -961,12 +1037,14 @@ var Compiler = class {
|
|
|
961
1037
|
};
|
|
962
1038
|
}
|
|
963
1039
|
case "TakeWhile": return this.tokenTakeWhile(node, used);
|
|
964
|
-
case "TakeUntil":
|
|
965
|
-
|
|
1040
|
+
case "TakeUntil":
|
|
1041
|
+
case "TakeUntilAny": {
|
|
1042
|
+
const { max, min } = node;
|
|
966
1043
|
const bounded = min > 0 || max !== Infinity;
|
|
1044
|
+
const search = Predicate.isTagged(node, "TakeUntil") ? (s, from) => indexOf(s, node.literal, from) : (s, from) => indexOfAny(s, node.literals, from);
|
|
967
1045
|
return (s) => {
|
|
968
1046
|
const start = s.pos;
|
|
969
|
-
const idx =
|
|
1047
|
+
const idx = search(s, start);
|
|
970
1048
|
if (idx < 0) return failAt(s, s.end);
|
|
971
1049
|
if (bounded) {
|
|
972
1050
|
const count = countTokens(s, start, idx);
|
|
@@ -987,7 +1065,7 @@ var Compiler = class {
|
|
|
987
1065
|
const lit = node.literal;
|
|
988
1066
|
const literalKind = Predicate.isString(lit) ? 0 : lit instanceof Uint8Array ? 1 : 2;
|
|
989
1067
|
if (this.kind === 0) {
|
|
990
|
-
if (
|
|
1068
|
+
if (!Predicate.isString(lit)) return this.fallback(p, node, "byte or array literal on string input");
|
|
991
1069
|
const str = lit;
|
|
992
1070
|
const len = str.length;
|
|
993
1071
|
if (node.caseless) {
|
|
@@ -1003,8 +1081,8 @@ var Compiler = class {
|
|
|
1003
1081
|
}
|
|
1004
1082
|
return stringLiteral(str, str);
|
|
1005
1083
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1084
|
+
const bytes = Predicate.isString(lit) ? new TextEncoder().encode(lit) : lit instanceof Uint8Array ? lit : void 0;
|
|
1085
|
+
if (bytes === void 0) return this.fallback(p, node, "array literal on byte input");
|
|
1008
1086
|
const len = bytes.length;
|
|
1009
1087
|
const sameKind = literalKind === 1 && !node.caseless;
|
|
1010
1088
|
const expect = node.caseless ? Array.from(bytes, lowerAscii) : Array.from(bytes);
|
|
@@ -1036,6 +1114,8 @@ var Compiler = class {
|
|
|
1036
1114
|
s.pos = i;
|
|
1037
1115
|
return used ? bytes.subarray(start, i) : void 0;
|
|
1038
1116
|
};
|
|
1117
|
+
const stops = negate && min <= 1 && max === Infinity ? stopChars(set) : void 0;
|
|
1118
|
+
if (stops !== void 0) return stopTakeTill(stops, min, used);
|
|
1039
1119
|
const test = set.test;
|
|
1040
1120
|
return (s) => {
|
|
1041
1121
|
const str = s.input;
|
|
@@ -1071,7 +1151,7 @@ var Compiler = class {
|
|
|
1071
1151
|
const { fast, unitAt, width: unitWidth } = unitReader(this.kind, enc);
|
|
1072
1152
|
const decode = enc.decode;
|
|
1073
1153
|
const width = enc.width;
|
|
1074
|
-
const toText = enc.text;
|
|
1154
|
+
const toText = enc === utf8 ? utf8Text : (s, start, end) => enc.text(s.input, start, end);
|
|
1075
1155
|
switch (node._tag) {
|
|
1076
1156
|
case "Any": return (s) => {
|
|
1077
1157
|
const pos = s.pos;
|
|
@@ -1112,7 +1192,7 @@ var Compiler = class {
|
|
|
1112
1192
|
if (fold(cp) !== folded[i]) return failAt(s, pos);
|
|
1113
1193
|
}
|
|
1114
1194
|
s.pos = pos;
|
|
1115
|
-
return used ? toText(
|
|
1195
|
+
return used ? toText(s, start, pos) : void 0;
|
|
1116
1196
|
};
|
|
1117
1197
|
}
|
|
1118
1198
|
const encoded = enc.encode(lit);
|
|
@@ -1177,7 +1257,7 @@ var Compiler = class {
|
|
|
1177
1257
|
}
|
|
1178
1258
|
}
|
|
1179
1259
|
s.pos = pos;
|
|
1180
|
-
return used ? toText(
|
|
1260
|
+
return used ? toText(s, start, pos) : void 0;
|
|
1181
1261
|
};
|
|
1182
1262
|
}
|
|
1183
1263
|
case "TakeWhile": {
|
|
@@ -1197,6 +1277,7 @@ var Compiler = class {
|
|
|
1197
1277
|
return this.kind === 0 ? takeWhileString(loop, enc) : takeWhileBytes(loop, enc);
|
|
1198
1278
|
}
|
|
1199
1279
|
case "TakeUntil":
|
|
1280
|
+
case "TakeUntilAny":
|
|
1200
1281
|
case "Rest": return this.fallback(p, node, "Text parser without a compiled form");
|
|
1201
1282
|
}
|
|
1202
1283
|
}
|
|
@@ -1215,7 +1296,7 @@ var Compiler = class {
|
|
|
1215
1296
|
};
|
|
1216
1297
|
}
|
|
1217
1298
|
const { fast, unitAt, width } = unitReader(this.kind, enc);
|
|
1218
|
-
const toText = enc.text;
|
|
1299
|
+
const toText = enc === utf8 ? utf8Text : (s, start, end) => enc.text(s.input, start, end);
|
|
1219
1300
|
return (s) => {
|
|
1220
1301
|
const start = s.pos;
|
|
1221
1302
|
if (c(s) === Fail) return Fail;
|
|
@@ -1224,7 +1305,7 @@ var Compiler = class {
|
|
|
1224
1305
|
let i = start;
|
|
1225
1306
|
while (i < end && unitAt(input, i, end) < fast) i += width;
|
|
1226
1307
|
if (i < end && validate(enc, s, i, end) < 0) return fail(s);
|
|
1227
|
-
return used ? toText(
|
|
1308
|
+
return used ? toText(s, start, end) : void 0;
|
|
1228
1309
|
};
|
|
1229
1310
|
}
|
|
1230
1311
|
/**
|
|
@@ -1295,7 +1376,7 @@ var Compiler = class {
|
|
|
1295
1376
|
return Fail;
|
|
1296
1377
|
};
|
|
1297
1378
|
if (raw) {
|
|
1298
|
-
const slice = enc === void 0 ? (s, start) => s.slice(start, s.pos) : (s, start) => enc
|
|
1379
|
+
const slice = enc === void 0 ? (s, start) => s.slice(start, s.pos) : (s, start) => textIn(enc, s, start, s.pos);
|
|
1299
1380
|
return (s) => {
|
|
1300
1381
|
const start = s.pos;
|
|
1301
1382
|
let resumed = false;
|
|
@@ -1326,7 +1407,10 @@ var Compiler = class {
|
|
|
1326
1407
|
if (escape(s) === Fail) return s.mode === INC ? incomplete(s, start, before) : Fail;
|
|
1327
1408
|
} else return resumed ? Resume.done(s, key, start, true, slice(s, start)) : slice(s, start);
|
|
1328
1409
|
}
|
|
1329
|
-
if (s.partial)
|
|
1410
|
+
if (s.partial) {
|
|
1411
|
+
s.incomplete(0);
|
|
1412
|
+
return incomplete(s, start, s.pos);
|
|
1413
|
+
}
|
|
1330
1414
|
return resumed ? Resume.done(s, key, start, true, slice(s, start)) : slice(s, start);
|
|
1331
1415
|
};
|
|
1332
1416
|
}
|
|
@@ -1371,14 +1455,23 @@ var Compiler = class {
|
|
|
1371
1455
|
out += b;
|
|
1372
1456
|
} else return resumed ? Resume.done(s, key, start, true, out) : out;
|
|
1373
1457
|
}
|
|
1374
|
-
if (s.partial)
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1458
|
+
if (s.partial) {
|
|
1459
|
+
s.incomplete(0);
|
|
1460
|
+
return incomplete(s, start, {
|
|
1461
|
+
out,
|
|
1462
|
+
pos: s.pos
|
|
1463
|
+
});
|
|
1464
|
+
}
|
|
1378
1465
|
return resumed ? Resume.done(s, key, start, true, out) : out;
|
|
1379
1466
|
};
|
|
1380
1467
|
}
|
|
1381
1468
|
};
|
|
1469
|
+
/** How far past the cursor a token parser may read: its literals' length in UTF-8 at most, or `Margin`. */
|
|
1470
|
+
const marginOf = (node) => {
|
|
1471
|
+
if (Predicate.isTagged(node, "Literal") || Predicate.isTagged(node, "TakeUntil")) return node.literal.length * 4;
|
|
1472
|
+
if (Predicate.isTagged(node, "TakeUntilAny")) return Math.max(0, ...node.literals.map((lit) => lit.length)) * 4;
|
|
1473
|
+
return Margin;
|
|
1474
|
+
};
|
|
1382
1475
|
const fail = (s) => {
|
|
1383
1476
|
s.mode = BT;
|
|
1384
1477
|
return Fail;
|
|
@@ -1506,7 +1599,62 @@ const stringLiteral = (str, value) => {
|
|
|
1506
1599
|
return fail(s);
|
|
1507
1600
|
};
|
|
1508
1601
|
};
|
|
1509
|
-
/**
|
|
1602
|
+
/**
|
|
1603
|
+
* `Token.takeTill` on a string, of one to three stop characters that are
|
|
1604
|
+
* whole code points (see `search.ts`): every other unit, surrogates
|
|
1605
|
+
* included, is accepted, so the run ends at the first stop character, or
|
|
1606
|
+
* at the state's end.
|
|
1607
|
+
*/
|
|
1608
|
+
const stopTakeTill = (stops, min, used) => {
|
|
1609
|
+
const head = stops.length === 1 ? SearchHead : 2 * SearchHead;
|
|
1610
|
+
const c0 = stops[0];
|
|
1611
|
+
const c1 = stops.length > 1 ? stops[1] : -1;
|
|
1612
|
+
const c2 = stops.length > 2 ? stops[2] : -1;
|
|
1613
|
+
const one = String.fromCharCode(c0);
|
|
1614
|
+
const site = new StopCache(stops.map((u) => String.fromCharCode(u)));
|
|
1615
|
+
return (s) => {
|
|
1616
|
+
const str = s.input;
|
|
1617
|
+
const start = s.pos;
|
|
1618
|
+
const end = s.end;
|
|
1619
|
+
const h = start + head < end ? start + head : end;
|
|
1620
|
+
let i = start;
|
|
1621
|
+
let c = -1;
|
|
1622
|
+
while (i < h && (c = str.charCodeAt(i)) !== c0 && c !== c1 && c !== c2) i++;
|
|
1623
|
+
if (i === h && i < end && (c = str.charCodeAt(i)) !== c0 && c !== c1 && c !== c2) {
|
|
1624
|
+
if (stops.length === 1) {
|
|
1625
|
+
const at = str.indexOf(one, i);
|
|
1626
|
+
i = at < 0 || at > end ? end : at;
|
|
1627
|
+
} else i = nextStop(site, s, i);
|
|
1628
|
+
}
|
|
1629
|
+
if (i - start < min) return failAt(s, i);
|
|
1630
|
+
s.pos = i;
|
|
1631
|
+
return used ? str.slice(start, i) : void 0;
|
|
1632
|
+
};
|
|
1633
|
+
};
|
|
1634
|
+
/** Takes the checkpoint `entriesLoop` saved at `at`, restoring the position of a completed one. */
|
|
1635
|
+
const resumeEntries = (s, key, at) => {
|
|
1636
|
+
const cp = Resume.take(s, key, at);
|
|
1637
|
+
if (cp instanceof Resume.Done) s.pos = cp.pos;
|
|
1638
|
+
else if (cp !== void 0) s.pos = cp.pos;
|
|
1639
|
+
return cp;
|
|
1640
|
+
};
|
|
1641
|
+
/** The object `entriesLoop` built, recorded as done when the loop resumed. */
|
|
1642
|
+
const entriesDone = (s, key, at, resumed, acc) => resumed ? Resume.done(s, key, at, true, acc.result()) : acc.result();
|
|
1643
|
+
/**
|
|
1644
|
+
* Where `entriesLoop` stops at an entry (or separator) that failed at
|
|
1645
|
+
* `start`: a checkpoint when the input ran out, `Fail` unless the failure
|
|
1646
|
+
* backtracks after `min` entries, otherwise the object.
|
|
1647
|
+
*/
|
|
1648
|
+
const stopEntries = (s, site, at, resumed, acc, count, start, min) => {
|
|
1649
|
+
if (s.mode === INC && s.resume !== void 0) Resume.save(s, site, at, {
|
|
1650
|
+
acc,
|
|
1651
|
+
count,
|
|
1652
|
+
pos: start
|
|
1653
|
+
});
|
|
1654
|
+
if (s.mode !== BT || count < min) return Fail;
|
|
1655
|
+
s.pos = start;
|
|
1656
|
+
return entriesDone(s, site, at, resumed, acc);
|
|
1657
|
+
};
|
|
1510
1658
|
/** The object of `Object.fromEntries`, built an entry at a time (see `internal/entries.ts`). */
|
|
1511
1659
|
var EntriesAcc = class {
|
|
1512
1660
|
o = {};
|
|
@@ -1542,12 +1690,14 @@ const backend = { build: (p, kind, resumable) => Result.match(Result.try(() => c
|
|
|
1542
1690
|
onSuccess: ({ fallbacks, step }) => ({
|
|
1543
1691
|
backend: "closure",
|
|
1544
1692
|
step,
|
|
1693
|
+
guarded: false,
|
|
1545
1694
|
fallbacks,
|
|
1546
1695
|
error: void 0
|
|
1547
1696
|
}),
|
|
1548
1697
|
onFailure: (error) => ({
|
|
1549
|
-
backend:
|
|
1698
|
+
backend: "interpreted",
|
|
1550
1699
|
step: void 0,
|
|
1700
|
+
guarded: false,
|
|
1551
1701
|
fallbacks: [],
|
|
1552
1702
|
error
|
|
1553
1703
|
})
|