parseman 0.19.0 → 0.20.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/README.md +3 -3
- package/dist/combinators/regex.d.ts +7 -7
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/compiler/scannable-run.d.ts +2 -10
- package/dist/compiler/scannable-run.d.ts.map +1 -1
- package/dist/index.cjs +313 -217
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +313 -207
- package/dist/index.js.map +4 -4
- package/dist/plugin/index.cjs +313 -207
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.js +313 -207
- package/dist/plugin/index.js.map +4 -4
- package/dist/regex/classes.d.ts +40 -0
- package/dist/regex/classes.d.ts.map +1 -0
- package/dist/regex/first-set.d.ts +35 -0
- package/dist/regex/first-set.d.ts.map +1 -0
- package/package.json +2 -3
- package/dist/combinators/regex-analyze.d.ts +0 -6
- package/dist/combinators/regex-analyze.d.ts.map +0 -1
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,oBAAoB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1P,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAE9D,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -327,9 +327,9 @@ function asciiFoldEq(a, b) {
|
|
|
327
327
|
}
|
|
328
328
|
function literal(value, opts = {}) {
|
|
329
329
|
const caseInsensitive = opts.caseInsensitive ?? false;
|
|
330
|
-
const
|
|
330
|
+
const firstSet2 = value.length > 0 ? fromChar(value.codePointAt(0)) : empty();
|
|
331
331
|
const meta = {
|
|
332
|
-
firstSet,
|
|
332
|
+
firstSet: firstSet2,
|
|
333
333
|
canMatchNewline: value.includes("\n"),
|
|
334
334
|
isTrivia: false
|
|
335
335
|
};
|
|
@@ -341,7 +341,7 @@ function literal(value, opts = {}) {
|
|
|
341
341
|
meta.firstSet = firstLower !== void 0 && firstUpper !== void 0 ? firstLower === firstUpper ? { kind: "ranges", ranges: [{ lo: firstLower, hi: firstLower }] } : { kind: "ranges", ranges: [
|
|
342
342
|
{ lo: firstLower, hi: firstLower },
|
|
343
343
|
{ lo: firstUpper, hi: firstUpper }
|
|
344
|
-
] } :
|
|
344
|
+
] } : firstSet2;
|
|
345
345
|
}
|
|
346
346
|
return {
|
|
347
347
|
_tag: "literal",
|
|
@@ -364,68 +364,66 @@ function literal(value, opts = {}) {
|
|
|
364
364
|
};
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
-
// src/
|
|
368
|
-
var
|
|
369
|
-
function registerRegexAnalyzer(analyzer) {
|
|
370
|
-
firstSetAnalyzer = analyzer;
|
|
371
|
-
}
|
|
372
|
-
var permissiveFirstSet = () => ({ firstSet: any(), canMatchNewline: true });
|
|
373
|
-
var SCAN_BAIL_AT = 64;
|
|
367
|
+
// src/regex/classes.ts
|
|
368
|
+
var CLASS_ESCAPES = { t: 9, n: 10, r: 13, f: 12, v: 11, "0": 0 };
|
|
374
369
|
var SPACE_RANGES = [
|
|
375
370
|
[9, 13],
|
|
376
371
|
[32, 32],
|
|
377
372
|
[160, 160],
|
|
378
373
|
[5760, 5760],
|
|
379
374
|
[8192, 8202],
|
|
380
|
-
[8232,
|
|
375
|
+
[8232, 8232],
|
|
376
|
+
[8233, 8233],
|
|
381
377
|
[8239, 8239],
|
|
382
378
|
[8287, 8287],
|
|
383
379
|
[12288, 12288],
|
|
384
380
|
[65279, 65279]
|
|
385
381
|
];
|
|
386
|
-
var CLASS_ESCAPES = { t: 9, n: 10, r: 13, f: 12, v: 11, "0": 0 };
|
|
387
382
|
function shorthandRanges(ch) {
|
|
388
383
|
if (ch === "d") return [[48, 57]];
|
|
389
384
|
if (ch === "s") return SPACE_RANGES;
|
|
390
385
|
return [[48, 57], [65, 90], [97, 122], [95, 95]];
|
|
391
386
|
}
|
|
392
|
-
function
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
}
|
|
397
|
-
return false;
|
|
387
|
+
function readUnicodeEscape(body, i) {
|
|
388
|
+
if (body[i] !== "\\" || body[i + 1] !== "u") return null;
|
|
389
|
+
const hex = body.slice(i + 2, i + 6);
|
|
390
|
+
if (!/^[0-9a-fA-F]{4}$/.test(hex)) return null;
|
|
391
|
+
return { cp: Number.parseInt(hex, 16), next: i + 6 };
|
|
398
392
|
}
|
|
399
|
-
function
|
|
400
|
-
if (body.startsWith("^")) return null;
|
|
393
|
+
function parseClassRanges(body) {
|
|
401
394
|
const ranges = [];
|
|
402
395
|
let i = 0;
|
|
403
396
|
const readAtom = () => {
|
|
404
397
|
const ch = body[i];
|
|
405
398
|
if (ch === void 0) return null;
|
|
406
399
|
if (ch === "\\") {
|
|
407
|
-
const
|
|
408
|
-
if (
|
|
400
|
+
const uni = readUnicodeEscape(body, i);
|
|
401
|
+
if (uni) {
|
|
402
|
+
i = uni.next;
|
|
403
|
+
return { cp: uni.cp };
|
|
404
|
+
}
|
|
405
|
+
const e = body[i + 1];
|
|
406
|
+
if (e === void 0) return null;
|
|
409
407
|
i += 2;
|
|
410
|
-
if (
|
|
411
|
-
if (
|
|
412
|
-
if (
|
|
413
|
-
return { cp:
|
|
408
|
+
if (e in CLASS_ESCAPES) return { cp: CLASS_ESCAPES[e] };
|
|
409
|
+
if (e === "d" || e === "w" || e === "s") return { set: shorthandRanges(e) };
|
|
410
|
+
if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
411
|
+
return { cp: e.codePointAt(0) };
|
|
414
412
|
}
|
|
415
|
-
i
|
|
416
|
-
return { cp: ch.
|
|
413
|
+
i += ch.length;
|
|
414
|
+
return { cp: ch.codePointAt(0) };
|
|
417
415
|
};
|
|
418
416
|
while (i < body.length) {
|
|
419
417
|
const lo = readAtom();
|
|
420
|
-
if (
|
|
421
|
-
if ("
|
|
422
|
-
ranges.push(...lo.
|
|
418
|
+
if (lo === null) return null;
|
|
419
|
+
if ("set" in lo) {
|
|
420
|
+
ranges.push(...lo.set);
|
|
423
421
|
continue;
|
|
424
422
|
}
|
|
425
423
|
if (body[i] === "-" && body[i + 1] !== void 0 && body[i + 1] !== "]") {
|
|
426
|
-
i
|
|
424
|
+
i += 1;
|
|
427
425
|
const hi = readAtom();
|
|
428
|
-
if (
|
|
426
|
+
if (hi === null || "set" in hi) return null;
|
|
429
427
|
ranges.push([lo.cp, hi.cp]);
|
|
430
428
|
} else {
|
|
431
429
|
ranges.push([lo.cp, lo.cp]);
|
|
@@ -433,6 +431,25 @@ function readClassRanges(body) {
|
|
|
433
431
|
}
|
|
434
432
|
return ranges.length ? ranges : null;
|
|
435
433
|
}
|
|
434
|
+
|
|
435
|
+
// src/combinators/regex.ts
|
|
436
|
+
var firstSetAnalyzer = null;
|
|
437
|
+
function registerRegexAnalyzer(analyzer) {
|
|
438
|
+
firstSetAnalyzer = analyzer;
|
|
439
|
+
}
|
|
440
|
+
var permissiveFirstSet = () => ({ firstSet: any(), canMatchNewline: true });
|
|
441
|
+
var SCAN_BAIL_AT = 64;
|
|
442
|
+
function inRanges(cp, ranges) {
|
|
443
|
+
for (let i = 0; i < ranges.length; i++) {
|
|
444
|
+
const [lo, hi] = ranges[i];
|
|
445
|
+
if (cp >= lo && cp <= hi) return true;
|
|
446
|
+
}
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
function readClassRanges(body) {
|
|
450
|
+
if (body.startsWith("^")) return null;
|
|
451
|
+
return parseClassRanges(body);
|
|
452
|
+
}
|
|
436
453
|
function shortScanner(source, flags) {
|
|
437
454
|
if (/[imsuvy]/.test(flags)) return null;
|
|
438
455
|
let ranges = null;
|
|
@@ -466,8 +483,8 @@ function regex(pattern, flags = "") {
|
|
|
466
483
|
const resolvedFlags = typeof pattern === "string" ? flags : pattern.flags;
|
|
467
484
|
const anchored = new RegExp(source, "y" + resolvedFlags.replace(/[gy]/g, ""));
|
|
468
485
|
const scan = shortScanner(source, resolvedFlags);
|
|
469
|
-
const { firstSet, canMatchNewline } = (firstSetAnalyzer ?? permissiveFirstSet)(source);
|
|
470
|
-
const meta = { firstSet, canMatchNewline, isTrivia: false };
|
|
486
|
+
const { firstSet: firstSet2, canMatchNewline } = (firstSetAnalyzer ?? permissiveFirstSet)(source);
|
|
487
|
+
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
471
488
|
return {
|
|
472
489
|
_tag: "regex",
|
|
473
490
|
_meta: meta,
|
|
@@ -495,111 +512,266 @@ function regex(pattern, flags = "") {
|
|
|
495
512
|
};
|
|
496
513
|
}
|
|
497
514
|
|
|
498
|
-
// src/
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
return extractFirstSet(ast.body);
|
|
504
|
-
} catch {
|
|
505
|
-
return { firstSet: any(), canMatchNewline: true };
|
|
506
|
-
}
|
|
515
|
+
// src/regex/first-set.ts
|
|
516
|
+
var ANY = { t: "any" };
|
|
517
|
+
var EMPTY2 = { t: "empty" };
|
|
518
|
+
function charNode(set, nl) {
|
|
519
|
+
return { t: "char", set, nl };
|
|
507
520
|
}
|
|
508
|
-
function
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
521
|
+
function rangesToSet(ranges) {
|
|
522
|
+
let fs = empty();
|
|
523
|
+
for (const [lo, hi] of ranges) fs = union(fs, fromRange(lo, hi));
|
|
524
|
+
return fs;
|
|
525
|
+
}
|
|
526
|
+
function rangesHaveNewline(ranges) {
|
|
527
|
+
return ranges.some(([lo, hi]) => lo <= 10 && 10 <= hi);
|
|
528
|
+
}
|
|
529
|
+
var BAIL = /* @__PURE__ */ Symbol("regex-bail");
|
|
530
|
+
function parseRegex(src) {
|
|
531
|
+
let i = 0;
|
|
532
|
+
const parseAlt = () => {
|
|
533
|
+
const arms = [parseSeq()];
|
|
534
|
+
while (src[i] === "|") {
|
|
535
|
+
i++;
|
|
536
|
+
arms.push(parseSeq());
|
|
514
537
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
538
|
+
return arms.length === 1 ? arms[0] : { t: "alt", arms };
|
|
539
|
+
};
|
|
540
|
+
const parseSeq = () => {
|
|
541
|
+
const parts = [];
|
|
542
|
+
while (i < src.length) {
|
|
543
|
+
const ch = src[i];
|
|
544
|
+
if (ch === "|" || ch === ")") break;
|
|
545
|
+
parts.push(parseQuantified());
|
|
546
|
+
}
|
|
547
|
+
if (parts.length === 0) return EMPTY2;
|
|
548
|
+
return parts.length === 1 ? parts[0] : { t: "seq", parts };
|
|
549
|
+
};
|
|
550
|
+
const parseQuantified = () => {
|
|
551
|
+
const atom = parseAtom();
|
|
552
|
+
const ch = src[i];
|
|
553
|
+
let min = null;
|
|
554
|
+
if (ch === "*") {
|
|
555
|
+
min = 0;
|
|
556
|
+
i++;
|
|
557
|
+
} else if (ch === "+") {
|
|
558
|
+
min = 1;
|
|
559
|
+
i++;
|
|
560
|
+
} else if (ch === "?") {
|
|
561
|
+
min = 0;
|
|
562
|
+
i++;
|
|
563
|
+
} else if (ch === "{") {
|
|
564
|
+
min = parseBraceQuantifier();
|
|
518
565
|
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
566
|
+
if (min === null) return atom;
|
|
567
|
+
if (src[i] === "?") i++;
|
|
568
|
+
return { t: "rep", node: atom, min };
|
|
569
|
+
};
|
|
570
|
+
const parseBraceQuantifier = () => {
|
|
571
|
+
const close = src.indexOf("}", i);
|
|
572
|
+
if (close === -1) return null;
|
|
573
|
+
const m = /^(\d+)(?:,(\d*))?$/.exec(src.slice(i + 1, close));
|
|
574
|
+
if (!m) return null;
|
|
575
|
+
i = close + 1;
|
|
576
|
+
return Number.parseInt(m[1], 10);
|
|
577
|
+
};
|
|
578
|
+
const parseAtom = () => {
|
|
579
|
+
const ch = src[i];
|
|
580
|
+
switch (ch) {
|
|
581
|
+
case "(":
|
|
582
|
+
return parseGroup();
|
|
583
|
+
case "[":
|
|
584
|
+
return parseClass();
|
|
585
|
+
case ".":
|
|
586
|
+
i++;
|
|
587
|
+
return charNode(any(), false);
|
|
588
|
+
// `.` matches any char except line terminators
|
|
589
|
+
case "\\":
|
|
590
|
+
return parseEscape();
|
|
591
|
+
case "^":
|
|
592
|
+
case "$":
|
|
593
|
+
i++;
|
|
594
|
+
return EMPTY2;
|
|
595
|
+
// anchors are zero-width
|
|
596
|
+
case "{":
|
|
597
|
+
i++;
|
|
598
|
+
return charNode(fromRange(123, 123), false);
|
|
599
|
+
// a `{` with nothing to quantify is a literal brace
|
|
600
|
+
default:
|
|
601
|
+
i += ch.length;
|
|
602
|
+
return charNode(fromRange(ch.codePointAt(0), ch.codePointAt(0)), ch === "\n");
|
|
537
603
|
}
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
}
|
|
549
|
-
|
|
604
|
+
};
|
|
605
|
+
const parseGroup = () => {
|
|
606
|
+
i++;
|
|
607
|
+
let lookaround = false;
|
|
608
|
+
if (src[i] === "?") {
|
|
609
|
+
const c1 = src[i + 1];
|
|
610
|
+
if (c1 === ":") i += 2;
|
|
611
|
+
else if (c1 === "=" || c1 === "!") {
|
|
612
|
+
i += 2;
|
|
613
|
+
lookaround = true;
|
|
614
|
+
} else if (c1 === "<") {
|
|
615
|
+
const c2 = src[i + 2];
|
|
616
|
+
if (c2 === "=" || c2 === "!") {
|
|
617
|
+
i += 3;
|
|
618
|
+
lookaround = true;
|
|
619
|
+
} else {
|
|
620
|
+
const gt = src.indexOf(">", i);
|
|
621
|
+
if (gt === -1) throw BAIL;
|
|
622
|
+
i = gt + 1;
|
|
623
|
+
}
|
|
624
|
+
} else throw BAIL;
|
|
550
625
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
};
|
|
569
|
-
if (val === "s") return { firstSet: fromRange(9, 13), canMatchNewline: true };
|
|
570
|
-
if (val === "n") return { firstSet: fromRange(10, 10), canMatchNewline: true };
|
|
626
|
+
const inner = parseAlt();
|
|
627
|
+
if (src[i] !== ")") throw BAIL;
|
|
628
|
+
i++;
|
|
629
|
+
return lookaround ? EMPTY2 : inner;
|
|
630
|
+
};
|
|
631
|
+
const parseClass = () => {
|
|
632
|
+
let k = i + 1;
|
|
633
|
+
const negated = src[k] === "^";
|
|
634
|
+
if (negated) k++;
|
|
635
|
+
let body = "";
|
|
636
|
+
while (k < src.length && src[k] !== "]") {
|
|
637
|
+
if (src[k] === "\\") {
|
|
638
|
+
body += src[k] + (src[k + 1] ?? "");
|
|
639
|
+
k += 2;
|
|
640
|
+
} else {
|
|
641
|
+
body += src[k];
|
|
642
|
+
k++;
|
|
571
643
|
}
|
|
572
|
-
return { firstSet: any(), canMatchNewline: true };
|
|
573
644
|
}
|
|
574
|
-
|
|
575
|
-
|
|
645
|
+
if (src[k] !== "]") throw BAIL;
|
|
646
|
+
i = k + 1;
|
|
647
|
+
if (negated) return charNode(any(), true);
|
|
648
|
+
const ranges = parseClassRanges(body);
|
|
649
|
+
if (!ranges) return charNode(any(), true);
|
|
650
|
+
return charNode(rangesToSet(ranges), rangesHaveNewline(ranges));
|
|
651
|
+
};
|
|
652
|
+
const parseEscape = () => {
|
|
653
|
+
const e = src[i + 1];
|
|
654
|
+
if (e === void 0) throw BAIL;
|
|
655
|
+
if (e === "u" && /^[0-9a-fA-F]{4}$/.test(src.slice(i + 2, i + 6))) {
|
|
656
|
+
const cp = Number.parseInt(src.slice(i + 2, i + 6), 16);
|
|
657
|
+
i += 6;
|
|
658
|
+
return charNode(fromRange(cp, cp), cp === 10);
|
|
659
|
+
}
|
|
660
|
+
if (e === "x" && /^[0-9a-fA-F]{2}$/.test(src.slice(i + 2, i + 4))) {
|
|
661
|
+
const cp = Number.parseInt(src.slice(i + 2, i + 4), 16);
|
|
662
|
+
i += 4;
|
|
663
|
+
return charNode(fromRange(cp, cp), cp === 10);
|
|
664
|
+
}
|
|
665
|
+
i += 2;
|
|
666
|
+
switch (e) {
|
|
667
|
+
case "d":
|
|
668
|
+
return charNode(rangesToSet(shorthandRanges("d")), false);
|
|
669
|
+
case "w":
|
|
670
|
+
return charNode(rangesToSet(shorthandRanges("w")), false);
|
|
671
|
+
case "s":
|
|
672
|
+
return charNode(rangesToSet(shorthandRanges("s")), true);
|
|
673
|
+
case "D":
|
|
674
|
+
case "W":
|
|
675
|
+
case "S":
|
|
676
|
+
return charNode(any(), true);
|
|
677
|
+
// negated shorthand → widen
|
|
678
|
+
case "b":
|
|
679
|
+
case "B":
|
|
680
|
+
return EMPTY2;
|
|
681
|
+
// word boundary: zero-width
|
|
682
|
+
case "n":
|
|
683
|
+
return charNode(fromRange(10, 10), true);
|
|
684
|
+
case "r":
|
|
685
|
+
return charNode(fromRange(13, 13), false);
|
|
686
|
+
case "t":
|
|
687
|
+
return charNode(fromRange(9, 9), false);
|
|
688
|
+
case "f":
|
|
689
|
+
return charNode(fromRange(12, 12), false);
|
|
690
|
+
case "v":
|
|
691
|
+
return charNode(fromRange(11, 11), false);
|
|
692
|
+
case "0":
|
|
693
|
+
return charNode(fromRange(0, 0), false);
|
|
694
|
+
default:
|
|
695
|
+
if (e >= "1" && e <= "9") return ANY;
|
|
696
|
+
return charNode(fromRange(e.codePointAt(0), e.codePointAt(0)), e === "\n");
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
const node2 = parseAlt();
|
|
700
|
+
if (i < src.length) throw BAIL;
|
|
701
|
+
return node2;
|
|
702
|
+
}
|
|
703
|
+
function nullable(n) {
|
|
704
|
+
switch (n.t) {
|
|
705
|
+
case "char":
|
|
706
|
+
return false;
|
|
707
|
+
case "any":
|
|
708
|
+
return true;
|
|
709
|
+
case "empty":
|
|
710
|
+
return true;
|
|
711
|
+
case "seq":
|
|
712
|
+
return n.parts.every(nullable);
|
|
713
|
+
case "alt":
|
|
714
|
+
return n.arms.some(nullable);
|
|
715
|
+
case "rep":
|
|
716
|
+
return n.min === 0 || nullable(n.node);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
function firstSet(n) {
|
|
720
|
+
switch (n.t) {
|
|
721
|
+
case "char":
|
|
722
|
+
return n.set;
|
|
723
|
+
case "any":
|
|
724
|
+
return any();
|
|
725
|
+
case "empty":
|
|
726
|
+
return empty();
|
|
727
|
+
case "rep":
|
|
728
|
+
return firstSet(n.node);
|
|
729
|
+
case "alt": {
|
|
730
|
+
let fs = empty();
|
|
731
|
+
for (const arm of n.arms) fs = union(fs, firstSet(arm));
|
|
732
|
+
return fs;
|
|
733
|
+
}
|
|
734
|
+
case "seq": {
|
|
576
735
|
let fs = empty();
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
if (
|
|
580
|
-
const from = expr.from.codePoint;
|
|
581
|
-
const to = expr.to.codePoint;
|
|
582
|
-
fs = union(fs, fromRange(from, to));
|
|
583
|
-
if (from <= 10 && 10 <= to) canNL = true;
|
|
584
|
-
} else if (expr.type === "Char") {
|
|
585
|
-
const r = extractFirstSet(expr);
|
|
586
|
-
fs = union(fs, r.firstSet);
|
|
587
|
-
canNL = canNL || r.canMatchNewline;
|
|
588
|
-
}
|
|
736
|
+
for (const part of n.parts) {
|
|
737
|
+
fs = union(fs, firstSet(part));
|
|
738
|
+
if (!nullable(part)) break;
|
|
589
739
|
}
|
|
590
|
-
|
|
591
|
-
return { firstSet: fs, canMatchNewline: canNL };
|
|
740
|
+
return fs;
|
|
592
741
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
function firstCanBeNewline(n) {
|
|
745
|
+
switch (n.t) {
|
|
746
|
+
case "char":
|
|
747
|
+
return n.nl;
|
|
748
|
+
case "any":
|
|
749
|
+
return true;
|
|
750
|
+
case "empty":
|
|
751
|
+
return false;
|
|
752
|
+
case "rep":
|
|
753
|
+
return firstCanBeNewline(n.node);
|
|
754
|
+
case "alt":
|
|
755
|
+
return n.arms.some(firstCanBeNewline);
|
|
756
|
+
case "seq": {
|
|
757
|
+
for (const part of n.parts) {
|
|
758
|
+
if (firstCanBeNewline(part)) return true;
|
|
759
|
+
if (!nullable(part)) break;
|
|
760
|
+
}
|
|
761
|
+
return false;
|
|
598
762
|
}
|
|
599
|
-
default:
|
|
600
|
-
return { firstSet: any(), canMatchNewline: true };
|
|
601
763
|
}
|
|
602
764
|
}
|
|
765
|
+
function firstSetFromRegex(source) {
|
|
766
|
+
let ast;
|
|
767
|
+
try {
|
|
768
|
+
ast = parseRegex(source);
|
|
769
|
+
} catch {
|
|
770
|
+
return { firstSet: any(), canMatchNewline: true };
|
|
771
|
+
}
|
|
772
|
+
if (nullable(ast)) return { firstSet: any(), canMatchNewline: true };
|
|
773
|
+
return { firstSet: firstSet(ast), canMatchNewline: firstCanBeNewline(ast) };
|
|
774
|
+
}
|
|
603
775
|
|
|
604
776
|
// src/combinators/keywords.ts
|
|
605
777
|
function word(str, boundary = "_0-9A-Za-z") {
|
|
@@ -617,19 +789,19 @@ function keywords(words, opts = {}) {
|
|
|
617
789
|
const boundary = opts.boundary ? `(?![${opts.boundary}])` : "";
|
|
618
790
|
const flags = opts.caseInsensitive ? "iuy" : "uy";
|
|
619
791
|
const re = new RegExp(`(?:${alt})${boundary}`, flags);
|
|
620
|
-
let
|
|
792
|
+
let firstSet2 = empty();
|
|
621
793
|
for (const w of sorted) {
|
|
622
794
|
if (w.length === 0) continue;
|
|
623
795
|
const cp = w.codePointAt(0);
|
|
624
|
-
|
|
796
|
+
firstSet2 = union(firstSet2, fromChar(cp));
|
|
625
797
|
if (opts.caseInsensitive) {
|
|
626
798
|
const u = String.fromCodePoint(cp).toUpperCase().codePointAt(0);
|
|
627
799
|
const l = String.fromCodePoint(cp).toLowerCase().codePointAt(0);
|
|
628
|
-
if (u !== void 0)
|
|
629
|
-
if (l !== void 0)
|
|
800
|
+
if (u !== void 0) firstSet2 = union(firstSet2, fromChar(u));
|
|
801
|
+
if (l !== void 0) firstSet2 = union(firstSet2, fromChar(l));
|
|
630
802
|
}
|
|
631
803
|
}
|
|
632
|
-
const meta = { firstSet, canMatchNewline: false, isTrivia: false };
|
|
804
|
+
const meta = { firstSet: firstSet2, canMatchNewline: false, isTrivia: false };
|
|
633
805
|
return {
|
|
634
806
|
_tag: "keywords",
|
|
635
807
|
_meta: meta,
|
|
@@ -1993,77 +2165,11 @@ function expect(combinator, label2) {
|
|
|
1993
2165
|
|
|
1994
2166
|
// src/compiler/scannable-run.ts
|
|
1995
2167
|
var BACKSLASH = 92;
|
|
1996
|
-
var CLASS_ESCAPES2 = { t: 9, n: 10, r: 13, f: 12, v: 11, "0": 0 };
|
|
1997
2168
|
var META = new Set("()[]{}*+?|^$.".split(""));
|
|
1998
|
-
var SPACE_RANGES2 = [
|
|
1999
|
-
[9, 13],
|
|
2000
|
-
[32, 32],
|
|
2001
|
-
[160, 160],
|
|
2002
|
-
[5760, 5760],
|
|
2003
|
-
[8192, 8202],
|
|
2004
|
-
[8232, 8232],
|
|
2005
|
-
[8233, 8233],
|
|
2006
|
-
[8239, 8239],
|
|
2007
|
-
[8287, 8287],
|
|
2008
|
-
[12288, 12288],
|
|
2009
|
-
[65279, 65279]
|
|
2010
|
-
];
|
|
2011
|
-
function shorthandRanges2(ch) {
|
|
2012
|
-
if (ch === "d") return [[48, 57]];
|
|
2013
|
-
if (ch === "s") return SPACE_RANGES2;
|
|
2014
|
-
return [[48, 57], [65, 90], [97, 122], [95, 95]];
|
|
2015
|
-
}
|
|
2016
|
-
function readUnicodeEscape(body, i) {
|
|
2017
|
-
if (body[i] !== "\\" || body[i + 1] !== "u") return null;
|
|
2018
|
-
const hex = body.slice(i + 2, i + 6);
|
|
2019
|
-
if (!/^[0-9a-fA-F]{4}$/.test(hex)) return null;
|
|
2020
|
-
return { cp: Number.parseInt(hex, 16), next: i + 6 };
|
|
2021
|
-
}
|
|
2022
|
-
function parseClassRanges(body) {
|
|
2023
|
-
const ranges = [];
|
|
2024
|
-
let i = 0;
|
|
2025
|
-
const readAtom = () => {
|
|
2026
|
-
const ch = body[i];
|
|
2027
|
-
if (ch === void 0) return null;
|
|
2028
|
-
if (ch === "\\") {
|
|
2029
|
-
const uni = readUnicodeEscape(body, i);
|
|
2030
|
-
if (uni) {
|
|
2031
|
-
i = uni.next;
|
|
2032
|
-
return { cp: uni.cp };
|
|
2033
|
-
}
|
|
2034
|
-
const e = body[i + 1];
|
|
2035
|
-
if (e === void 0) return null;
|
|
2036
|
-
i += 2;
|
|
2037
|
-
if (e in CLASS_ESCAPES2) return { cp: CLASS_ESCAPES2[e] };
|
|
2038
|
-
if (e === "d" || e === "w" || e === "s") return { set: shorthandRanges2(e) };
|
|
2039
|
-
if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
2040
|
-
return { cp: e.codePointAt(0) };
|
|
2041
|
-
}
|
|
2042
|
-
i += ch.length;
|
|
2043
|
-
return { cp: ch.codePointAt(0) };
|
|
2044
|
-
};
|
|
2045
|
-
while (i < body.length) {
|
|
2046
|
-
const lo = readAtom();
|
|
2047
|
-
if (lo === null) return null;
|
|
2048
|
-
if ("set" in lo) {
|
|
2049
|
-
ranges.push(...lo.set);
|
|
2050
|
-
continue;
|
|
2051
|
-
}
|
|
2052
|
-
if (body[i] === "-" && body[i + 1] !== void 0 && body[i + 1] !== "]") {
|
|
2053
|
-
i += 1;
|
|
2054
|
-
const hi = readAtom();
|
|
2055
|
-
if (hi === null || "set" in hi) return null;
|
|
2056
|
-
ranges.push([lo.cp, hi.cp]);
|
|
2057
|
-
} else {
|
|
2058
|
-
ranges.push([lo.cp, lo.cp]);
|
|
2059
|
-
}
|
|
2060
|
-
}
|
|
2061
|
-
return ranges.length ? ranges : null;
|
|
2062
|
-
}
|
|
2063
2169
|
function classToRanges(cls) {
|
|
2064
|
-
if (cls === "\\d") return
|
|
2065
|
-
if (cls === "\\w") return
|
|
2066
|
-
if (cls === "\\s") return
|
|
2170
|
+
if (cls === "\\d") return shorthandRanges("d");
|
|
2171
|
+
if (cls === "\\w") return shorthandRanges("w");
|
|
2172
|
+
if (cls === "\\s") return shorthandRanges("s");
|
|
2067
2173
|
const body = cls.slice(1, -1);
|
|
2068
2174
|
if (body.startsWith("^")) return null;
|
|
2069
2175
|
return parseClassRanges(body);
|
|
@@ -2081,7 +2187,7 @@ function literalCodePoints(frag) {
|
|
|
2081
2187
|
if (ch === "\\") {
|
|
2082
2188
|
const e = frag[i + 1];
|
|
2083
2189
|
if (e === void 0) return null;
|
|
2084
|
-
out.push(e in
|
|
2190
|
+
out.push(e in CLASS_ESCAPES ? CLASS_ESCAPES[e] : e.codePointAt(0));
|
|
2085
2191
|
i += 2;
|
|
2086
2192
|
continue;
|
|
2087
2193
|
}
|
|
@@ -2174,7 +2280,7 @@ function parseSeqParts(source) {
|
|
|
2174
2280
|
if (e === "d" || e === "w" || e === "s") {
|
|
2175
2281
|
flush();
|
|
2176
2282
|
i += 2;
|
|
2177
|
-
i += runFrom(
|
|
2283
|
+
i += runFrom(shorthandRanges(e), false, source[i]);
|
|
2178
2284
|
continue;
|
|
2179
2285
|
}
|
|
2180
2286
|
const uni = readUnicodeEscape(source, i);
|
|
@@ -2183,8 +2289,8 @@ function parseSeqParts(source) {
|
|
|
2183
2289
|
cp2 = uni.cp;
|
|
2184
2290
|
i = uni.next;
|
|
2185
2291
|
} else if (e === void 0) return null;
|
|
2186
|
-
else if (e in
|
|
2187
|
-
cp2 =
|
|
2292
|
+
else if (e in CLASS_ESCAPES) {
|
|
2293
|
+
cp2 = CLASS_ESCAPES[e];
|
|
2188
2294
|
i += 2;
|
|
2189
2295
|
} else if (e >= "a" && e <= "z" || e >= "A" && e <= "Z") return null;
|
|
2190
2296
|
else {
|
|
@@ -2291,7 +2397,7 @@ function rangesSubset(sub, sup) {
|
|
|
2291
2397
|
}
|
|
2292
2398
|
function parseClassOperand(body) {
|
|
2293
2399
|
if (body === "\\d" || body === "\\w" || body === "\\s") {
|
|
2294
|
-
return { ranges:
|
|
2400
|
+
return { ranges: shorthandRanges(body[1]), negated: false };
|
|
2295
2401
|
}
|
|
2296
2402
|
if (body.length >= 2 && body[0] === "[" && body[body.length - 1] === "]") {
|
|
2297
2403
|
let inner = body.slice(1, -1);
|
|
@@ -2724,7 +2830,7 @@ function parseScanShapeCore(source) {
|
|
|
2724
2830
|
}
|
|
2725
2831
|
m = /^\\([dws])([+*])$/.exec(source);
|
|
2726
2832
|
if (m) {
|
|
2727
|
-
return { kind: "chars", ranges:
|
|
2833
|
+
return { kind: "chars", ranges: shorthandRanges(m[1]), minOne: m[2] === "+" };
|
|
2728
2834
|
}
|
|
2729
2835
|
m = /^(\[(?:\\.|[^\]])+\]|\\[dws])(\[(?:\\.|[^\]])+\]|\\[dws])\*$/.exec(source);
|
|
2730
2836
|
if (m) {
|