parseman 0.50.1 → 0.50.4
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 +455 -229
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +445 -194
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/first-set.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 +22 -11
- package/dist/compiler/token-capability.js.map +2 -2
- package/dist/index.js +446 -195
- 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 +491 -309
- 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 +421 -285
- package/dist/spec/index.js.map +3 -3
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/index.js +331 -191
- 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 +5 -3
- package/src/combinators/choice.ts +34 -1
- package/src/combinators/first-set.ts +33 -7
- 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/table/encode.ts +14 -2
- package/src/types.ts +8 -0
- package/src/version.ts +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -43,10 +43,20 @@ function classifyFinalChoice(arms, resolve2) {
|
|
|
43
43
|
}
|
|
44
44
|
return { exclusive, firstSets, nullable: nullable2 };
|
|
45
45
|
}
|
|
46
|
-
function
|
|
46
|
+
function winnerForRef(p, resolve2) {
|
|
47
47
|
if (resolve2 === void 0) return void 0;
|
|
48
48
|
const name = p._ruleName;
|
|
49
|
-
|
|
49
|
+
const w = name === void 0 ? void 0 : resolve2(name);
|
|
50
|
+
if (w === void 0 || w === p) return void 0;
|
|
51
|
+
let cur = w;
|
|
52
|
+
for (const seen = /* @__PURE__ */ new Set(); !seen.has(cur); ) {
|
|
53
|
+
if (cur === p) return void 0;
|
|
54
|
+
seen.add(cur);
|
|
55
|
+
const cd = cur._def;
|
|
56
|
+
if (cd.tag !== "grammar" && cd.tag !== "trivia") return w;
|
|
57
|
+
cur = cd.parser;
|
|
58
|
+
}
|
|
59
|
+
return w;
|
|
50
60
|
}
|
|
51
61
|
function union(a, b) {
|
|
52
62
|
if (a.kind === "any" || b.kind === "any") return { kind: "any" };
|
|
@@ -144,13 +154,15 @@ function matchesEmptyBody(p, seen, resolve2) {
|
|
|
144
154
|
case "grammar":
|
|
145
155
|
case "recover":
|
|
146
156
|
return me(d.parser);
|
|
147
|
-
case "lazy":
|
|
157
|
+
case "lazy": {
|
|
158
|
+
const w = winnerForRef(p, resolve2);
|
|
159
|
+
if (w !== void 0) return me(w);
|
|
148
160
|
try {
|
|
149
161
|
return me(d.thunk());
|
|
150
162
|
} catch {
|
|
151
|
-
|
|
152
|
-
return t2 ? me(t2) : true;
|
|
163
|
+
return true;
|
|
153
164
|
}
|
|
165
|
+
}
|
|
154
166
|
default:
|
|
155
167
|
return true;
|
|
156
168
|
}
|
|
@@ -214,13 +226,15 @@ function firstSetBody(p, seen, resolve2) {
|
|
|
214
226
|
// terminals: no refs, cached set is exact
|
|
215
227
|
case "dispatch":
|
|
216
228
|
return fs(d.selector);
|
|
217
|
-
case "lazy":
|
|
229
|
+
case "lazy": {
|
|
230
|
+
const w = winnerForRef(p, resolve2);
|
|
231
|
+
if (w !== void 0) return fs(w);
|
|
218
232
|
try {
|
|
219
233
|
return fs(d.thunk());
|
|
220
234
|
} catch {
|
|
221
|
-
|
|
222
|
-
return t2 ? fs(t2) : any();
|
|
235
|
+
return any();
|
|
223
236
|
}
|
|
237
|
+
}
|
|
224
238
|
case "choice": {
|
|
225
239
|
let out = empty();
|
|
226
240
|
for (const arm of d.parsers) out = union(out, fs(arm));
|
|
@@ -689,9 +703,43 @@ function hasOwnTriviaBoundary(p, depth = MAX_DEPTH) {
|
|
|
689
703
|
}
|
|
690
704
|
}
|
|
691
705
|
|
|
706
|
+
// src/combinators/scalar.ts
|
|
707
|
+
var SCALAR_TAG = /^(?:literal|regex|keywords|sequence|choice|many|oneOrMore|optional|transform|trivia|grammar|sepBy|lazy)$/;
|
|
708
|
+
function scalarOf(combinator) {
|
|
709
|
+
return combinator._parseScalar;
|
|
710
|
+
}
|
|
711
|
+
function scalarTree(parser2, seen) {
|
|
712
|
+
if (seen.has(parser2)) return true;
|
|
713
|
+
if (parser2._parseScalar === void 0) return false;
|
|
714
|
+
seen.add(parser2);
|
|
715
|
+
const def = parser2._def;
|
|
716
|
+
if (!SCALAR_TAG.test(def.tag)) return false;
|
|
717
|
+
if ("parsers" in def && !def.parsers.every((child) => scalarTree(child, seen))) return false;
|
|
718
|
+
if ("parser" in def && !scalarTree(def.parser, seen)) return false;
|
|
719
|
+
if ("separator" in def && !scalarTree(def.separator, seen)) return false;
|
|
720
|
+
return def.tag !== "lazy" || scalarTree(def.thunk(), seen);
|
|
721
|
+
}
|
|
722
|
+
function scalarRootOf(combinator) {
|
|
723
|
+
const scalar = combinator._parseScalar;
|
|
724
|
+
const def = combinator._def;
|
|
725
|
+
return scalar !== void 0 && def.tag === "grammar" && scalarTree(def.parser, /* @__PURE__ */ new Set()) ? scalar : void 0;
|
|
726
|
+
}
|
|
727
|
+
|
|
692
728
|
// src/combinators/ref.ts
|
|
729
|
+
function withRuleTrivia(trivia2, ctx, run) {
|
|
730
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
731
|
+
ctx.trivia = trivia2;
|
|
732
|
+
ctx.triviaKindLabels = trivia2._meta.triviaKindLabels;
|
|
733
|
+
try {
|
|
734
|
+
return run();
|
|
735
|
+
} finally {
|
|
736
|
+
ctx.trivia = void 0;
|
|
737
|
+
ctx.triviaKindLabels = savedLabels;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
693
740
|
function ref() {
|
|
694
741
|
let resolved = null;
|
|
742
|
+
let resolvedScalar = null;
|
|
695
743
|
let ownBoundary = false;
|
|
696
744
|
const meta = {
|
|
697
745
|
firstSet: any(),
|
|
@@ -708,25 +756,28 @@ function ref() {
|
|
|
708
756
|
return resolved;
|
|
709
757
|
}
|
|
710
758
|
},
|
|
759
|
+
_parseScalar(input, pos, ctx) {
|
|
760
|
+
const scalar = resolvedScalar;
|
|
761
|
+
if (!scalar) throw new Error("ref<T>() used before .define() was called");
|
|
762
|
+
const gt = meta.grammarTrivia;
|
|
763
|
+
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
764
|
+
return withRuleTrivia(gt, ctx, () => scalar(input, pos, ctx));
|
|
765
|
+
}
|
|
766
|
+
return scalar(input, pos, ctx);
|
|
767
|
+
},
|
|
711
768
|
parse(input, pos, ctx) {
|
|
712
|
-
|
|
769
|
+
const parser2 = resolved;
|
|
770
|
+
if (!parser2) throw new Error("ref<T>() used before .define() was called");
|
|
713
771
|
const gt = meta.grammarTrivia;
|
|
714
772
|
if (gt !== void 0 && ownBoundary && ctx.trivia === void 0) {
|
|
715
|
-
|
|
716
|
-
ctx.trivia = gt;
|
|
717
|
-
ctx.triviaKindLabels = gt._meta.triviaKindLabels;
|
|
718
|
-
try {
|
|
719
|
-
return resolved.parse(input, pos, ctx);
|
|
720
|
-
} finally {
|
|
721
|
-
ctx.trivia = void 0;
|
|
722
|
-
ctx.triviaKindLabels = savedLabels;
|
|
723
|
-
}
|
|
773
|
+
return withRuleTrivia(gt, ctx, () => parser2.parse(input, pos, ctx));
|
|
724
774
|
}
|
|
725
|
-
return
|
|
775
|
+
return parser2.parse(input, pos, ctx);
|
|
726
776
|
},
|
|
727
777
|
define(p) {
|
|
728
778
|
if (resolved) throw new Error("ref<T>() already defined");
|
|
729
779
|
resolved = p;
|
|
780
|
+
resolvedScalar = scalarOf(p);
|
|
730
781
|
ownBoundary = hasOwnTriviaBoundary(p);
|
|
731
782
|
meta.firstSet = p._meta.firstSet;
|
|
732
783
|
meta.canMatchNewline = p._meta.canMatchNewline;
|
|
@@ -1112,6 +1163,7 @@ function createParseContext() {
|
|
|
1112
1163
|
_fe: void 0,
|
|
1113
1164
|
_fx: void 0,
|
|
1114
1165
|
_fc: void 0,
|
|
1166
|
+
_sv: void 0,
|
|
1115
1167
|
_probe: void 0,
|
|
1116
1168
|
_cstChildren: void 0,
|
|
1117
1169
|
_cstLeaves: void 0,
|
|
@@ -1949,6 +2001,24 @@ function parser(opts, root) {
|
|
|
1949
2001
|
const captureKinds = clearTrivia ? void 0 : opts.captureTriviaKinds;
|
|
1950
2002
|
const ownCaptureMask = captureKinds === void 0 ? void 0 : scopeLabels !== void 0 ? triviaKindMask(scopeLabels, captureKinds) : void 0;
|
|
1951
2003
|
const inheritCaptureMask = captureKinds !== void 0 && scopeLabels === void 0;
|
|
2004
|
+
const rootScalar = scalarOf(root);
|
|
2005
|
+
const scalarEligible = opts.trackLines !== true && opts.recover !== true && !opaqueRootCapture && !forceCaptureTrivia && captureKinds === void 0;
|
|
2006
|
+
const parseScalar = scalarEligible ? (input, pos, ctx) => {
|
|
2007
|
+
const savedTrivia = ctx.trivia;
|
|
2008
|
+
const savedLabels = ctx.triviaKindLabels;
|
|
2009
|
+
if (clearTrivia) {
|
|
2010
|
+
ctx.trivia = void 0;
|
|
2011
|
+
ctx.triviaKindLabels = void 0;
|
|
2012
|
+
} else if (scopeTrivia !== void 0) {
|
|
2013
|
+
ctx.trivia = scopeTrivia;
|
|
2014
|
+
ctx.triviaKindLabels = scopeLabels;
|
|
2015
|
+
}
|
|
2016
|
+
const end = rootScalar(input, pos, ctx);
|
|
2017
|
+
ctx.trivia = savedTrivia;
|
|
2018
|
+
ctx.triviaKindLabels = savedLabels;
|
|
2019
|
+
return end;
|
|
2020
|
+
} : void 0;
|
|
2021
|
+
let publicScalar;
|
|
1952
2022
|
const grammar = {
|
|
1953
2023
|
_tag: "grammar",
|
|
1954
2024
|
_meta: {
|
|
@@ -1972,7 +2042,20 @@ function parser(opts, root) {
|
|
|
1972
2042
|
constructionTrackLines: trackLinesPolicy,
|
|
1973
2043
|
...captureKinds === void 0 ? {} : { constructionCaptureTriviaKinds: captureKinds }
|
|
1974
2044
|
},
|
|
2045
|
+
_parseScalar: parseScalar,
|
|
1975
2046
|
parse(input, pos, _ctx) {
|
|
2047
|
+
if (pos === void 0 && _ctx === void 0) {
|
|
2048
|
+
publicScalar ??= scalarRootOf(grammar) ?? null;
|
|
2049
|
+
if (publicScalar) {
|
|
2050
|
+
const ctx2 = createParseContext();
|
|
2051
|
+
const end = publicScalar(input, 0, ctx2);
|
|
2052
|
+
if (end < 0) {
|
|
2053
|
+
const at = ~end;
|
|
2054
|
+
return { ok: false, expected: ctx2._fx ?? [], span: { start: at, end: at } };
|
|
2055
|
+
}
|
|
2056
|
+
return { ok: true, value: ctx2._sv, span: { start: 0, end } };
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
1976
2059
|
if (refuseUnclassified) refuseUnclassifiedRootScope(_ctx?._rootTriviaStrictScopes);
|
|
1977
2060
|
const trackLines = trackLinesOf(_ctx);
|
|
1978
2061
|
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
@@ -2007,6 +2090,9 @@ function parse(combinator, input, opts = {}) {
|
|
|
2007
2090
|
_analyzed.add(combinator);
|
|
2008
2091
|
markUnusedValues(combinator);
|
|
2009
2092
|
}
|
|
2093
|
+
if (!opts.trackLines && !opts.recover && combinator._def.tag === "grammar" && combinator._meta.grammarScanSkip === void 0) {
|
|
2094
|
+
return combinator.parse(input);
|
|
2095
|
+
}
|
|
2010
2096
|
const trackLines = opts.trackLines ?? combinator._meta.grammarTrackLines ?? false;
|
|
2011
2097
|
const lineContext = trackLines ? createParseLineContext(input, 0) : void 0;
|
|
2012
2098
|
const lineIndex = lineContext?.lineIndex;
|
|
@@ -2601,10 +2687,32 @@ function regex(pattern, flags = "") {
|
|
|
2601
2687
|
const canMatchNewline = raw.canMatchNewline;
|
|
2602
2688
|
const meta = { firstSet: firstSet2, canMatchNewline, isTrivia: false };
|
|
2603
2689
|
const def = { tag: "regex", source, flags: resolvedFlags };
|
|
2690
|
+
const expected = directTerminalFailureExpected(def);
|
|
2691
|
+
const parseScalar = (input, pos, ctx) => {
|
|
2692
|
+
const scanEnd = scan?.(input, pos);
|
|
2693
|
+
if (scanEnd !== void 0) {
|
|
2694
|
+
if (scanEnd === null) {
|
|
2695
|
+
ctx._fx = expected;
|
|
2696
|
+
return ~pos;
|
|
2697
|
+
}
|
|
2698
|
+
ctx._sv = input.slice(pos, scanEnd);
|
|
2699
|
+
return scanEnd;
|
|
2700
|
+
}
|
|
2701
|
+
anchored.lastIndex = pos;
|
|
2702
|
+
const match = anchored.exec(input);
|
|
2703
|
+
if (match === null) {
|
|
2704
|
+
ctx._fx = expected;
|
|
2705
|
+
return ~pos;
|
|
2706
|
+
}
|
|
2707
|
+
ctx._sv = match[0];
|
|
2708
|
+
return pos + match[0].length;
|
|
2709
|
+
};
|
|
2604
2710
|
return {
|
|
2605
2711
|
_tag: "regex",
|
|
2606
2712
|
_meta: meta,
|
|
2607
2713
|
_def: def,
|
|
2714
|
+
_stickyRegex: anchored,
|
|
2715
|
+
_parseScalar: parseScalar,
|
|
2608
2716
|
parse(input, pos, ctx) {
|
|
2609
2717
|
const scanEnd = scan?.(input, pos);
|
|
2610
2718
|
if (scanEnd !== void 0) {
|
|
@@ -2649,6 +2757,28 @@ function literal(value, opts = {}) {
|
|
|
2649
2757
|
isTrivia: false
|
|
2650
2758
|
};
|
|
2651
2759
|
const canMatchNewline = meta.canMatchNewline;
|
|
2760
|
+
const parseScalar = !caseInsensitive && value.length === 1 ? (() => {
|
|
2761
|
+
const code = value.charCodeAt(0);
|
|
2762
|
+
return (input, pos, ctx) => {
|
|
2763
|
+
if (input.charCodeAt(pos) === code) {
|
|
2764
|
+
ctx._sv = value;
|
|
2765
|
+
return pos + 1;
|
|
2766
|
+
}
|
|
2767
|
+
ctx._fx = expected;
|
|
2768
|
+
return ~pos;
|
|
2769
|
+
};
|
|
2770
|
+
})() : (input, pos, ctx) => {
|
|
2771
|
+
const end = pos + value.length;
|
|
2772
|
+
if (end <= input.length) {
|
|
2773
|
+
const matchedValue = caseInsensitive ? input.slice(pos, end) : value;
|
|
2774
|
+
if (caseInsensitive ? asciiFoldEq(matchedValue, value) : input.startsWith(value, pos)) {
|
|
2775
|
+
ctx._sv = matchedValue;
|
|
2776
|
+
return end;
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
ctx._fx = expected;
|
|
2780
|
+
return ~pos;
|
|
2781
|
+
};
|
|
2652
2782
|
if (caseInsensitive) {
|
|
2653
2783
|
const upper = value.toUpperCase();
|
|
2654
2784
|
const lower = value.toLowerCase();
|
|
@@ -2689,6 +2819,7 @@ function literal(value, opts = {}) {
|
|
|
2689
2819
|
_tag: "literal",
|
|
2690
2820
|
_meta: meta,
|
|
2691
2821
|
_def: { tag: "literal", value, caseInsensitive },
|
|
2822
|
+
_parseScalar: parseScalar,
|
|
2692
2823
|
parse: parse2
|
|
2693
2824
|
};
|
|
2694
2825
|
}
|
|
@@ -2756,16 +2887,26 @@ function keywords(words, opts = {}) {
|
|
|
2756
2887
|
caseInsensitive: opts.caseInsensitive ?? false,
|
|
2757
2888
|
boundary: opts.boundary
|
|
2758
2889
|
};
|
|
2890
|
+
const expected = directTerminalFailureExpected(def);
|
|
2891
|
+
const parseScalar = (input, pos, ctx) => {
|
|
2892
|
+
re.lastIndex = pos;
|
|
2893
|
+
const m = re.exec(input);
|
|
2894
|
+
if (m === null) {
|
|
2895
|
+
ctx._fx = expected;
|
|
2896
|
+
return ~pos;
|
|
2897
|
+
}
|
|
2898
|
+
ctx._sv = m[0];
|
|
2899
|
+
return pos + m[0].length;
|
|
2900
|
+
};
|
|
2759
2901
|
return {
|
|
2760
2902
|
_tag: "keywords",
|
|
2761
2903
|
_meta: meta,
|
|
2762
2904
|
_def: def,
|
|
2905
|
+
_parseScalar: parseScalar,
|
|
2763
2906
|
parse(input, pos, ctx) {
|
|
2764
2907
|
re.lastIndex = pos;
|
|
2765
2908
|
const m = re.exec(input);
|
|
2766
|
-
if (m === null
|
|
2767
|
-
return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
2768
|
-
}
|
|
2909
|
+
if (m === null) return failAt(ctx, directTerminalFailureExpected(def), pos);
|
|
2769
2910
|
const value = m[0];
|
|
2770
2911
|
const span = { start: pos, end: pos + value.length };
|
|
2771
2912
|
if (cstCaptureActive(ctx)) pushCstLeaf(ctx, { _tag: "leaf", value, span });
|
|
@@ -2796,6 +2937,9 @@ var fastScanner3;
|
|
|
2796
2937
|
function needsDeferredTriviaCommit(ctx) {
|
|
2797
2938
|
return ctx._triviaLog !== void 0 || ctx._rootTriviaLog !== void 0 || ctx._cstBuf !== void 0 || ctx._cstTriviaLog !== void 0;
|
|
2798
2939
|
}
|
|
2940
|
+
function needsTriviaRollback(ctx) {
|
|
2941
|
+
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;
|
|
2942
|
+
}
|
|
2799
2943
|
function saveTriviaMark(ctx) {
|
|
2800
2944
|
const m = saveCstMark(ctx);
|
|
2801
2945
|
return {
|
|
@@ -2912,7 +3056,8 @@ function advanceTrivia(input, cur, ctx) {
|
|
|
2912
3056
|
const triviaP = ctx.trivia;
|
|
2913
3057
|
if (!triviaP) return cur;
|
|
2914
3058
|
if (!ctx.trackLines) {
|
|
2915
|
-
const
|
|
3059
|
+
const classified = triviaP._meta.triviaScanner;
|
|
3060
|
+
const fast2 = classified === void 0 ? fastTriviaScanner(triviaP) : classified;
|
|
2916
3061
|
if (fast2) return fast2(input, cur);
|
|
2917
3062
|
if (ctx.triviaKindLabels) return skipWithLabels(input, cur, ctx);
|
|
2918
3063
|
const tr2 = triviaP.parse(input, cur, createDetachedParseContext(ctx.trackLines, ctx.state));
|
|
@@ -3517,6 +3662,7 @@ function sequence(...parsers) {
|
|
|
3517
3662
|
(adjacency ??= Array.from({ length: parsers.length }, () => null))[i] = a;
|
|
3518
3663
|
}
|
|
3519
3664
|
const hasAdjacency = adjacency !== null;
|
|
3665
|
+
const strictArity = !hasAdjacency && (parsers.length === 2 && !matchesEmpty(parsers[1]) || parsers.length === 3 && parsers.every((p) => !matchesEmpty(p))) ? parsers.length : 0;
|
|
3520
3666
|
const meta = {
|
|
3521
3667
|
// Union through the nullable prefix — a leading optional()/many() lets a later
|
|
3522
3668
|
// term's first char start the sequence. Just `parsers[0]` under-approximates.
|
|
@@ -3525,165 +3671,96 @@ function sequence(...parsers) {
|
|
|
3525
3671
|
isTrivia: false
|
|
3526
3672
|
};
|
|
3527
3673
|
const def = { tag: "sequence", parsers };
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
followSentinels ??= parsers.map((_, i) => {
|
|
3531
|
-
const fs = parsers.slice(i + 1).reduce(
|
|
3532
|
-
(acc, p) => union(acc, firstSetOf(p)),
|
|
3533
|
-
{ kind: "empty" }
|
|
3534
|
-
);
|
|
3535
|
-
return firstSetSentinel(fs);
|
|
3536
|
-
});
|
|
3537
|
-
const values = def.valueUnused ? void 0 : [];
|
|
3674
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
3675
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3538
3676
|
let cur = pos;
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
const mTlog = cstTlLen(ctx);
|
|
3551
|
-
const mLog = ctx._triviaLog?.length ?? 0;
|
|
3552
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3553
|
-
let scanEnd;
|
|
3554
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
3555
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
3556
|
-
} else {
|
|
3557
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
3558
|
-
}
|
|
3559
|
-
const scanTlog = cstTlLen(ctx);
|
|
3560
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
3561
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3562
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
3563
|
-
if (!result2.ok) return result2;
|
|
3564
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
3565
|
-
else rollbackScannedTriviaAt(
|
|
3566
|
-
ctx,
|
|
3567
|
-
mTlog,
|
|
3568
|
-
scanTlog,
|
|
3569
|
-
mLog,
|
|
3570
|
-
scanLog,
|
|
3571
|
-
mRootLog,
|
|
3572
|
-
scanRootLog
|
|
3573
|
-
);
|
|
3574
|
-
if (values !== void 0) values.push(result2.value);
|
|
3575
|
-
continue;
|
|
3576
|
-
}
|
|
3577
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
3578
|
-
if (!result.ok) return result;
|
|
3579
|
-
if (values !== void 0) values.push(result.value);
|
|
3580
|
-
cur = result.span.end;
|
|
3677
|
+
if (strictArity !== 0) {
|
|
3678
|
+
cur = scalarParsers[0](input, cur, ctx);
|
|
3679
|
+
if (cur < 0) return cur;
|
|
3680
|
+
const first = ctx._sv;
|
|
3681
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
3682
|
+
cur = scalarParsers[1](input, cur, ctx);
|
|
3683
|
+
if (cur < 0) return cur;
|
|
3684
|
+
const second = ctx._sv;
|
|
3685
|
+
if (strictArity === 2) {
|
|
3686
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second];
|
|
3687
|
+
return cur;
|
|
3581
3688
|
}
|
|
3582
|
-
|
|
3583
|
-
|
|
3689
|
+
if (ctx.trivia) cur = advanceTrivia(input, cur, ctx);
|
|
3690
|
+
cur = scalarParsers[2](input, cur, ctx);
|
|
3691
|
+
if (cur < 0) return cur;
|
|
3692
|
+
ctx._sv = def.valueUnused ? void 0 : [first, second, ctx._sv];
|
|
3693
|
+
return cur;
|
|
3584
3694
|
}
|
|
3585
|
-
return {
|
|
3586
|
-
ok: true,
|
|
3587
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
3588
|
-
value: values ?? void 0,
|
|
3589
|
-
span: { start: pos, end: cur }
|
|
3590
|
-
};
|
|
3591
|
-
}
|
|
3592
|
-
function parseAdjacent(input, pos, ctx) {
|
|
3593
3695
|
const values = def.valueUnused ? void 0 : [];
|
|
3594
|
-
let
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
const mRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3607
|
-
if (needsDeferredTriviaCommit(ctx)) {
|
|
3608
|
-
scanEnd = commitTriviaScan(scanTriviaCompact(input, cur, ctx));
|
|
3609
|
-
} else {
|
|
3610
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
3611
|
-
}
|
|
3612
|
-
const scanTlog = cstTlLen(ctx);
|
|
3613
|
-
const scanLog = ctx._triviaLog?.length ?? 0;
|
|
3614
|
-
const scanRootLog = ctx._rootTriviaLog?.length ?? 0;
|
|
3615
|
-
const result2 = parsers[i].parse(input, scanEnd, ctx);
|
|
3616
|
-
if (!result2.ok) return result2;
|
|
3617
|
-
if (result2.span.end > scanEnd) cur = result2.span.end;
|
|
3618
|
-
else rollbackScannedTriviaAt(
|
|
3619
|
-
ctx,
|
|
3620
|
-
mTlog,
|
|
3621
|
-
scanTlog,
|
|
3622
|
-
mLog,
|
|
3623
|
-
scanLog,
|
|
3624
|
-
mRootLog,
|
|
3625
|
-
scanRootLog
|
|
3626
|
-
);
|
|
3627
|
-
if (values !== void 0) values.push(result2.value);
|
|
3628
|
-
continue;
|
|
3629
|
-
}
|
|
3630
|
-
const result = parsers[i].parse(input, cur, ctx);
|
|
3631
|
-
if (!result.ok) return result;
|
|
3632
|
-
if (values !== void 0) values.push(result.value);
|
|
3633
|
-
cur = result.span.end;
|
|
3634
|
-
}
|
|
3635
|
-
return {
|
|
3636
|
-
ok: true,
|
|
3637
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
3638
|
-
value: values ?? void 0,
|
|
3639
|
-
span: { start: pos, end: cur }
|
|
3640
|
-
};
|
|
3641
|
-
}
|
|
3696
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
3697
|
+
let termPos = cur;
|
|
3698
|
+
if (i > 0 && ctx.trivia) termPos = advanceTrivia(input, cur, ctx);
|
|
3699
|
+
const end = scalarParsers[i](input, termPos, ctx);
|
|
3700
|
+
if (end < 0) return end;
|
|
3701
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
3702
|
+
if (end > termPos || termPos === cur) cur = end;
|
|
3703
|
+
}
|
|
3704
|
+
ctx._sv = values;
|
|
3705
|
+
return cur;
|
|
3706
|
+
};
|
|
3707
|
+
let followSentinels;
|
|
3642
3708
|
return {
|
|
3643
3709
|
_tag: "sequence",
|
|
3644
3710
|
_meta: meta,
|
|
3645
3711
|
_def: def,
|
|
3712
|
+
_parseScalar: hasAdjacency ? void 0 : parseScalar,
|
|
3646
3713
|
parse(input, pos, ctx) {
|
|
3647
|
-
|
|
3648
|
-
if (
|
|
3714
|
+
const tolerant = ctx._tolerant === true;
|
|
3715
|
+
if (tolerant) {
|
|
3716
|
+
followSentinels ??= parsers.map((_, i) => firstSetSentinel(
|
|
3717
|
+
parsers.slice(i + 1).reduce(
|
|
3718
|
+
(set, parser2) => union(set, firstSetOf(parser2)),
|
|
3719
|
+
{ kind: "empty" }
|
|
3720
|
+
)
|
|
3721
|
+
));
|
|
3722
|
+
}
|
|
3723
|
+
const inheritedSync = ctx._sync;
|
|
3724
|
+
const deferredTrivia = needsDeferredTriviaCommit(ctx);
|
|
3649
3725
|
const values = def.valueUnused ? void 0 : [];
|
|
3650
3726
|
let cur = pos;
|
|
3651
|
-
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
const
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
} else {
|
|
3660
|
-
scanEnd = advanceTrivia(input, cur, ctx);
|
|
3727
|
+
try {
|
|
3728
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
3729
|
+
if (tolerant) ctx._sync = followSentinels[i] ?? inheritedSync;
|
|
3730
|
+
const assertion = adjacency?.[i];
|
|
3731
|
+
if (assertion) {
|
|
3732
|
+
if (!holdsAdjacency(input, cur, ctx, assertion)) return adjacencyFail(cur, assertion);
|
|
3733
|
+
if (values !== void 0) values.push(null);
|
|
3734
|
+
continue;
|
|
3661
3735
|
}
|
|
3662
|
-
|
|
3663
|
-
const
|
|
3664
|
-
const
|
|
3665
|
-
const
|
|
3666
|
-
if (
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3736
|
+
let termPos = cur;
|
|
3737
|
+
const markTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
3738
|
+
const markLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
3739
|
+
const markRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
3740
|
+
if (ctx.trivia && i > 0) {
|
|
3741
|
+
termPos = deferredTrivia ? commitTriviaScan(scanTriviaCompact(input, cur, ctx)) : advanceTrivia(input, cur, ctx);
|
|
3742
|
+
}
|
|
3743
|
+
const scanTlog = deferredTrivia ? cstTlLen(ctx) : 0;
|
|
3744
|
+
const scanLog = deferredTrivia ? ctx._triviaLog?.length ?? 0 : 0;
|
|
3745
|
+
const scanRootLog = deferredTrivia ? ctx._rootTriviaLog?.length ?? 0 : 0;
|
|
3746
|
+
const result = parsers[i].parse(input, termPos, ctx);
|
|
3747
|
+
if (!result.ok) return result;
|
|
3748
|
+
if (values !== void 0) values.push(result.value);
|
|
3749
|
+
if (result.span.end > termPos || termPos === cur) cur = result.span.end;
|
|
3750
|
+
else if (deferredTrivia) {
|
|
3670
3751
|
rollbackScannedTriviaAt(
|
|
3671
3752
|
ctx,
|
|
3672
|
-
|
|
3753
|
+
markTlog,
|
|
3673
3754
|
scanTlog,
|
|
3674
|
-
|
|
3755
|
+
markLog,
|
|
3675
3756
|
scanLog,
|
|
3676
|
-
|
|
3757
|
+
markRootLog,
|
|
3677
3758
|
scanRootLog
|
|
3678
3759
|
);
|
|
3679
3760
|
}
|
|
3680
|
-
if (values !== void 0) values.push(result2.value);
|
|
3681
|
-
continue;
|
|
3682
3761
|
}
|
|
3683
|
-
|
|
3684
|
-
if (
|
|
3685
|
-
if (values !== void 0) values.push(result.value);
|
|
3686
|
-
cur = result.span.end;
|
|
3762
|
+
} finally {
|
|
3763
|
+
if (tolerant) ctx._sync = inheritedSync;
|
|
3687
3764
|
}
|
|
3688
3765
|
return {
|
|
3689
3766
|
ok: true,
|
|
@@ -3815,7 +3892,8 @@ function choice(...args) {
|
|
|
3815
3892
|
disjoint
|
|
3816
3893
|
};
|
|
3817
3894
|
const strategy = disjoint || hasGates ? null : detectStrategy(parsers);
|
|
3818
|
-
const
|
|
3895
|
+
const ordered = strategy?.tag === "firstMatch" || strategy?.tag === "sharedPrefix";
|
|
3896
|
+
const autoNot = !disjoint && !hasGates && ordered ? computeAutoNot(parsers) : parsers.map(() => null);
|
|
3819
3897
|
let greedyLitMap = null;
|
|
3820
3898
|
let sortedParsers = null;
|
|
3821
3899
|
const asciiDispatch = disjoint ? buildAsciiDispatch(parsers) : null;
|
|
@@ -3829,6 +3907,37 @@ function choice(...args) {
|
|
|
3829
3907
|
} else if (strategy?.tag === "literalsLongestFirst") {
|
|
3830
3908
|
sortedParsers = strategy.sortedIndices.map((i) => parsers[i]);
|
|
3831
3909
|
}
|
|
3910
|
+
const scalarParsers = parsers.map(scalarOf);
|
|
3911
|
+
const scalarEligible = !hasGates && parsers.every((p) => p._parseScalar !== void 0) && (disjoint || ordered);
|
|
3912
|
+
const scalarExpected = parsers.flatMap(deriveExpected);
|
|
3913
|
+
const parseScalar = (input, pos, ctx) => {
|
|
3914
|
+
if (disjoint) {
|
|
3915
|
+
const code = pos < input.length ? input.codePointAt(pos) : -1;
|
|
3916
|
+
let idx = code >= 0 && code < 128 ? asciiDispatch[code] : -1;
|
|
3917
|
+
if (idx < 0 && code >= 0) {
|
|
3918
|
+
for (let i = 0; i < parsers.length; i++) {
|
|
3919
|
+
if (inFirstSet(code, parsers[i]._meta.firstSet)) {
|
|
3920
|
+
idx = i;
|
|
3921
|
+
break;
|
|
3922
|
+
}
|
|
3923
|
+
}
|
|
3924
|
+
}
|
|
3925
|
+
if (idx >= 0) {
|
|
3926
|
+
const gate = gates[idx];
|
|
3927
|
+
if (!gate || gate(ctx.state)) return scalarParsers[idx](input, pos, ctx);
|
|
3928
|
+
ctx._fx = deriveExpected(parsers[idx]);
|
|
3929
|
+
return ~pos;
|
|
3930
|
+
}
|
|
3931
|
+
} else {
|
|
3932
|
+
for (let i = 0; i < scalarParsers.length; i++) {
|
|
3933
|
+
if (gates[i] && !gates[i](ctx.state)) continue;
|
|
3934
|
+
const end = scalarParsers[i](input, pos, ctx);
|
|
3935
|
+
if (end >= 0 && (!autoNot[i] || !autoNotFires(input, end, autoNot[i]))) return end;
|
|
3936
|
+
}
|
|
3937
|
+
}
|
|
3938
|
+
ctx._fx = scalarExpected;
|
|
3939
|
+
return ~pos;
|
|
3940
|
+
};
|
|
3832
3941
|
return {
|
|
3833
3942
|
_tag: "choice",
|
|
3834
3943
|
_meta: meta,
|
|
@@ -3840,6 +3949,7 @@ function choice(...args) {
|
|
|
3840
3949
|
strategy: strategy ?? { tag: "firstMatch" },
|
|
3841
3950
|
autoNot
|
|
3842
3951
|
},
|
|
3952
|
+
_parseScalar: scalarEligible ? parseScalar : void 0,
|
|
3843
3953
|
parse(input, pos, ctx) {
|
|
3844
3954
|
const expected = [];
|
|
3845
3955
|
let expectedAt = pos;
|
|
@@ -4371,8 +4481,8 @@ function attempt(parser2) {
|
|
|
4371
4481
|
}
|
|
4372
4482
|
|
|
4373
4483
|
// src/combinators/repeat.ts
|
|
4374
|
-
function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
4375
|
-
const mark = saveTriviaMark(ctx);
|
|
4484
|
+
function repItem(combinator, input, cur, ctx, guardable, mandatory, rollbackNeeded) {
|
|
4485
|
+
const mark = rollbackNeeded ? saveTriviaMark(ctx) : void 0;
|
|
4376
4486
|
let pos = cur;
|
|
4377
4487
|
if (ctx.trivia) {
|
|
4378
4488
|
if (needsDeferredTriviaCommit(ctx)) {
|
|
@@ -4382,24 +4492,24 @@ function repItem(combinator, input, cur, ctx, guardable, mandatory) {
|
|
|
4382
4492
|
}
|
|
4383
4493
|
}
|
|
4384
4494
|
if (pos >= input.length && !mandatory) {
|
|
4385
|
-
rollbackTrivia(ctx, mark);
|
|
4495
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4386
4496
|
return "stop";
|
|
4387
4497
|
}
|
|
4388
4498
|
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(combinator, input, pos)) {
|
|
4389
|
-
rollbackTrivia(ctx, mark);
|
|
4499
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4390
4500
|
return "stop";
|
|
4391
4501
|
}
|
|
4392
4502
|
const result = combinator.parse(input, pos, ctx);
|
|
4393
4503
|
if (!result.ok) {
|
|
4394
|
-
rollbackTrivia(ctx, mark);
|
|
4504
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4395
4505
|
if (result.committed) return { fail: result, failPos: pos };
|
|
4396
4506
|
return { fail: result, failPos: pos };
|
|
4397
4507
|
}
|
|
4398
4508
|
if (result.span.end === pos && !mandatory) {
|
|
4399
|
-
rollbackTrivia(ctx, mark);
|
|
4509
|
+
if (mark !== void 0) rollbackTrivia(ctx, mark);
|
|
4400
4510
|
return "stop";
|
|
4401
4511
|
}
|
|
4402
|
-
return
|
|
4512
|
+
return result;
|
|
4403
4513
|
}
|
|
4404
4514
|
function resolveBounds(what, opts) {
|
|
4405
4515
|
const min = opts.min ?? 0;
|
|
@@ -4412,6 +4522,21 @@ function resolveBounds(what, opts) {
|
|
|
4412
4522
|
if (max < min) bad(`max (${max}) is less than min (${min}) \u2014 the combinator could never succeed`);
|
|
4413
4523
|
return { min, max };
|
|
4414
4524
|
}
|
|
4525
|
+
function repeatScalarTail(combinator, child, input, cur, ctx, guardable, values, remaining) {
|
|
4526
|
+
while (cur < input.length && remaining > 0) {
|
|
4527
|
+
let itemPos = cur;
|
|
4528
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4529
|
+
if (itemPos >= input.length) break;
|
|
4530
|
+
if (guardable && !startsFirstSet(combinator, input, itemPos)) break;
|
|
4531
|
+
const end = child(input, itemPos, ctx);
|
|
4532
|
+
if (end <= itemPos) break;
|
|
4533
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4534
|
+
cur = end;
|
|
4535
|
+
remaining--;
|
|
4536
|
+
}
|
|
4537
|
+
ctx._sv = values;
|
|
4538
|
+
return cur;
|
|
4539
|
+
}
|
|
4415
4540
|
function many(combinator, opts = {}) {
|
|
4416
4541
|
const { min, max } = resolveBounds("many()", opts);
|
|
4417
4542
|
if (min >= 1) return atLeast(combinator, min, max);
|
|
@@ -4423,17 +4548,21 @@ function many(combinator, opts = {}) {
|
|
|
4423
4548
|
const def = { tag: "many", parser: combinator, min: 0, ...max === Infinity ? {} : { max } };
|
|
4424
4549
|
let expected;
|
|
4425
4550
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4551
|
+
const scalarChild = scalarOf(combinator);
|
|
4552
|
+
const parseScalar = (input, pos, ctx) => repeatScalarTail(combinator, scalarChild, input, pos, ctx, guardable, def.valueUnused ? void 0 : [], max);
|
|
4426
4553
|
return {
|
|
4427
4554
|
_tag: "many",
|
|
4428
4555
|
_meta: meta,
|
|
4429
4556
|
_def: def,
|
|
4557
|
+
_parseScalar: parseScalar,
|
|
4430
4558
|
parse(input, pos, ctx) {
|
|
4431
4559
|
const values = def.valueUnused ? void 0 : [];
|
|
4560
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4432
4561
|
let cur = pos;
|
|
4433
4562
|
let count = 0;
|
|
4434
4563
|
while (cur < input.length) {
|
|
4435
4564
|
if (count >= max) break;
|
|
4436
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
4565
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4437
4566
|
if (item === "stop") break;
|
|
4438
4567
|
if ("fail" in item) {
|
|
4439
4568
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -4450,7 +4579,7 @@ function many(combinator, opts = {}) {
|
|
|
4450
4579
|
}
|
|
4451
4580
|
if (values !== void 0) values.push(item.value);
|
|
4452
4581
|
count++;
|
|
4453
|
-
cur = item.end;
|
|
4582
|
+
cur = item.span.end;
|
|
4454
4583
|
}
|
|
4455
4584
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4456
4585
|
}
|
|
@@ -4468,30 +4597,47 @@ function atLeast(combinator, min, max) {
|
|
|
4468
4597
|
const def = { tag: "oneOrMore", parser: combinator, min, ...max === Infinity ? {} : { max } };
|
|
4469
4598
|
let expected;
|
|
4470
4599
|
const guardable = combinator._meta.firstSet.kind !== "any" && !matchesEmpty(combinator);
|
|
4600
|
+
const scalarChild = scalarOf(combinator);
|
|
4601
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4602
|
+
let cur = scalarChild(input, pos, ctx);
|
|
4603
|
+
if (cur < 0) return cur;
|
|
4604
|
+
const values = def.valueUnused ? void 0 : [ctx._sv];
|
|
4605
|
+
for (let count = 1; count < min; count++) {
|
|
4606
|
+
let itemPos = cur;
|
|
4607
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, cur, ctx);
|
|
4608
|
+
const end = scalarChild(input, itemPos, ctx);
|
|
4609
|
+
if (end < 0) return ~cur;
|
|
4610
|
+
cur = end;
|
|
4611
|
+
if (values !== void 0) values.push(ctx._sv);
|
|
4612
|
+
}
|
|
4613
|
+
return repeatScalarTail(combinator, scalarChild, input, cur, ctx, guardable, values, max - min);
|
|
4614
|
+
};
|
|
4471
4615
|
return {
|
|
4472
4616
|
_tag: "oneOrMore",
|
|
4473
4617
|
_meta: meta,
|
|
4474
4618
|
_def: def,
|
|
4619
|
+
_parseScalar: parseScalar,
|
|
4475
4620
|
parse(input, pos, ctx) {
|
|
4476
4621
|
const first = combinator.parse(input, pos, ctx);
|
|
4477
4622
|
if (!first.ok) return first;
|
|
4478
4623
|
const values = def.valueUnused ? void 0 : [first.value];
|
|
4624
|
+
const rollbackNeeded = needsTriviaRollback(ctx);
|
|
4479
4625
|
let cur = first.span.end;
|
|
4480
4626
|
let count = 1;
|
|
4481
4627
|
while (count < min) {
|
|
4482
|
-
const item = repItem(combinator, input, cur, ctx, guardable, true);
|
|
4628
|
+
const item = repItem(combinator, input, cur, ctx, guardable, true, rollbackNeeded);
|
|
4483
4629
|
if (item === "stop" || "fail" in item) {
|
|
4484
4630
|
if (item !== "stop" && !item.fail.ok && item.fail.committed) return item.fail;
|
|
4485
4631
|
expected ??= deriveExpected(combinator);
|
|
4486
4632
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: cur, end: cur } };
|
|
4487
4633
|
}
|
|
4488
4634
|
if (values !== void 0) values.push(item.value);
|
|
4489
|
-
cur = item.end;
|
|
4635
|
+
cur = item.span.end;
|
|
4490
4636
|
count++;
|
|
4491
4637
|
}
|
|
4492
4638
|
while (cur < input.length) {
|
|
4493
4639
|
if (count >= max) break;
|
|
4494
|
-
const item = repItem(combinator, input, cur, ctx, guardable, false);
|
|
4640
|
+
const item = repItem(combinator, input, cur, ctx, guardable, false, rollbackNeeded);
|
|
4495
4641
|
if (item === "stop") break;
|
|
4496
4642
|
if ("fail" in item) {
|
|
4497
4643
|
if (!item.fail.ok && item.fail.committed) return item.fail;
|
|
@@ -4508,7 +4654,7 @@ function atLeast(combinator, min, max) {
|
|
|
4508
4654
|
}
|
|
4509
4655
|
if (values !== void 0) values.push(item.value);
|
|
4510
4656
|
count++;
|
|
4511
|
-
cur = item.end;
|
|
4657
|
+
cur = item.span.end;
|
|
4512
4658
|
}
|
|
4513
4659
|
return { ok: true, value: values ?? void 0, span: { start: pos, end: cur } };
|
|
4514
4660
|
}
|
|
@@ -4521,10 +4667,22 @@ function optional(combinator) {
|
|
|
4521
4667
|
isTrivia: false
|
|
4522
4668
|
};
|
|
4523
4669
|
const firstSetSkippable = !matchesEmpty(combinator);
|
|
4670
|
+
const scalarChild = scalarOf(combinator);
|
|
4671
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4672
|
+
if (firstSetSkippable && !startsFirstSet(combinator, input, pos)) {
|
|
4673
|
+
ctx._sv = null;
|
|
4674
|
+
return pos;
|
|
4675
|
+
}
|
|
4676
|
+
const end = scalarChild(input, pos, ctx);
|
|
4677
|
+
if (end >= 0) return end;
|
|
4678
|
+
ctx._sv = null;
|
|
4679
|
+
return pos;
|
|
4680
|
+
};
|
|
4524
4681
|
return {
|
|
4525
4682
|
_tag: "optional",
|
|
4526
4683
|
_meta: meta,
|
|
4527
4684
|
_def: { tag: "optional", parser: combinator },
|
|
4685
|
+
_parseScalar: parseScalar,
|
|
4528
4686
|
parse(input, pos, ctx) {
|
|
4529
4687
|
if (firstSetSkippable && ctx._probe === void 0 && !startsFirstSet(combinator, input, pos)) {
|
|
4530
4688
|
return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
@@ -4558,6 +4716,43 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4558
4716
|
expected ??= deriveExpected(combinator);
|
|
4559
4717
|
return { ok: false, expected: expected.length > 0 ? expected : [combinator._tag], span: { start: at, end: at } };
|
|
4560
4718
|
};
|
|
4719
|
+
const scalarExpected = deriveExpected(combinator);
|
|
4720
|
+
const scalarChild = scalarOf(combinator);
|
|
4721
|
+
const scalarSeparator = scalarOf(separator);
|
|
4722
|
+
const parseScalar = (input, pos, ctx) => {
|
|
4723
|
+
let cur = scalarChild(input, pos, ctx);
|
|
4724
|
+
if (cur < 0) {
|
|
4725
|
+
if (min >= 1) {
|
|
4726
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
4727
|
+
return ~pos;
|
|
4728
|
+
}
|
|
4729
|
+
ctx._sv = [];
|
|
4730
|
+
return pos;
|
|
4731
|
+
}
|
|
4732
|
+
const values = [ctx._sv];
|
|
4733
|
+
while (values.length < max && (cur < input.length || values.length < min)) {
|
|
4734
|
+
const beforeSeparator = cur;
|
|
4735
|
+
let separatorPos = cur;
|
|
4736
|
+
if (ctx.trivia) separatorPos = advanceTrivia(input, cur, ctx);
|
|
4737
|
+
const separatorEnd = scalarSeparator(input, separatorPos, ctx);
|
|
4738
|
+
if (separatorEnd < 0) break;
|
|
4739
|
+
let itemPos = separatorEnd;
|
|
4740
|
+
if (ctx.trivia) itemPos = advanceTrivia(input, itemPos, ctx);
|
|
4741
|
+
const itemEnd = scalarChild(input, itemPos, ctx);
|
|
4742
|
+
if (itemEnd < 0) {
|
|
4743
|
+
cur = trailing === "allow" ? separatorEnd : beforeSeparator;
|
|
4744
|
+
break;
|
|
4745
|
+
}
|
|
4746
|
+
values.push(ctx._sv);
|
|
4747
|
+
cur = itemEnd;
|
|
4748
|
+
}
|
|
4749
|
+
if (values.length < min) {
|
|
4750
|
+
ctx._fx = scalarExpected.length > 0 ? scalarExpected : [combinator._tag];
|
|
4751
|
+
return ~cur;
|
|
4752
|
+
}
|
|
4753
|
+
ctx._sv = values;
|
|
4754
|
+
return cur;
|
|
4755
|
+
};
|
|
4561
4756
|
return {
|
|
4562
4757
|
_tag: "sepBy",
|
|
4563
4758
|
_meta: meta,
|
|
@@ -4573,6 +4768,7 @@ function sepBy(combinator, separatorArg, opts = {}) {
|
|
|
4573
4768
|
// this option surface already; parity is held by test/parity, not by hope.
|
|
4574
4769
|
...keepSeparators ? { keepSeparators: true } : {}
|
|
4575
4770
|
},
|
|
4771
|
+
_parseScalar: keepSeparators ? void 0 : parseScalar,
|
|
4576
4772
|
parse(input, pos, ctx) {
|
|
4577
4773
|
const first = combinator.parse(input, pos, ctx);
|
|
4578
4774
|
const values = [];
|
|
@@ -5155,11 +5351,54 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
5155
5351
|
}
|
|
5156
5352
|
|
|
5157
5353
|
// src/combinators/map.ts
|
|
5354
|
+
var JSON_STRING_BODY = String.raw`(?:[^"\\]|\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4}))*`;
|
|
5158
5355
|
function transform(combinator, fn) {
|
|
5356
|
+
const observesSpan = fn.length > 1;
|
|
5357
|
+
const sequenceDef = combinator._def.tag === "sequence" ? combinator._def : void 0;
|
|
5358
|
+
const terms = sequenceDef?.parsers;
|
|
5359
|
+
const inner = terms?.[1];
|
|
5360
|
+
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;
|
|
5361
|
+
const child = scalarOf(combinator);
|
|
5362
|
+
const parseScalar = fused ? (() => {
|
|
5363
|
+
const body = inner._stickyRegex;
|
|
5364
|
+
const tuple = ['"', "", '"'];
|
|
5365
|
+
const expected = [JSON.stringify('"')];
|
|
5366
|
+
return (input, pos, ctx) => {
|
|
5367
|
+
if (ctx.trivia !== void 0) {
|
|
5368
|
+
const end2 = child(input, pos, ctx);
|
|
5369
|
+
if (end2 < 0) return end2;
|
|
5370
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end: end2 }) : fn(ctx._sv);
|
|
5371
|
+
return end2;
|
|
5372
|
+
}
|
|
5373
|
+
if (input.charCodeAt(pos) !== 34) {
|
|
5374
|
+
ctx._fx = expected;
|
|
5375
|
+
return ~pos;
|
|
5376
|
+
}
|
|
5377
|
+
body.lastIndex = pos + 1;
|
|
5378
|
+
const match = body.exec(input);
|
|
5379
|
+
const close = pos + 1 + match[0].length;
|
|
5380
|
+
if (input.charCodeAt(close) !== 34) {
|
|
5381
|
+
ctx._fx = expected;
|
|
5382
|
+
return ~close;
|
|
5383
|
+
}
|
|
5384
|
+
tuple[1] = match[0];
|
|
5385
|
+
const end = close + 1;
|
|
5386
|
+
ctx._sv = observesSpan ? fn(tuple, { start: pos, end }) : fn(tuple);
|
|
5387
|
+
return end;
|
|
5388
|
+
};
|
|
5389
|
+
})() : /* @__PURE__ */ (() => {
|
|
5390
|
+
return (input, pos, ctx) => {
|
|
5391
|
+
const end = child(input, pos, ctx);
|
|
5392
|
+
if (end < 0) return end;
|
|
5393
|
+
ctx._sv = observesSpan ? fn(ctx._sv, { start: pos, end }) : fn(ctx._sv);
|
|
5394
|
+
return end;
|
|
5395
|
+
};
|
|
5396
|
+
})();
|
|
5159
5397
|
return {
|
|
5160
5398
|
_tag: "transform",
|
|
5161
5399
|
_meta: combinator._meta,
|
|
5162
5400
|
_def: { tag: "transform", parser: combinator, fn },
|
|
5401
|
+
_parseScalar: parseScalar,
|
|
5163
5402
|
parse(input, pos, ctx) {
|
|
5164
5403
|
const result = combinator.parse(input, pos, ctx);
|
|
5165
5404
|
if (!result.ok) return result;
|
|
@@ -5174,9 +5413,11 @@ function trivia(combinator) {
|
|
|
5174
5413
|
_meta: {
|
|
5175
5414
|
...combinator._meta,
|
|
5176
5415
|
isTrivia: true,
|
|
5416
|
+
triviaScanner: fastTriviaScanner(combinator),
|
|
5177
5417
|
...kindLabels ? { triviaKindLabels: kindLabels } : {}
|
|
5178
5418
|
},
|
|
5179
5419
|
_def: { tag: "trivia", parser: combinator },
|
|
5420
|
+
_parseScalar: scalarOf(combinator),
|
|
5180
5421
|
parse: combinator.parse.bind(combinator)
|
|
5181
5422
|
};
|
|
5182
5423
|
}
|
|
@@ -7979,7 +8220,7 @@ var Encoder = class {
|
|
|
7979
8220
|
d.tags === void 0 ? -1 : this.constant(d.tags)
|
|
7980
8221
|
);
|
|
7981
8222
|
if (matchesEmpty(d.parser)) return body;
|
|
7982
|
-
const fs = d.parser._meta.firstSet;
|
|
8223
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
7983
8224
|
if (fs.kind === "any") return body;
|
|
7984
8225
|
const cls = this.charClass(fs);
|
|
7985
8226
|
if (cls < 0) return body;
|
|
@@ -8093,7 +8334,7 @@ var Encoder = class {
|
|
|
8093
8334
|
case "attempt": {
|
|
8094
8335
|
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
|
|
8095
8336
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
8096
|
-
const fs = d.parser._meta.firstSet;
|
|
8337
|
+
const fs = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver()) : d.parser._meta.firstSet;
|
|
8097
8338
|
if (fs.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
8098
8339
|
const cls = this.charClass(fs);
|
|
8099
8340
|
if (cls < 0) return inner;
|
|
@@ -9909,6 +10150,9 @@ if(ctx._rootTriviaLog!==undefined&&ctx._rootTriviaLog.length!==rt)ctx._rootTrivi
|
|
|
9909
10150
|
function q(s) {
|
|
9910
10151
|
return JSON.stringify(s);
|
|
9911
10152
|
}
|
|
10153
|
+
function isAsciiOnlyClass(cls) {
|
|
10154
|
+
return cls !== null && cls !== void 0 && cls.hi.length === 0;
|
|
10155
|
+
}
|
|
9912
10156
|
var NO_SINKS = { fd: false, er: false };
|
|
9913
10157
|
function sinkSlots(t2, s) {
|
|
9914
10158
|
return `${s.fd ? `,${t2}fd=0` : ""}${s.er ? `,${t2}er=0` : ""}`;
|
|
@@ -10455,12 +10699,13 @@ ${cfg.probe ? `failAt(ctx,${xf},pos)
|
|
|
10455
10699
|
return `${head}EC.e=pos;return ''}`;
|
|
10456
10700
|
case OP_GATE: {
|
|
10457
10701
|
const child = link(code[ip + 2]);
|
|
10458
|
-
const
|
|
10702
|
+
const resolved = t2.cc[code[ip + 1]];
|
|
10703
|
+
const ci = classes.push([resolved]) - 1;
|
|
10459
10704
|
classPlan.push([code[ip + 1]]);
|
|
10460
10705
|
const cls = hoist("cl", `CLS[${ci}][0]`);
|
|
10461
10706
|
const xf = fxRef(code[ip + 3]);
|
|
10462
10707
|
return `${head}
|
|
10463
|
-
if(
|
|
10708
|
+
if(${staticBuild && isAsciiOnlyClass(resolved) ? `${cls}.ascii[input.charCodeAt(pos)]!==1` : `!classHas(${cls},lead(input,pos))`}){ctx._fe=pos;ctx._fx=${xf};return FAIL}
|
|
10464
10709
|
return ${child}(input,pos,ctx)
|
|
10465
10710
|
}`;
|
|
10466
10711
|
}
|
|
@@ -10803,10 +11048,11 @@ return v
|
|
|
10803
11048
|
const asc = hoist("as", `DISP[${di}].ascii`);
|
|
10804
11049
|
const hiArr = table.hi;
|
|
10805
11050
|
const armSwitch = arms.map((a, i) => `case ${i}:v=${a}(input,pos,ctx);break`).join("\n");
|
|
11051
|
+
const directAscii = staticBuild && table.hi.length === 0;
|
|
10806
11052
|
return `${head}
|
|
10807
|
-
const c
|
|
11053
|
+
const c=${directAscii ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
10808
11054
|
let arm=-1
|
|
10809
|
-
if(c>=0&&c<128){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
11055
|
+
if(${directAscii ? "c<128" : "c>=0&&c<128"}){const a=${asc}[c];if(a!==0)arm=a-1}
|
|
10810
11056
|
${hiArr.length === 0 ? "" : `else if(c>=128){const h=${hoist("hi", `DISP[${di}].hi`)}
|
|
10811
11057
|
for(let i=0;i<h.length;i+=3){if(c>=h[i]&&c<=h[i+1]){arm=h[i+2];break}}}`}
|
|
10812
11058
|
if(arm>=0){
|
|
@@ -10828,7 +11074,9 @@ return FAIL
|
|
|
10828
11074
|
const di = code[ip + 1];
|
|
10829
11075
|
const expected = Array.from({ length: n }, (_, i) => fxRef(code[base + n + i]));
|
|
10830
11076
|
const gates = Array.from({ length: n }, (_, i) => table.armCls[i] ?? null);
|
|
10831
|
-
const
|
|
11077
|
+
const maskable = n <= 32;
|
|
11078
|
+
const directAsciiMask = staticBuild && maskable && gates.every(isAsciiOnlyClass);
|
|
11079
|
+
const gateRefs = directAsciiMask ? [] : Array.from({ length: n }, (_, i) => hoist("g", `DISP[${di}].armCls[${i}]`));
|
|
10832
11080
|
const tokenCandidate = tokenChoiceCandidates.get(ip);
|
|
10833
11081
|
const pretests = Array.from({ length: n }, (_, i) => {
|
|
10834
11082
|
if (tokenCandidate?.arm === i) {
|
|
@@ -10848,7 +11096,6 @@ return FAIL
|
|
|
10848
11096
|
const sequence6 = largeChoiceScalarSequences.get(code[base + i]);
|
|
10849
11097
|
return sequence6 === void 0 ? void 0 : { sequence: scalarSequenceRef(sequence6) };
|
|
10850
11098
|
});
|
|
10851
|
-
const maskable = n <= 32;
|
|
10852
11099
|
const maskName = maskable ? hoist("mk", `MASK[${masks.push(maskForClassRow(gates)) - 1}]`) : "";
|
|
10853
11100
|
if (maskable) maskPlan.push(~di);
|
|
10854
11101
|
const p = tmp();
|
|
@@ -10910,16 +11157,16 @@ ${merge}
|
|
|
10910
11157
|
ctx._fe=pos;ctx._fx=acc??${choiceFx}
|
|
10911
11158
|
return FAIL`;
|
|
10912
11159
|
return `${head}
|
|
10913
|
-
const c
|
|
11160
|
+
const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
10914
11161
|
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
10915
11162
|
${deepAt.map((at, i) => `let ${at},${deepFx[i]}`).join("\n")}
|
|
10916
11163
|
${maskable ? `if(c<128){
|
|
10917
|
-
const bits=${maskName}[c<0?128:c]
|
|
11164
|
+
const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
10918
11165
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
10919
11166
|
${lazyArms(true)}
|
|
10920
|
-
}else{
|
|
11167
|
+
}${directAsciiMask ? "" : `else{
|
|
10921
11168
|
${lazyArms(false)}
|
|
10922
|
-
}
|
|
11169
|
+
}`}
|
|
10923
11170
|
` : lazyArms(false)}
|
|
10924
11171
|
${finish}
|
|
10925
11172
|
}`;
|
|
@@ -10970,7 +11217,7 @@ if(ctx._fc===true){${startFailureExact ? `if(best===pos){acc=${catchName}(${i},0
|
|
|
10970
11217
|
${rollbackFor(i)}
|
|
10971
11218
|
}${routeMiss}${sequenceMiss}`;
|
|
10972
11219
|
}).join("\n") : "";
|
|
10973
|
-
const generalArms = arms.map((arm, i) => {
|
|
11220
|
+
const generalArms = directAsciiMask ? "" : arms.map((arm, i) => {
|
|
10974
11221
|
const pretest = pretests[i];
|
|
10975
11222
|
const decision = pretest?.token === void 0 && pretest?.sequence === void 0 ? "" : tmp();
|
|
10976
11223
|
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("||")})`;
|
|
@@ -11000,12 +11247,12 @@ ${rollbackFor(i)}
|
|
|
11000
11247
|
}${miss}`;
|
|
11001
11248
|
}).join("\n");
|
|
11002
11249
|
return `${head}
|
|
11003
|
-
const c
|
|
11250
|
+
const c=${directAsciiMask ? "input.charCodeAt(pos)" : "lead(input,pos)"}
|
|
11004
11251
|
${hasRollback ? emitMark(p, L.buf, L.raw, sinks) : ""}
|
|
11005
11252
|
let acc
|
|
11006
11253
|
let best=pos
|
|
11007
11254
|
${maskable ? `if(c<128){
|
|
11008
|
-
const bits=${maskName}[c<0?128:c]
|
|
11255
|
+
const bits=${maskName}[${directAsciiMask ? "c" : "c<0?128:c"}]
|
|
11009
11256
|
if(bits===0){ctx._fe=pos;ctx._fx=${choiceFx};return FAIL}
|
|
11010
11257
|
${startFailureExact ? "" : "let prev=0"}
|
|
11011
11258
|
${maskArms}
|
|
@@ -11100,14 +11347,18 @@ return [key,v]
|
|
|
11100
11347
|
const itemFx = reportItem ? fxRef(code[ip + 6]) : "EMPTY_FX";
|
|
11101
11348
|
const collect = op === OP_REP;
|
|
11102
11349
|
let itemCls;
|
|
11350
|
+
let itemAscii = false;
|
|
11103
11351
|
if (!REC) {
|
|
11104
11352
|
const itemClassIndex = sepIp < 0 ? code[ip + 7] : -1;
|
|
11105
11353
|
if (itemClassIndex >= 0) {
|
|
11106
|
-
const
|
|
11354
|
+
const resolved = t2.cc[itemClassIndex];
|
|
11355
|
+
const ci = classes.push([resolved]) - 1;
|
|
11107
11356
|
classPlan.push([itemClassIndex]);
|
|
11108
11357
|
itemCls = hoist("ri", `CLS[${ci}][0]`);
|
|
11358
|
+
itemAscii = staticBuild && isAsciiOnlyClass(resolved);
|
|
11109
11359
|
}
|
|
11110
11360
|
}
|
|
11361
|
+
const itemMiss = (at) => itemAscii ? `${itemCls}.ascii[input.charCodeAt(${at})]!==1` : `!classHas(${itemCls},lead(input,${at}))`;
|
|
11111
11362
|
const skipBeforeFirst = sepIp < 0 && min === 0;
|
|
11112
11363
|
const p = tmp();
|
|
11113
11364
|
const via = sep !== void 0 ? "false" : min === 0 ? skipBeforeFirst ? "true" : "count>0" : `count>=${min}&&count>0`;
|
|
@@ -11167,7 +11418,7 @@ let count=0
|
|
|
11167
11418
|
for(;;){
|
|
11168
11419
|
${max >= 0 ? `if(count>=${max})break
|
|
11169
11420
|
` : ""}${sep !== void 0 ? `if(count>0&&count>=${min}&&cur>=input.length)break
|
|
11170
|
-
` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}
|
|
11421
|
+
` : ""}${itemCls !== void 0 && sep === void 0 ? `if(count>=${min}&&${p}gate&&${hasTrivia === "false" ? "true" : hasTrivia === "true" ? "false" : "!hasTrivia"}&&${itemMiss("cur")})break
|
|
11171
11422
|
` : ""}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` : ""}
|
|
11172
11423
|
${markBody}
|
|
11173
11424
|
let itemStart=cur
|
|
@@ -11192,7 +11443,7 @@ itemStart=${hasTrivia === "false" ? "EC.e" : hasTrivia === "true" ? `${skip}(inp
|
|
|
11192
11443
|
${rb}
|
|
11193
11444
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
11194
11445
|
}
|
|
11195
|
-
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate
|
|
11446
|
+
${itemCls === void 0 ? "" : `if(count>=${min}&&${p}gate&&${itemMiss("itemStart")}){
|
|
11196
11447
|
${rb}
|
|
11197
11448
|
${trailingAllowed ? "if(sepEnd>=0)cur=sepEnd\n" : ""}break
|
|
11198
11449
|
}
|