parseman 0.50.1 → 0.50.3
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 +14 -10
- package/dist/analysis/diagnostics.js +431 -219
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +421 -184
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/keywords.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/ref.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/repeat.d.ts.map +1 -1
- package/dist/combinators/scalar.d.ts +6 -0
- package/dist/combinators/scalar.d.ts.map +1 -0
- package/dist/combinators/sequence.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +2 -0
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +0 -3
- package/dist/compiler/token-capability.js.map +2 -2
- package/dist/index.js +422 -185
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +68 -172
- package/dist/language-service/index.js.map +3 -3
- package/dist/parse-context.d.ts.map +1 -1
- package/dist/plugin/index.js +467 -299
- package/dist/plugin/index.js.map +3 -3
- package/dist/run/index.js +1 -0
- package/dist/run/index.js.map +1 -1
- package/dist/spec/index.js +399 -277
- package/dist/spec/index.js.map +3 -3
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/index.js +307 -181
- package/dist/table/index.js.map +3 -3
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +4 -2
- package/src/combinators/choice.ts +34 -1
- package/src/combinators/grammar.ts +39 -0
- package/src/combinators/keywords.ts +14 -3
- package/src/combinators/literal.ts +26 -0
- package/src/combinators/map.ts +60 -0
- package/src/combinators/ref.ts +26 -7
- package/src/combinators/regex.ts +23 -0
- package/src/combinators/repeat.ts +109 -16
- package/src/combinators/scalar.ts +30 -0
- package/src/combinators/sequence.ts +76 -161
- package/src/combinators/trivia-skip.ts +14 -1
- package/src/parse-context.ts +1 -0
- package/src/table/emit-assembly.ts +39 -16
- package/src/types.ts +8 -0
- package/src/version.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -595,6 +595,28 @@ function literal(value, opts = {}) {
|
|
|
595
595
|
isTrivia: false
|
|
596
596
|
};
|
|
597
597
|
const canMatchNewline = meta.canMatchNewline;
|
|
598
|
+
const parseScalar = !caseInsensitive && value.length === 1 ? (() => {
|
|
599
|
+
const code = value.charCodeAt(0);
|
|
600
|
+
return (input, pos, ctx) => {
|
|
601
|
+
if (input.charCodeAt(pos) === code) {
|
|
602
|
+
ctx._sv = value;
|
|
603
|
+
return pos + 1;
|
|
604
|
+
}
|
|
605
|
+
ctx._fx = expected;
|
|
606
|
+
return ~pos;
|
|
607
|
+
};
|
|
608
|
+
})() : (input, pos, ctx) => {
|
|
609
|
+
const end = pos + value.length;
|
|
610
|
+
if (end <= input.length) {
|
|
611
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
612
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
613
|
+
ctx._sv = matchedValue;
|
|
614
|
+
return end;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
ctx._fx = expected;
|
|
618
|
+
return ~pos;
|
|
619
|
+
};
|
|
598
620
|
if (caseInsensitive) {
|
|
599
621
|
const upper = value.toUpperCase();
|
|
600
622
|
const lower = value.toLowerCase();
|
|
@@ -635,6 +657,7 @@ function literal(value, opts = {}) {
|
|
|
635
657
|
_tag: "literal",
|
|
636
658
|
_meta: meta,
|
|
637
659
|
_def: { tag: "literal", value, caseInsensitive },
|
|
660
|
+
_parseScalar: parseScalar,
|
|
638
661
|
parse: parse2
|
|
639
662
|
};
|
|
640
663
|
}
|
|
@@ -1091,10 +1114,32 @@ function regex(pattern, flags = "") {
|
|
|
1091
1114
|
const canMatchNewline = raw.canMatchNewline;
|
|
1092
1115
|
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
1093
1116
|
const def = { tag: "regex", source, flags: resolvedFlags };
|
|
1117
|
+
const expected = directTerminalFailureExpected(def);
|
|
1118
|
+
const parseScalar = (input, pos, ctx) => {
|
|
1119
|
+
const scanEnd = scan?.(input, pos);
|
|
1120
|
+
if (scanEnd !== void 0) {
|
|
1121
|
+
if (scanEnd === null) {
|
|
1122
|
+
ctx._fx = expected;
|
|
1123
|
+
return ~pos;
|
|
1124
|
+
}
|
|
1125
|
+
ctx._sv = input.slice(pos, scanEnd);
|
|
1126
|
+
return scanEnd;
|
|
1127
|
+
}
|
|
1128
|
+
anchored.lastIndex = pos;
|
|
1129
|
+
const match = anchored.exec(input);
|
|
1130
|
+
if (match === null) {
|
|
1131
|
+
ctx._fx = expected;
|
|
1132
|
+
return ~pos;
|
|
1133
|
+
}
|
|
1134
|
+
ctx._sv = match[0];
|
|
1135
|
+
return pos + match[0].length;
|
|
1136
|
+
};
|
|
1094
1137
|
return {
|
|
1095
1138
|
_tag: "regex",
|
|
1096
1139
|
_meta: meta,
|
|
1097
1140
|
_def: def,
|
|
1141
|
+
_stickyRegex: anchored,
|
|
1142
|
+
_parseScalar: parseScalar,
|
|
1098
1143
|
parse(input, pos, ctx) {
|
|
1099
1144
|
const scanEnd = scan?.(input, pos);
|
|
1100
1145
|
if (scanEnd !== void 0) {
|
|
@@ -1191,16 +1236,26 @@ function keywords(words, opts = {}) {
|
|
|
1191
1236
|
caseInsensitive: opts.caseInsensitive ?? false,
|
|
1192
1237
|
boundary: opts.boundary
|
|
1193
1238
|
};
|
|
1239
|
+
const expected = directTerminalFailureExpected(def);
|
|
1240
|
+
const parseScalar = (input, pos, ctx) => {
|
|
1241
|
+
re.lastIndex = pos;
|
|
1242
|
+
const m = re.exec(input);
|
|
1243
|
+
if (m === null) {
|
|
1244
|
+
ctx._fx = expected;
|
|
1245
|
+
return ~pos;
|
|
1246
|
+
}
|
|
1247
|
+
ctx._sv = m[0];
|
|
1248
|
+
return pos + m[0].length;
|
|
1249
|
+
};
|
|
1194
1250
|
return {
|
|
1195
1251
|
_tag: "keywords",
|
|
1196
1252
|
_meta: meta,
|
|
1197
1253
|
_def: def,
|
|
1254
|
+
_parseScalar: parseScalar,
|
|
1198
1255
|
parse(input, pos, ctx) {
|
|
1199
1256
|
re.lastIndex = pos;
|
|
1200
1257
|
const m = re.exec(input);
|
|
1201
|
-
if (m === null
|
|
1202
|
-
return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
1203
|
-
}
|
|
1258
|
+
if (m === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
1204
1259
|
const value = m[0];
|
|
1205
1260
|
const span = { start: pos, end: pos + value.length };
|
|
1206
1261
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
@@ -1227,6 +1282,7 @@ function createParseContext() {
|
|
|
1227
1282
|
_fe: void 0,
|
|
1228
1283
|
_fx: void 0,
|
|
1229
1284
|
_fc: void 0,
|
|
1285
|
+
_sv: void 0,
|
|
1230
1286
|
_probe: void 0,
|
|
1231
1287
|
_cstChildren: void 0,
|
|
1232
1288
|
_cstLeaves: void 0,
|
|
@@ -1927,6 +1983,9 @@ var fastScanner3;
|
|
|
1927
1983
|
function needsDeferredTriviaCommit(ctx) {
|
|
1928
1984
|
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
1929
1985
|
}
|
|
1986
|
+
function needsTriviaRollback(ctx) {
|
|
1987
|
+
return ctx._cstBuf !== void 0 || ctx._cstLeaves !== void 0 || ctx._cstRawChildren !== void 0 || ctx._cstTriviaLog !== void 0 || ctx._fields !== void 0 || ctx._errors !== void 0 || ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0;
|
|
1988
|
+
}
|
|
1930
1989
|
function saveTriviaMark(ctx) {
|
|
1931
1990
|
const m = saveCstMark(ctx);
|
|
1932
1991
|
return {
|
|
@@ -2043,7 +2102,8 @@ function advanceTrivia(input, cur, ctx) {
|
|
|
2043
2102
|
const triviaP = ctx.trivia;
|
|
2044
2103
|
if (!triviaP) return cur;
|
|
2045
2104
|
if (!ctx.trackLines) {
|
|
2046
|
-
const
|
|
2105
|
+
const classified = triviaP._meta.triviaScanner;
|
|
2106
|
+
const fast2 = classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
2047
2107
|
if (fast2) return fast2(input, cur);
|
|
2048
2108
|
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
2049
2109
|
const tr2 = triviaP.parse(input, cur, createDetachedParseContext(ctx.trackLines, ctx.state));
|
|
@@ -2634,6 +2694,28 @@ function notAdjacent(options) {
|
|
|
2634
2694
|
);
|
|
2635
2695
|
}
|
|
2636
2696
|
|
|
2697
|
+
// src/combinators/scalar.ts
|
|
2698
|
+
var SCALAR_TAG = /^(?:literal|regex|keywords|sequence|choice|many|oneOrMore|optional|transform|trivia|grammar|sepBy|lazy)$/;
|
|
2699
|
+
function scalarOf(combinator) {
|
|
2700
|
+
return combinator._parseScalar;
|
|
2701
|
+
}
|
|
2702
|
+
function scalarTree(parser2, seen) {
|
|
2703
|
+
if (seen.has(parser2)) return true;
|
|
2704
|
+
if (parser2._parseScalar === void 0) return false;
|
|
2705
|
+
seen.add(parser2);
|
|
2706
|
+
const def = parser2._def;
|
|
2707
|
+
if (!SCALAR_TAG.test(def.tag)) return false;
|
|
2708
|
+
if ("parsers" in def && !def.parsers.every((child) => scalarTree(child, seen))) return false;
|
|
2709
|
+
if ("parser" in def && !scalarTree(def.parser, seen)) return false;
|
|
2710
|
+
if ("separator" in def && !scalarTree(def.separator, seen)) return false;
|
|
2711
|
+
return def.tag !== "lazy" || scalarTree(def.thunk(), seen);
|
|
2712
|
+
}
|
|
2713
|
+
function scalarRootOf(combinator) {
|
|
2714
|
+
const scalar = combinator._parseScalar;
|
|
2715
|
+
const def = combinator._def;
|
|
2716
|
+
return scalar !== void 0 && def.tag === "grammar" && scalarTree(def.parser, /* @__PURE__ */ new Set()) ? scalar : void 0;
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2637
2719
|
// src/combinators/sequence.ts
|
|
2638
2720
|
function sequence(...parsers) {
|
|
2639
2721
|
let adjacency = null;
|
|
@@ -2649,6 +2731,7 @@ function sequence(...parsers) {
|
|
|
2649
2731
|
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
2650
2732
|
}
|
|
2651
2733
|
const hasAdjacency = adjacency !== null;
|
|
2734
|
+
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
2652
2735
|
const meta = {
|
|
2653
2736
|
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
2654
2737
|
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
@@ -2657,165 +2740,96 @@ function sequence(...parsers) {
|
|
|
2657
2740
|
isTrivia: false
|
|
2658
2741
|
};
|
|
2659
2742
|
const def = { tag: "sequence", parsers };
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
2663
|
-
const fs = parsers.slice(i + 1).reduce(
|
|
2664
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
2665
|
-
{ kind: "empty" }
|
|
2666
|
-
);
|
|
2667
|
-
return firstSetSentinel(fs);
|
|
2668
|
-
});
|
|
2669
|
-
const values = def.valueUnused ? void 0 : [];
|
|
2743
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
2744
|
+
const parseScalar = (input, pos, ctx) => {
|
|
2670
2745
|
let cur = pos;
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
const mTlog = cstTlLen(ctx);
|
|
2683
|
-
const mLog = ctx._triviaLog?.length ?? 0;
|
|
2684
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2685
|
-
let scanEnd;
|
|
2686
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2687
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
2688
|
-
} else {
|
|
2689
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2690
|
-
}
|
|
2691
|
-
const scanTlog = cstTlLen(ctx);
|
|
2692
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
2693
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2694
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2695
|
-
if (!result2.ok) return result2;
|
|
2696
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2697
|
-
else rollbackScannedTriviaAt(
|
|
2698
|
-
ctx,
|
|
2699
|
-
mTlog,
|
|
2700
|
-
scanTlog,
|
|
2701
|
-
mLog,
|
|
2702
|
-
scanLog,
|
|
2703
|
-
mRootLog,
|
|
2704
|
-
scanRootLog
|
|
2705
|
-
);
|
|
2706
|
-
if (values !== void 0) values.push(result2.value);
|
|
2707
|
-
continue;
|
|
2708
|
-
}
|
|
2709
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2710
|
-
if (!result.ok) return result;
|
|
2711
|
-
if (values !== void 0) values.push(result.value);
|
|
2712
|
-
cur = result.span.end;
|
|
2746
|
+
if (strictArity !== 0) {
|
|
2747
|
+
cur = scalarParsers[0](input, cur, ctx);
|
|
2748
|
+
if (cur < 0) return cur;
|
|
2749
|
+
const first = ctx._sv;
|
|
2750
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
2751
|
+
cur = scalarParsers[1](input, cur, ctx);
|
|
2752
|
+
if (cur < 0) return cur;
|
|
2753
|
+
const second = ctx._sv;
|
|
2754
|
+
if (strictArity === 2) {
|
|
2755
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second];
|
|
2756
|
+
return cur;
|
|
2713
2757
|
}
|
|
2714
|
-
|
|
2715
|
-
|
|
2758
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
2759
|
+
cur = scalarParsers[2](input, cur, ctx);
|
|
2760
|
+
if (cur < 0) return cur;
|
|
2761
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second, ctx._sv];
|
|
2762
|
+
return cur;
|
|
2716
2763
|
}
|
|
2717
|
-
return {
|
|
2718
|
-
ok: true,
|
|
2719
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2720
|
-
value: values ?? void 0,
|
|
2721
|
-
span: { start: pos, end: cur }
|
|
2722
|
-
};
|
|
2723
|
-
}
|
|
2724
|
-
function parseAdjacent(input, pos, ctx) {
|
|
2725
2764
|
const values = def.valueUnused ? void 0 : [];
|
|
2726
|
-
let
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2739
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
2740
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
2741
|
-
} else {
|
|
2742
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2743
|
-
}
|
|
2744
|
-
const scanTlog = cstTlLen(ctx);
|
|
2745
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
2746
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
2747
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
2748
|
-
if (!result2.ok) return result2;
|
|
2749
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
2750
|
-
else rollbackScannedTriviaAt(
|
|
2751
|
-
ctx,
|
|
2752
|
-
mTlog,
|
|
2753
|
-
scanTlog,
|
|
2754
|
-
mLog,
|
|
2755
|
-
scanLog,
|
|
2756
|
-
mRootLog,
|
|
2757
|
-
scanRootLog
|
|
2758
|
-
);
|
|
2759
|
-
if (values !== void 0) values.push(result2.value);
|
|
2760
|
-
continue;
|
|
2761
|
-
}
|
|
2762
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
2763
|
-
if (!result.ok) return result;
|
|
2764
|
-
if (values !== void 0) values.push(result.value);
|
|
2765
|
-
cur = result.span.end;
|
|
2766
|
-
}
|
|
2767
|
-
return {
|
|
2768
|
-
ok: true,
|
|
2769
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
2770
|
-
value: values ?? void 0,
|
|
2771
|
-
span: { start: pos, end: cur }
|
|
2772
|
-
};
|
|
2773
|
-
}
|
|
2765
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
2766
|
+
let termPos = cur;
|
|
2767
|
+
if (i > 0 && ctx.trivia) termPos = advanceTrivia(input, cur, ctx);
|
|
2768
|
+
const end = scalarParsers[i](input, termPos, ctx);
|
|
2769
|
+
if (end < 0) return end;
|
|
2770
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
2771
|
+
if (end > termPos || termPos === cur) cur = end;
|
|
2772
|
+
}
|
|
2773
|
+
ctx._sv = values;
|
|
2774
|
+
return cur;
|
|
2775
|
+
};
|
|
2776
|
+
let followSentinels;
|
|
2774
2777
|
return {
|
|
2775
2778
|
_tag: "sequence",
|
|
2776
2779
|
_meta: meta,
|
|
2777
2780
|
_def: def,
|
|
2781
|
+
_parseScalar: hasAdjacency ? void 0 : parseScalar,
|
|
2778
2782
|
parse(input, pos, ctx) {
|
|
2779
|
-
|
|
2780
|
-
if (
|
|
2783
|
+
const tolerant = ctx._tolerant === true;
|
|
2784
|
+
if (tolerant) {
|
|
2785
|
+
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
2786
|
+
parsers.slice(i + 1).reduce(
|
|
2787
|
+
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
2788
|
+
{ kind: "empty" }
|
|
2789
|
+
)
|
|
2790
|
+
));
|
|
2791
|
+
}
|
|
2792
|
+
const inheritedSync = ctx._sync;
|
|
2793
|
+
const deferredTrivia = needsDeferredTriviaCommit(ctx);
|
|
2781
2794
|
const values = def.valueUnused ? void 0 : [];
|
|
2782
2795
|
let cur = pos;
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
const
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
} else {
|
|
2792
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
2796
|
+
try {
|
|
2797
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2798
|
+
if (tolerant) ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
2799
|
+
const assertion = adjacency?.[i];
|
|
2800
|
+
if (assertion) {
|
|
2801
|
+
if (!holdsAdjacency(input, cur, ctx, assertion)) return adjacencyFail(cur, assertion);
|
|
2802
|
+
if (values !== void 0) values.push(null);
|
|
2803
|
+
continue;
|
|
2793
2804
|
}
|
|
2794
|
-
|
|
2795
|
-
const
|
|
2796
|
-
const
|
|
2797
|
-
const
|
|
2798
|
-
if (
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2805
|
+
let termPos = cur;
|
|
2806
|
+
const markTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
2807
|
+
const markLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
2808
|
+
const markRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
2809
|
+
if (ctx.trivia && i > 0) {
|
|
2810
|
+
termPos = deferredTrivia ? commitTriviaScan(scanTriviaCompact(input, cur, ctx)) : advanceTrivia(input, cur, ctx);
|
|
2811
|
+
}
|
|
2812
|
+
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
2813
|
+
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
2814
|
+
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
2815
|
+
const result = parsers[i].parse(input, termPos, ctx);
|
|
2816
|
+
if (!result.ok) return result;
|
|
2817
|
+
if (values !== void 0) values.push(result.value);
|
|
2818
|
+
if (result.span.end > termPos || termPos === cur) cur = result.span.end;
|
|
2819
|
+
else if (deferredTrivia) {
|
|
2802
2820
|
rollbackScannedTriviaAt(
|
|
2803
2821
|
ctx,
|
|
2804
|
-
|
|
2822
|
+
markTlog,
|
|
2805
2823
|
scanTlog,
|
|
2806
|
-
|
|
2824
|
+
markLog,
|
|
2807
2825
|
scanLog,
|
|
2808
|
-
|
|
2826
|
+
markRootLog,
|
|
2809
2827
|
scanRootLog
|
|
2810
2828
|
);
|
|
2811
2829
|
}
|
|
2812
|
-
if (values !== void 0) values.push(result2.value);
|
|
2813
|
-
continue;
|
|
2814
2830
|
}
|
|
2815
|
-
|
|
2816
|
-
if (
|
|
2817
|
-
if (values !== void 0) values.push(result.value);
|
|
2818
|
-
cur = result.span.end;
|
|
2831
|
+
} finally {
|
|
2832
|
+
if (tolerant) ctx._sync = inheritedSync;
|
|
2819
2833
|
}
|
|
2820
2834
|
return {
|
|
2821
2835
|
ok: true,
|
|
@@ -2950,7 +2964,8 @@ function choice(...args) {
|
|
|
2950
2964
|
disjoint
|
|
2951
2965
|
};
|
|
2952
2966
|
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
2953
|
-
const
|
|
2967
|
+
const ordered = strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix";
|
|
2968
|
+
const autoNot = !disjoint && !hasGates && ordered ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
2954
2969
|
let greedyLitMap = null;
|
|
2955
2970
|
let sortedParsers = null;
|
|
2956
2971
|
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
@@ -2964,6 +2979,37 @@ function choice(...args) {
|
|
|
2964
2979
|
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
2965
2980
|
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
2966
2981
|
}
|
|
2982
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
2983
|
+
const scalarEligible = !hasGates && parsers.every((p) => p._parseScalar !== void 0) && (disjoint || ordered);
|
|
2984
|
+
const scalarExpected = parsers.flatMap(deriveExpected);
|
|
2985
|
+
const parseScalar = (input, pos, ctx) => {
|
|
2986
|
+
if (disjoint) {
|
|
2987
|
+
const code = pos < input.length ? input.codePointAt(pos) : -1;
|
|
2988
|
+
let idx = code >= 0 && code < 128 ? asciiDispatch[code] : -1;
|
|
2989
|
+
if (idx < 0 && code >= 0) {
|
|
2990
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
2991
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
2992
|
+
idx = i;
|
|
2993
|
+
break;
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
if (idx >= 0) {
|
|
2998
|
+
const gate2 = gates[idx];
|
|
2999
|
+
if (!gate2 || gate2(ctx.state)) return scalarParsers[idx](input, pos, ctx);
|
|
3000
|
+
ctx._fx = deriveExpected(parsers[idx]);
|
|
3001
|
+
return ~pos;
|
|
3002
|
+
}
|
|
3003
|
+
} else {
|
|
3004
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
3005
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
3006
|
+
const end = scalarParsers[i](input, pos, ctx);
|
|
3007
|
+
if (end >= 0 && (!autoNot[i] || !autoNotFires(input, end, autoNot[i]))) return end;
|
|
3008
|
+
}
|
|
3009
|
+
}
|
|
3010
|
+
ctx._fx = scalarExpected;
|
|
3011
|
+
return ~pos;
|
|
3012
|
+
};
|
|
2967
3013
|
return {
|
|
2968
3014
|
_tag: "choice",
|
|
2969
3015
|
_meta: meta,
|
|
@@ -2975,6 +3021,7 @@ function choice(...args) {
|
|
|
2975
3021
|
strategy: strategy ?? { tag: "firstMatch" },
|
|
2976
3022
|
autoNot
|
|
2977
3023
|
},
|
|
3024
|
+
_parseScalar: scalarEligible ? parseScalar : void 0,
|
|
2978
3025
|
parse(input, pos, ctx) {
|
|
2979
3026
|
const expected = [];
|
|
2980
3027
|
let expectedAt = pos;
|
|
@@ -3509,8 +3556,8 @@ function attempt(parser2) {
|
|
|
3509
3556
|
}
|
|
3510
3557
|
|
|
3511
3558
|
// src/combinators/repeat.ts
|
|
3512
|
-
function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
3513
|
-
const mark = saveTriviaMark(ctx);
|
|
3559
|
+
function repItem(combinator, input, cur, ctx, guardable, mandatory, rollbackNeeded) {
|
|
3560
|
+
const mark = rollbackNeeded ? saveTriviaMark(ctx) : void 0;
|
|
3514
3561
|
let pos = cur;
|
|
3515
3562
|
if (ctx.trivia) {
|
|
3516
3563
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -3520,24 +3567,24 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
|
3520
3567
|
}
|
|
3521
3568
|
}
|
|
3522
3569
|
if (pos >= input.length && !mandatory) {
|
|
3523
|
-
rollbackTrivia(ctx, mark);
|
|
3570
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3524
3571
|
return "stop";
|
|
3525
3572
|
}
|
|
3526
3573
|
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
3527
|
-
rollbackTrivia(ctx, mark);
|
|
3574
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3528
3575
|
return "stop";
|
|
3529
3576
|
}
|
|
3530
3577
|
const result = combinator.parse(input, pos, ctx);
|
|
3531
3578
|
if (!result.ok) {
|
|
3532
|
-
rollbackTrivia(ctx, mark);
|
|
3579
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3533
3580
|
if (result.committed) return { fail: result, failPos: pos };
|
|
3534
3581
|
return { fail: result, failPos: pos };
|
|
3535
3582
|
}
|
|
3536
3583
|
if (result.span.end === pos && !mandatory) {
|
|
3537
|
-
rollbackTrivia(ctx, mark);
|
|
3584
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
3538
3585
|
return "stop";
|
|
3539
3586
|
}
|
|
3540
|
-
return
|
|
3587
|
+
return result;
|
|
3541
3588
|
}
|
|
3542
3589
|
function resolveBounds(what, opts) {
|
|
3543
3590
|
const min = opts.min ?? 0;
|
|
@@ -3550,6 +3597,21 @@ function resolveBounds(what, opts) {
|
|
|
3550
3597
|
if (max < min) bad(`max (${max}) is less than min (${min}) \u2014 the combinator could never succeed`);
|
|
3551
3598
|
return { min, max };
|
|
3552
3599
|
}
|
|
3600
|
+
function repeatScalarTail(combinator, child, input, cur, ctx, guardable, values, remaining) {
|
|
3601
|
+
while (cur < input.length && remaining > 0) {
|
|
3602
|
+
let itemPos = cur;
|
|
3603
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
3604
|
+
if (itemPos >= input.length) break;
|
|
3605
|
+
if (guardable && !startsFirstSet(combinator, input, itemPos)) break;
|
|
3606
|
+
const end = child(input, itemPos, ctx);
|
|
3607
|
+
if (end <= itemPos) break;
|
|
3608
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
3609
|
+
cur = end;
|
|
3610
|
+
remaining--;
|
|
3611
|
+
}
|
|
3612
|
+
ctx._sv = values;
|
|
3613
|
+
return cur;
|
|
3614
|
+
}
|
|
3553
3615
|
function many(combinator, opts = {}) {
|
|
3554
3616
|
const { min, max } = resolveBounds("many()", opts);
|
|
3555
3617
|
if (min >= 1) return atLeast(combinator, min, max);
|
|
@@ -3561,17 +3623,21 @@ function many(combinator, opts = {}) {
|
|
|
3561
3623
|
const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max } };
|
|
3562
3624
|
let expected;
|
|
3563
3625
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
3626
|
+
const scalarChild = scalarOf(combinator);
|
|
3627
|
+
const parseScalar = (input, pos, ctx) => repeatScalarTail(combinator, scalarChild, input, pos, ctx, guardable, def.valueUnused ? void 0 : [], max);
|
|
3564
3628
|
return {
|
|
3565
3629
|
_tag: "many",
|
|
3566
3630
|
_meta: meta,
|
|
3567
3631
|
_def: def,
|
|
3632
|
+
_parseScalar: parseScalar,
|
|
3568
3633
|
parse(input, pos, ctx) {
|
|
3569
3634
|
const values = def.valueUnused ? void 0 : [];
|
|
3635
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
3570
3636
|
let cur = pos;
|
|
3571
3637
|
let count = 0;
|
|
3572
3638
|
while (cur < input.length) {
|
|
3573
3639
|
if (count >= max) break;
|
|
3574
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
3640
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
3575
3641
|
if (item === "stop") break;
|
|
3576
3642
|
if ("fail" in item) {
|
|
3577
3643
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -3588,7 +3654,7 @@ function many(combinator, opts = {}) {
|
|
|
3588
3654
|
}
|
|
3589
3655
|
if (values !== void 0) values.push(item.value);
|
|
3590
3656
|
count++;
|
|
3591
|
-
cur = item.end;
|
|
3657
|
+
cur = item.span.end;
|
|
3592
3658
|
}
|
|
3593
3659
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
3594
3660
|
}
|
|
@@ -3606,30 +3672,47 @@ function atLeast(combinator, min, max) {
|
|
|
3606
3672
|
const def = { tag: "oneOrMore", parser: combinator, min, ...max === Infinity ? {} : { max } };
|
|
3607
3673
|
let expected;
|
|
3608
3674
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
3675
|
+
const scalarChild = scalarOf(combinator);
|
|
3676
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3677
|
+
let cur = scalarChild(input, pos, ctx);
|
|
3678
|
+
if (cur < 0) return cur;
|
|
3679
|
+
const values = def.valueUnused ? void 0 : [ctx._sv];
|
|
3680
|
+
for (let count = 1; count < min; count++) {
|
|
3681
|
+
let itemPos = cur;
|
|
3682
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
3683
|
+
const end = scalarChild(input, itemPos, ctx);
|
|
3684
|
+
if (end < 0) return ~cur;
|
|
3685
|
+
cur = end;
|
|
3686
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
3687
|
+
}
|
|
3688
|
+
return repeatScalarTail(combinator, scalarChild, input, cur, ctx, guardable, values, max - min);
|
|
3689
|
+
};
|
|
3609
3690
|
return {
|
|
3610
3691
|
_tag: "oneOrMore",
|
|
3611
3692
|
_meta: meta,
|
|
3612
3693
|
_def: def,
|
|
3694
|
+
_parseScalar: parseScalar,
|
|
3613
3695
|
parse(input, pos, ctx) {
|
|
3614
3696
|
const first = combinator.parse(input, pos, ctx);
|
|
3615
3697
|
if (!first.ok) return first;
|
|
3616
3698
|
const values = def.valueUnused ? void 0 : [first.value];
|
|
3699
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
3617
3700
|
let cur = first.span.end;
|
|
3618
3701
|
let count = 1;
|
|
3619
3702
|
while (count < min) {
|
|
3620
|
-
const item = repItem(combinator, input, cur, ctx, guardable, true);
|
|
3703
|
+
const item = repItem(combinator, input, cur, ctx, guardable, true, rollbackNeeded);
|
|
3621
3704
|
if (item === "stop" || "fail" in item) {
|
|
3622
3705
|
if (item !== "stop" && !item.fail.ok && item.fail.committed) return item.fail;
|
|
3623
3706
|
expected ??= deriveExpected(combinator);
|
|
3624
3707
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: cur, end: cur } };
|
|
3625
3708
|
}
|
|
3626
3709
|
if (values !== void 0) values.push(item.value);
|
|
3627
|
-
cur = item.end;
|
|
3710
|
+
cur = item.span.end;
|
|
3628
3711
|
count++;
|
|
3629
3712
|
}
|
|
3630
3713
|
while (cur < input.length) {
|
|
3631
3714
|
if (count >= max) break;
|
|
3632
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
3715
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
3633
3716
|
if (item === "stop") break;
|
|
3634
3717
|
if ("fail" in item) {
|
|
3635
3718
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -3646,7 +3729,7 @@ function atLeast(combinator, min, max) {
|
|
|
3646
3729
|
}
|
|
3647
3730
|
if (values !== void 0) values.push(item.value);
|
|
3648
3731
|
count++;
|
|
3649
|
-
cur = item.end;
|
|
3732
|
+
cur = item.span.end;
|
|
3650
3733
|
}
|
|
3651
3734
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
3652
3735
|
}
|
|
@@ -3659,10 +3742,22 @@ function optional(combinator) {
|
|
|
3659
3742
|
isTrivia: false
|
|
3660
3743
|
};
|
|
3661
3744
|
const firstSetSkippable = !matchesEmpty(combinator);
|
|
3745
|
+
const scalarChild = scalarOf(combinator);
|
|
3746
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3747
|
+
if (firstSetSkippable && !startsFirstSet(combinator, input, pos)) {
|
|
3748
|
+
ctx._sv = null;
|
|
3749
|
+
return pos;
|
|
3750
|
+
}
|
|
3751
|
+
const end = scalarChild(input, pos, ctx);
|
|
3752
|
+
if (end >= 0) return end;
|
|
3753
|
+
ctx._sv = null;
|
|
3754
|
+
return pos;
|
|
3755
|
+
};
|
|
3662
3756
|
return {
|
|
3663
3757
|
_tag: "optional",
|
|
3664
3758
|
_meta: meta,
|
|
3665
3759
|
_def: { tag: "optional", parser: combinator },
|
|
3760
|
+
_parseScalar: parseScalar,
|
|
3666
3761
|
parse(input, pos, ctx) {
|
|
3667
3762
|
if (firstSetSkippable && ctx._probe === void 0 && !startsFirstSet(combinator, input, pos)) {
|
|
3668
3763
|
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
@@ -3699,6 +3794,43 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
3699
3794
|
expected ??= deriveExpected(combinator);
|
|
3700
3795
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: at, end: at } };
|
|
3701
3796
|
};
|
|
3797
|
+
const scalarExpected = deriveExpected(combinator);
|
|
3798
|
+
const scalarChild = scalarOf(combinator);
|
|
3799
|
+
const scalarSeparator = scalarOf(separator);
|
|
3800
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3801
|
+
let cur = scalarChild(input, pos, ctx);
|
|
3802
|
+
if (cur < 0) {
|
|
3803
|
+
if (min >= 1) {
|
|
3804
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
3805
|
+
return ~pos;
|
|
3806
|
+
}
|
|
3807
|
+
ctx._sv = [];
|
|
3808
|
+
return pos;
|
|
3809
|
+
}
|
|
3810
|
+
const values = [ctx._sv];
|
|
3811
|
+
while (values.length < max && (cur < input.length || values.length < min)) {
|
|
3812
|
+
const beforeSeparator = cur;
|
|
3813
|
+
let separatorPos = cur;
|
|
3814
|
+
if (ctx.trivia) separatorPos = advanceTrivia(input, cur, ctx);
|
|
3815
|
+
const separatorEnd = scalarSeparator(input, separatorPos, ctx);
|
|
3816
|
+
if (separatorEnd < 0) break;
|
|
3817
|
+
let itemPos = separatorEnd;
|
|
3818
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, itemPos, ctx);
|
|
3819
|
+
const itemEnd = scalarChild(input, itemPos, ctx);
|
|
3820
|
+
if (itemEnd < 0) {
|
|
3821
|
+
cur = trailing === "allow" ? separatorEnd : beforeSeparator;
|
|
3822
|
+
break;
|
|
3823
|
+
}
|
|
3824
|
+
values.push(ctx._sv);
|
|
3825
|
+
cur = itemEnd;
|
|
3826
|
+
}
|
|
3827
|
+
if (values.length < min) {
|
|
3828
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
3829
|
+
return ~cur;
|
|
3830
|
+
}
|
|
3831
|
+
ctx._sv = values;
|
|
3832
|
+
return cur;
|
|
3833
|
+
};
|
|
3702
3834
|
return {
|
|
3703
3835
|
_tag: "sepBy",
|
|
3704
3836
|
_meta: meta,
|
|
@@ -3714,6 +3846,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
3714
3846
|
// this option surface already; parity is held by test/parity, not by hope.
|
|
3715
3847
|
...keepSeparators ? { keepSeparators: true } : {}
|
|
3716
3848
|
},
|
|
3849
|
+
_parseScalar: keepSeparators ? void 0 : parseScalar,
|
|
3717
3850
|
parse(input, pos, ctx) {
|
|
3718
3851
|
const first = combinator.parse(input, pos, ctx);
|
|
3719
3852
|
const values = [];
|
|
@@ -3827,8 +3960,20 @@ function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
|
3827
3960
|
}
|
|
3828
3961
|
|
|
3829
3962
|
// src/combinators/ref.ts
|
|
3963
|
+
function withRuleTrivia(trivia2, ctx, run3) {
|
|
3964
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
3965
|
+
ctx.trivia = trivia2;
|
|
3966
|
+
ctx.triviaKindLabels = trivia2._meta.triviaKindLabels;
|
|
3967
|
+
try {
|
|
3968
|
+
return run3();
|
|
3969
|
+
} finally {
|
|
3970
|
+
ctx.trivia = void 0;
|
|
3971
|
+
ctx.triviaKindLabels = savedLabels;
|
|
3972
|
+
}
|
|
3973
|
+
}
|
|
3830
3974
|
function ref() {
|
|
3831
3975
|
let resolved = null;
|
|
3976
|
+
let resolvedScalar = null;
|
|
3832
3977
|
let ownBoundary = false;
|
|
3833
3978
|
const meta = {
|
|
3834
3979
|
firstSet: any(),
|
|
@@ -3845,25 +3990,28 @@ function ref() {
|
|
|
3845
3990
|
return resolved;
|
|
3846
3991
|
}
|
|
3847
3992
|
},
|
|
3993
|
+
_parseScalar(input, pos, ctx) {
|
|
3994
|
+
const scalar = resolvedScalar;
|
|
3995
|
+
if (!scalar) throw new Error("ref<T>() used before .define() was called");
|
|
3996
|
+
const gt = meta.grammarTrivia;
|
|
3997
|
+
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
3998
|
+
return withRuleTrivia(gt, ctx, () => scalar(input, pos, ctx));
|
|
3999
|
+
}
|
|
4000
|
+
return scalar(input, pos, ctx);
|
|
4001
|
+
},
|
|
3848
4002
|
parse(input, pos, ctx) {
|
|
3849
|
-
|
|
4003
|
+
const parser2 = resolved;
|
|
4004
|
+
if (!parser2) throw new Error("ref<T>() used before .define() was called");
|
|
3850
4005
|
const gt = meta.grammarTrivia;
|
|
3851
4006
|
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
3852
|
-
|
|
3853
|
-
ctx.trivia = gt;
|
|
3854
|
-
ctx.triviaKindLabels = gt._meta.triviaKindLabels;
|
|
3855
|
-
try {
|
|
3856
|
-
return resolved.parse(input, pos, ctx);
|
|
3857
|
-
} finally {
|
|
3858
|
-
ctx.trivia = void 0;
|
|
3859
|
-
ctx.triviaKindLabels = savedLabels;
|
|
3860
|
-
}
|
|
4007
|
+
return withRuleTrivia(gt, ctx, () => parser2.parse(input, pos, ctx));
|
|
3861
4008
|
}
|
|
3862
|
-
return
|
|
4009
|
+
return parser2.parse(input, pos, ctx);
|
|
3863
4010
|
},
|
|
3864
4011
|
define(p) {
|
|
3865
4012
|
if (resolved) throw new Error("ref<T>() already defined");
|
|
3866
4013
|
resolved = p;
|
|
4014
|
+
resolvedScalar = scalarOf(p);
|
|
3867
4015
|
ownBoundary = hasOwnTriviaBoundary(p);
|
|
3868
4016
|
meta.firstSet = p._meta.firstSet;
|
|
3869
4017
|
meta.canMatchNewline = p._meta.canMatchNewline;
|
|
@@ -4021,6 +4169,24 @@ function parser(opts, root) {
|
|
|
4021
4169
|
const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
|
|
4022
4170
|
const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
|
|
4023
4171
|
const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
|
|
4172
|
+
const rootScalar = scalarOf(root);
|
|
4173
|
+
const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
|
|
4174
|
+
const parseScalar = scalarEligible ? (input, pos, ctx) => {
|
|
4175
|
+
const savedTrivia = ctx.trivia;
|
|
4176
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
4177
|
+
if (clearTrivia) {
|
|
4178
|
+
ctx.trivia = void 0;
|
|
4179
|
+
ctx.triviaKindLabels = void 0;
|
|
4180
|
+
} else if (scopeTrivia !== void 0) {
|
|
4181
|
+
ctx.trivia = scopeTrivia;
|
|
4182
|
+
ctx.triviaKindLabels = scopeLabels;
|
|
4183
|
+
}
|
|
4184
|
+
const end = rootScalar(input, pos, ctx);
|
|
4185
|
+
ctx.trivia = savedTrivia;
|
|
4186
|
+
ctx.triviaKindLabels = savedLabels;
|
|
4187
|
+
return end;
|
|
4188
|
+
} : void 0;
|
|
4189
|
+
let publicScalar;
|
|
4024
4190
|
const grammar = {
|
|
4025
4191
|
_tag: "grammar",
|
|
4026
4192
|
_meta: {
|
|
@@ -4044,7 +4210,20 @@ function parser(opts, root) {
|
|
|
4044
4210
|
constructionTrackLines: trackLinesPolicy,
|
|
4045
4211
|
...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
|
|
4046
4212
|
},
|
|
4213
|
+
_parseScalar: parseScalar,
|
|
4047
4214
|
parse(input, pos, _ctx) {
|
|
4215
|
+
if (pos === void 0 && _ctx === void 0) {
|
|
4216
|
+
publicScalar ??= scalarRootOf(grammar) ?? null;
|
|
4217
|
+
if (publicScalar) {
|
|
4218
|
+
const ctx2 = createParseContext();
|
|
4219
|
+
const end = publicScalar(input, 0, ctx2);
|
|
4220
|
+
if (end < 0) {
|
|
4221
|
+
const at = ~end;
|
|
4222
|
+
return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
|
|
4223
|
+
}
|
|
4224
|
+
return { ok: true, value: ctx2._sv, span: { start: 0, end } };
|
|
4225
|
+
}
|
|
4226
|
+
}
|
|
4048
4227
|
if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
|
|
4049
4228
|
const trackLines = trackLinesOf(_ctx);
|
|
4050
4229
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
@@ -4082,6 +4261,9 @@ function parse(combinator, input, opts = {}) {
|
|
|
4082
4261
|
_analyzed.add(combinator);
|
|
4083
4262
|
markUnusedValues(combinator);
|
|
4084
4263
|
}
|
|
4264
|
+
if (!opts.trackLines && !opts.recover && combinator._def.tag === "grammar" && combinator._meta.grammarScanSkip === void 0) {
|
|
4265
|
+
return combinator.parse(input);
|
|
4266
|
+
}
|
|
4085
4267
|
const trackLines = opts.trackLines ?? combinator._meta.grammarTrackLines ?? false;
|
|
4086
4268
|
const lineContext = trackLines ? createParseLineContext(input, 0) : void 0;
|
|
4087
4269
|
const lineIndex = lineContext?.lineIndex;
|
|
@@ -4820,11 +5002,54 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
4820
5002
|
}
|
|
4821
5003
|
|
|
4822
5004
|
// src/combinators/map.ts
|
|
5005
|
+
var JSON_STRING_BODY = String.raw`(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*`;
|
|
4823
5006
|
function transform(combinator, fn) {
|
|
5007
|
+
const observesSpan = fn.length > 1;
|
|
5008
|
+
const sequenceDef = combinator._def.tag === "sequence" ? combinator._def : void 0;
|
|
5009
|
+
const terms = sequenceDef?.parsers;
|
|
5010
|
+
const inner = terms?.[1];
|
|
5011
|
+
const fused = terms?.length === 3 && terms[0]._def.tag === "literal" && terms[0]._def.value === '"' && !terms[0]._def.caseInsensitive && inner._def.tag === "regex" && inner._def.source === JSON_STRING_BODY && inner._def.flags === "" && terms[2]._def.tag === "literal" && terms[2]._def.value === '"' && !terms[2]._def.caseInsensitive && inner._stickyRegex !== void 0;
|
|
5012
|
+
const child = scalarOf(combinator);
|
|
5013
|
+
const parseScalar = fused ? (() => {
|
|
5014
|
+
const body = inner._stickyRegex;
|
|
5015
|
+
const tuple = ['"', "", '"'];
|
|
5016
|
+
const expected = [JSON.stringify('"')];
|
|
5017
|
+
return (input, pos, ctx) => {
|
|
5018
|
+
if (ctx.trivia !== void 0) {
|
|
5019
|
+
const end2 = child(input, pos, ctx);
|
|
5020
|
+
if (end2 < 0) return end2;
|
|
5021
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end: end2 }) : fn(ctx._sv);
|
|
5022
|
+
return end2;
|
|
5023
|
+
}
|
|
5024
|
+
if (input.charCodeAt(pos) !== 34) {
|
|
5025
|
+
ctx._fx = expected;
|
|
5026
|
+
return ~pos;
|
|
5027
|
+
}
|
|
5028
|
+
body.lastIndex = pos + 1;
|
|
5029
|
+
const match = body.exec(input);
|
|
5030
|
+
const close = pos + 1 + match[0].length;
|
|
5031
|
+
if (input.charCodeAt(close) !== 34) {
|
|
5032
|
+
ctx._fx = expected;
|
|
5033
|
+
return ~close;
|
|
5034
|
+
}
|
|
5035
|
+
tuple[1] = match[0];
|
|
5036
|
+
const end = close + 1;
|
|
5037
|
+
ctx._sv = observesSpan ? fn(tuple, { start: pos, end }) : fn(tuple);
|
|
5038
|
+
return end;
|
|
5039
|
+
};
|
|
5040
|
+
})() : /* @__PURE__ */ (() => {
|
|
5041
|
+
return (input, pos, ctx) => {
|
|
5042
|
+
const end = child(input, pos, ctx);
|
|
5043
|
+
if (end < 0) return end;
|
|
5044
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end }) : fn(ctx._sv);
|
|
5045
|
+
return end;
|
|
5046
|
+
};
|
|
5047
|
+
})();
|
|
4824
5048
|
return {
|
|
4825
5049
|
_tag: "transform",
|
|
4826
5050
|
_meta: combinator._meta,
|
|
4827
5051
|
_def: { tag: "transform", parser: combinator, fn },
|
|
5052
|
+
_parseScalar: parseScalar,
|
|
4828
5053
|
parse(input, pos, ctx) {
|
|
4829
5054
|
const result = combinator.parse(input, pos, ctx);
|
|
4830
5055
|
if (!result.ok) return result;
|
|
@@ -4839,9 +5064,11 @@ function trivia(combinator) {
|
|
|
4839
5064
|
_meta: {
|
|
4840
5065
|
...combinator._meta,
|
|
4841
5066
|
isTrivia: true,
|
|
5067
|
+
triviaScanner: fastTriviaScanner(combinator),
|
|
4842
5068
|
...kindLabels ? { triviaKindLabels: kindLabels } : {}
|
|
4843
5069
|
},
|
|
4844
5070
|
_def: { tag: "trivia", parser: combinator },
|
|
5071
|
+
_parseScalar: scalarOf(combinator),
|
|
4845
5072
|
parse: combinator.parse.bind(combinator)
|
|
4846
5073
|
};
|
|
4847
5074
|
}
|
|
@@ -9772,6 +9999,9 @@ if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTrivi
|
|
|
9772
9999
|
function q(s) {
|
|
9773
10000
|
return JSON.stringify(s);
|
|
9774
10001
|
}
|
|
10002
|
+
function isAsciiOnlyClass(cls) {
|
|
10003
|
+
return cls !== null && cls !== void 0 && cls.hi.length === 0;
|
|
10004
|
+
}
|
|
9775
10005
|
var NO_SINKS = { fd: false, er: false };
|
|
9776
10006
|
function sinkSlots(t, s) {
|
|
9777
10007
|
return `${s.fd ? `,${t}fd=0` : ""}${s.er ? `,${t}er=0` : ""}`;
|
|
@@ -10318,12 +10548,13 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
10318
10548
|
return `${head}EC.e=pos;return ''}`;
|
|
10319
10549
|
case OP_GATE: {
|
|
10320
10550
|
const child = link(code[ip + 2]);
|
|
10321
|
-
const
|
|
10551
|
+
const resolved = t.cc[code[ip + 1]];
|
|
10552
|
+
const ci = classes.push([resolved]) - 1;
|
|
10322
10553
|
classPlan.push([code[ip + 1]]);
|
|
10323
10554
|
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
10324
10555
|
const xf = fxRef(code[ip + 3]);
|
|
10325
10556
|
return `${head}
|
|
10326
|
-
if(
|
|
10557
|
+
if(${staticBuild && isAsciiOnlyClass(resolved) ? `${cls}.ascii[input.charCodeAt(pos)]!==1` : `!classHas(${cls},lead(input,pos))`}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
10327
10558
|
return ${child}(input,pos,ctx)
|
|
10328
10559
|
}`;
|
|
10329
10560
|
}
|
|
@@ -10666,10 +10897,11 @@ return v
|
|
|
10666
10897
|
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
10667
10898
|
const hiArr = table.hi;
|
|
10668
10899
|
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
10900
|
+
const directAscii = staticBuild && table.hi.length === 0;
|
|
10669
10901
|
return `${head}
|
|
10670
|
-
const c
|
|
10902
|
+
const c=${directAscii ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
10671
10903
|
let arm=-1
|
|
10672
|
-
if(c>=0&&c<128){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
10904
|
+
if(${directAscii ? "c<128" : "c>=0&&c<128"}){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
10673
10905
|
${hiArr.length === 0 ? "" : `else if(c>=128){const h=${hoist("hi", `DISP[${di}].hi`)}
|
|
10674
10906
|
for(let i=0;i<h.length;i+=3){if(c>=h[i]&&c<=h[i+1]){arm=h[i+2];break}}}`}
|
|
10675
10907
|
if(arm>=0){
|
|
@@ -10691,7 +10923,9 @@ return FAIL
|
|
|
10691
10923
|
const di = code[ip + 1];
|
|
10692
10924
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
10693
10925
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
10694
|
-
const
|
|
10926
|
+
const maskable = n <= 32;
|
|
10927
|
+
const directAsciiMask = staticBuild && maskable && gates.every(isAsciiOnlyClass);
|
|
10928
|
+
const gateRefs = directAsciiMask ? [] : Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
10695
10929
|
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
10696
10930
|
const pretests = Array.from({ length: n }, (_, i) => {
|
|
10697
10931
|
if (tokenCandidate?.arm === i) {
|
|
@@ -10711,7 +10945,6 @@ return FAIL
|
|
|
10711
10945
|
const sequence6 = largeChoiceScalarSequences.get(code[base + i]);
|
|
10712
10946
|
return sequence6 === void 0 ? void 0 : { sequence: scalarSequenceRef(sequence6) };
|
|
10713
10947
|
});
|
|
10714
|
-
const maskable = n <= 32;
|
|
10715
10948
|
const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
|
|
10716
10949
|
if (maskable) maskPlan.push(~di);
|
|
10717
10950
|
const p = tmp();
|
|
@@ -10773,16 +11006,16 @@ ${merge2}
|
|
|
10773
11006
|
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
10774
11007
|
return FAIL`;
|
|
10775
11008
|
return `${head}
|
|
10776
|
-
const c
|
|
11009
|
+
const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
10777
11010
|
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
10778
11011
|
${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
|
|
10779
11012
|
${maskable ? `if(c<128){
|
|
10780
|
-
const bits=${maskName}[c<0?128:c]
|
|
11013
|
+
const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
10781
11014
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
10782
11015
|
${lazyArms(true)}
|
|
10783
|
-
}else{
|
|
11016
|
+
}${directAsciiMask ? "" : `else{
|
|
10784
11017
|
${lazyArms(false)}
|
|
10785
|
-
}
|
|
11018
|
+
}`}
|
|
10786
11019
|
` : lazyArms(false)}
|
|
10787
11020
|
${finish}
|
|
10788
11021
|
}`;
|
|
@@ -10833,7 +11066,7 @@ if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0
|
|
|
10833
11066
|
${rollbackFor(i)}
|
|
10834
11067
|
}${routeMiss}${sequenceMiss}`;
|
|
10835
11068
|
}).join("\n") : "";
|
|
10836
|
-
const generalArms = arms.map((arm, i) => {
|
|
11069
|
+
const generalArms = directAsciiMask ? "" : arms.map((arm, i) => {
|
|
10837
11070
|
const pretest = pretests[i];
|
|
10838
11071
|
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
10839
11072
|
const scalarCondition = pretest?.scalar === void 0 ? "" : pretest.scalar.length === 1 ? `&&${pretest.scalar[0]}(input,pos)>=0` : `&&(${pretest.scalar.map((recognize) => `${recognize}(input,pos)>=0`).join("||")})`;
|
|
@@ -10863,12 +11096,12 @@ ${rollbackFor(i)}
|
|
|
10863
11096
|
}${miss}`;
|
|
10864
11097
|
}).join("\n");
|
|
10865
11098
|
return `${head}
|
|
10866
|
-
const c
|
|
11099
|
+
const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
10867
11100
|
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
10868
11101
|
let acc
|
|
10869
11102
|
let best=pos
|
|
10870
11103
|
${maskable ? `if(c<128){
|
|
10871
|
-
const bits=${maskName}[c<0?128:c]
|
|
11104
|
+
const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
10872
11105
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
10873
11106
|
${startFailureExact ? "" : "let prev=0"}
|
|
10874
11107
|
${maskArms}
|
|
@@ -10963,14 +11196,18 @@ return [key,v]
|
|
|
10963
11196
|
const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
|
|
10964
11197
|
const collect = op === OP_REP;
|
|
10965
11198
|
let itemCls;
|
|
11199
|
+
let itemAscii = false;
|
|
10966
11200
|
if (!REC2) {
|
|
10967
11201
|
const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
|
|
10968
11202
|
if (itemClassIndex >= 0) {
|
|
10969
|
-
const
|
|
11203
|
+
const resolved = t.cc[itemClassIndex];
|
|
11204
|
+
const ci = classes.push([resolved]) - 1;
|
|
10970
11205
|
classPlan.push([itemClassIndex]);
|
|
10971
11206
|
itemCls = hoist("ri", `CLS[${ci}][0]`);
|
|
11207
|
+
itemAscii = staticBuild && isAsciiOnlyClass(resolved);
|
|
10972
11208
|
}
|
|
10973
11209
|
}
|
|
11210
|
+
const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
|
|
10974
11211
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
10975
11212
|
const p = tmp();
|
|
10976
11213
|
const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
|
|
@@ -11030,7 +11267,7 @@ let count=0
|
|
|
11030
11267
|
for(;;){
|
|
11031
11268
|
${max >= 0 ? `if(count>=${max})break
|
|
11032
11269
|
` : ""}${sep !== void 0 ? `if(count>0&&count>=${min}&&cur>=input.length)break
|
|
11033
|
-
` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}
|
|
11270
|
+
` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}&&${itemMiss("cur")})break
|
|
11034
11271
|
` : ""}let ${p}raw=0,${p}tl=0,${p}lv=0,${p}lg=0,${p}rt=0${sinks.fd ? `,${p}fd=0` : ""}${sinks.er ? `,${p}er=0` : ""}
|
|
11035
11272
|
${markBody}
|
|
11036
11273
|
let itemStart=cur
|
|
@@ -11055,7 +11292,7 @@ itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(inp
|
|
|
11055
11292
|
${rb}
|
|
11056
11293
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
11057
11294
|
}
|
|
11058
|
-
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate
|
|
11295
|
+
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&${itemMiss("itemStart")}){
|
|
11059
11296
|
${rb}
|
|
11060
11297
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
11061
11298
|
}
|
|
@@ -17106,7 +17343,7 @@ function compileRuleMap(ruleMap, opts = {}) {
|
|
|
17106
17343
|
}
|
|
17107
17344
|
|
|
17108
17345
|
// src/version.ts
|
|
17109
|
-
var PARSEMAN_VERSION = "0.50.
|
|
17346
|
+
var PARSEMAN_VERSION = "0.50.3";
|
|
17110
17347
|
|
|
17111
17348
|
// src/compiler/compile-linkable-table.ts
|
|
17112
17349
|
function isLocal(rule) {
|