parseman 0.42.0 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/combinators/node.d.ts +21 -7
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +23 -2
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +6 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +7 -1
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/cst/reflection.d.ts +24 -0
- package/dist/cst/reflection.d.ts.map +1 -0
- package/dist/cst/types.d.ts +2 -0
- package/dist/cst/types.d.ts.map +1 -1
- package/dist/cst/walk.d.ts +27 -62
- package/dist/cst/walk.d.ts.map +1 -1
- package/dist/index.cjs +375 -195
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +375 -195
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs +25 -33
- package/dist/language-service/index.cjs.map +4 -4
- package/dist/language-service/index.d.ts +1 -1
- package/dist/language-service/index.d.ts.map +1 -1
- package/dist/language-service/index.js +25 -33
- package/dist/language-service/index.js.map +4 -4
- package/dist/plugin/evaluator.d.ts +1 -0
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +654 -173
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +654 -173
- package/dist/plugin/index.js.map +4 -4
- package/dist/spec/index.cjs +429 -313
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +429 -313
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -121,7 +121,6 @@ __export(index_exports, {
|
|
|
121
121
|
trivia: () => trivia,
|
|
122
122
|
triviaEntries: () => triviaEntries,
|
|
123
123
|
triviaKindMask: () => triviaKindMask,
|
|
124
|
-
walk: () => walk,
|
|
125
124
|
when: () => when,
|
|
126
125
|
withCtx: () => withCtx,
|
|
127
126
|
word: () => word
|
|
@@ -2898,6 +2897,221 @@ function markUnusedValues(root) {
|
|
|
2898
2897
|
visit(resolveRoot(root), true);
|
|
2899
2898
|
}
|
|
2900
2899
|
|
|
2900
|
+
// src/combinators/grammar.ts
|
|
2901
|
+
function annotateResultLines(result, index) {
|
|
2902
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
2903
|
+
const errors = annotated.errors;
|
|
2904
|
+
if (errors) {
|
|
2905
|
+
;
|
|
2906
|
+
annotated.errors = errors.map((error) => ({
|
|
2907
|
+
...error,
|
|
2908
|
+
span: annotateSpan(error.span, index)
|
|
2909
|
+
}));
|
|
2910
|
+
}
|
|
2911
|
+
return annotated;
|
|
2912
|
+
}
|
|
2913
|
+
function createParseLineContext(input, pos) {
|
|
2914
|
+
const lineIndex = createLineIndex();
|
|
2915
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
2916
|
+
return { lineIndex, lineScannedTo: pos };
|
|
2917
|
+
}
|
|
2918
|
+
function parser(opts, root) {
|
|
2919
|
+
const clearTrivia = opts.trivia === null;
|
|
2920
|
+
return {
|
|
2921
|
+
_tag: "grammar",
|
|
2922
|
+
_meta: root._meta,
|
|
2923
|
+
_def: {
|
|
2924
|
+
tag: "grammar",
|
|
2925
|
+
parser: root,
|
|
2926
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2927
|
+
clearTrivia,
|
|
2928
|
+
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2929
|
+
trackLines: opts.trackLines ?? false
|
|
2930
|
+
},
|
|
2931
|
+
parse(input, pos, _ctx) {
|
|
2932
|
+
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2933
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2934
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
2935
|
+
const ctx = {
|
|
2936
|
+
..._ctx,
|
|
2937
|
+
trackLines,
|
|
2938
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
2939
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
2940
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
2941
|
+
...clearTrivia ? {
|
|
2942
|
+
trivia: void 0,
|
|
2943
|
+
triviaKindLabels: void 0
|
|
2944
|
+
} : opts.trivia != null ? {
|
|
2945
|
+
trivia: opts.trivia,
|
|
2946
|
+
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
2947
|
+
} : {},
|
|
2948
|
+
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
2949
|
+
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
2950
|
+
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
2951
|
+
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2952
|
+
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2953
|
+
// (capture all).
|
|
2954
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
2955
|
+
};
|
|
2956
|
+
const result = root.parse(input, pos ?? 0, ctx);
|
|
2957
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
2958
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
2959
|
+
}
|
|
2960
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
2961
|
+
}
|
|
2962
|
+
};
|
|
2963
|
+
}
|
|
2964
|
+
function noTrivia(root) {
|
|
2965
|
+
return parser({ trivia: null }, root);
|
|
2966
|
+
}
|
|
2967
|
+
var _analyzed = /* @__PURE__ */ new WeakSet();
|
|
2968
|
+
function parse(combinator, input, opts = {}) {
|
|
2969
|
+
if (!_analyzed.has(combinator)) {
|
|
2970
|
+
_analyzed.add(combinator);
|
|
2971
|
+
markUnusedValues(combinator);
|
|
2972
|
+
}
|
|
2973
|
+
const trackLines = opts.trackLines ?? combinator._meta.grammarTrackLines ?? false;
|
|
2974
|
+
const lineContext = trackLines ? createParseLineContext(input, 0) : void 0;
|
|
2975
|
+
const lineIndex = lineContext?.lineIndex;
|
|
2976
|
+
const _errors = opts.recover ? [] : void 0;
|
|
2977
|
+
const _probe = opts.recover ? { offset: input.length, best: null } : void 0;
|
|
2978
|
+
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
2979
|
+
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
2980
|
+
const ctx = {
|
|
2981
|
+
trackLines,
|
|
2982
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
2983
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
2984
|
+
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
|
|
2985
|
+
...grammarScanSkip !== void 0 ? { scanSkip: grammarScanSkip } : {},
|
|
2986
|
+
..._errors !== void 0 ? { _errors } : {},
|
|
2987
|
+
..._probe !== void 0 ? { _probe } : {}
|
|
2988
|
+
};
|
|
2989
|
+
const result = combinator.parse(input, 0, ctx);
|
|
2990
|
+
if (!result.ok) return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
2991
|
+
const withErrors = _errors !== void 0 ? { ...result, errors: _errors, furthestFail: _probe?.best ?? null } : result;
|
|
2992
|
+
return lineIndex ? annotateResultLines(withErrors, normalizeLineIndex(lineIndex)) : withErrors;
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2995
|
+
// src/cst/reflection.ts
|
|
2996
|
+
var GRAMMAR_REFLECTION = /* @__PURE__ */ Symbol.for("parseman.grammarReflection");
|
|
2997
|
+
function childrenOf(def) {
|
|
2998
|
+
switch (def.tag) {
|
|
2999
|
+
case "sequence":
|
|
3000
|
+
case "choice":
|
|
3001
|
+
return def.parsers;
|
|
3002
|
+
case "dispatch":
|
|
3003
|
+
return [
|
|
3004
|
+
def.selector,
|
|
3005
|
+
...def.cases.map((c) => c.parser),
|
|
3006
|
+
...def.matchers ? def.matchers.map((c) => c.parser) : [],
|
|
3007
|
+
...def.otherwise ? [def.otherwise] : []
|
|
3008
|
+
];
|
|
3009
|
+
case "many":
|
|
3010
|
+
case "oneOrMore":
|
|
3011
|
+
case "optional":
|
|
3012
|
+
case "attempt":
|
|
3013
|
+
case "transform":
|
|
3014
|
+
case "trivia":
|
|
3015
|
+
case "token":
|
|
3016
|
+
case "leaf":
|
|
3017
|
+
case "label":
|
|
3018
|
+
case "field":
|
|
3019
|
+
case "not":
|
|
3020
|
+
case "peek":
|
|
3021
|
+
case "node":
|
|
3022
|
+
case "withCtx":
|
|
3023
|
+
case "recover":
|
|
3024
|
+
case "expect":
|
|
3025
|
+
return [def.parser];
|
|
3026
|
+
case "grammar":
|
|
3027
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
3028
|
+
case "sepBy":
|
|
3029
|
+
return [def.parser, def.separator];
|
|
3030
|
+
case "skip":
|
|
3031
|
+
return [def.main, def.skipped];
|
|
3032
|
+
case "scanTo":
|
|
3033
|
+
return [def.sentinel, ...def.skip];
|
|
3034
|
+
case "literal":
|
|
3035
|
+
case "regex":
|
|
3036
|
+
case "keywords":
|
|
3037
|
+
case "routed":
|
|
3038
|
+
case "guard":
|
|
3039
|
+
case "lazy":
|
|
3040
|
+
case "unknown":
|
|
3041
|
+
return [];
|
|
3042
|
+
}
|
|
3043
|
+
}
|
|
3044
|
+
function addNode(out, def) {
|
|
3045
|
+
if (def.type === void 0) return;
|
|
3046
|
+
const existing = out.get(def.type);
|
|
3047
|
+
if (existing === void 0) {
|
|
3048
|
+
out.set(def.type, def.tags === void 0 ? [] : [...def.tags]);
|
|
3049
|
+
return;
|
|
3050
|
+
}
|
|
3051
|
+
if (def.tags === void 0) return;
|
|
3052
|
+
for (const tag of def.tags) {
|
|
3053
|
+
if (!existing.includes(tag)) existing.push(tag);
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
3057
|
+
if (seen.has(parser2)) return;
|
|
3058
|
+
seen.add(parser2);
|
|
3059
|
+
const def = parser2._def;
|
|
3060
|
+
if (def.tag === "lazy") {
|
|
3061
|
+
if (followLazy) {
|
|
3062
|
+
try {
|
|
3063
|
+
collectFromCombinator(def.thunk(), out, seen, followLazy);
|
|
3064
|
+
} catch {
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
3067
|
+
return;
|
|
3068
|
+
}
|
|
3069
|
+
if (def.tag === "node") addNode(out, def);
|
|
3070
|
+
for (const child of childrenOf(def)) collectFromCombinator(child, out, seen, followLazy);
|
|
3071
|
+
}
|
|
3072
|
+
function collectGrammarReflection(ruleMap, opts) {
|
|
3073
|
+
const byType = /* @__PURE__ */ new Map();
|
|
3074
|
+
const followLazy = opts?.followLazy !== false;
|
|
3075
|
+
for (const [, rule] of ruleMap) {
|
|
3076
|
+
if (!followLazy && rule._def.tag === "lazy") {
|
|
3077
|
+
try {
|
|
3078
|
+
const resolved = rule._def.thunk();
|
|
3079
|
+
if (resolved._def.tag !== "lazy") collectFromCombinator(resolved, byType, /* @__PURE__ */ new Set(), false);
|
|
3080
|
+
} catch {
|
|
3081
|
+
}
|
|
3082
|
+
continue;
|
|
3083
|
+
}
|
|
3084
|
+
collectFromCombinator(rule, byType, /* @__PURE__ */ new Set(), followLazy);
|
|
3085
|
+
}
|
|
3086
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
3087
|
+
}
|
|
3088
|
+
function mergeGrammarReflections(reflections) {
|
|
3089
|
+
const byType = /* @__PURE__ */ new Map();
|
|
3090
|
+
for (const reflection of reflections) {
|
|
3091
|
+
for (const node2 of reflection.nodes) {
|
|
3092
|
+
const tags = byType.get(node2.type);
|
|
3093
|
+
if (tags === void 0) {
|
|
3094
|
+
byType.set(node2.type, [...node2.tags]);
|
|
3095
|
+
continue;
|
|
3096
|
+
}
|
|
3097
|
+
for (const tag of node2.tags) {
|
|
3098
|
+
if (!tags.includes(tag)) tags.push(tag);
|
|
3099
|
+
}
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3102
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
3103
|
+
}
|
|
3104
|
+
function attachGrammarReflection(grammar, reflection) {
|
|
3105
|
+
Object.defineProperty(grammar, GRAMMAR_REFLECTION, { value: reflection, enumerable: false, configurable: true });
|
|
3106
|
+
return grammar;
|
|
3107
|
+
}
|
|
3108
|
+
function grammarReflectionOf(grammar) {
|
|
3109
|
+
return grammar[GRAMMAR_REFLECTION];
|
|
3110
|
+
}
|
|
3111
|
+
function grammarReflectionSource(reflection) {
|
|
3112
|
+
return `{ nodes: ${JSON.stringify(reflection.nodes)} }`;
|
|
3113
|
+
}
|
|
3114
|
+
|
|
2901
3115
|
// src/combinators/parser.ts
|
|
2902
3116
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2903
3117
|
function tagRule(r, key) {
|
|
@@ -2973,6 +3187,21 @@ function rules(a, b) {
|
|
|
2973
3187
|
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
2974
3188
|
}
|
|
2975
3189
|
}
|
|
3190
|
+
if (options?.trackLines === true) {
|
|
3191
|
+
for (const key of Object.keys(definitions)) {
|
|
3192
|
+
const rule = cache[key];
|
|
3193
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
3194
|
+
}
|
|
3195
|
+
for (const key of Object.keys(definitions)) {
|
|
3196
|
+
const rule = cache[key];
|
|
3197
|
+
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
3198
|
+
const wrapped = parser({ trackLines: true }, rule);
|
|
3199
|
+
tagRule(wrapped, key);
|
|
3200
|
+
wrapped._meta.grammarTrackLines = true;
|
|
3201
|
+
cache[key] = wrapped;
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
2976
3205
|
for (const key of Object.keys(definitions)) {
|
|
2977
3206
|
markUnusedValues(cache[key]);
|
|
2978
3207
|
}
|
|
@@ -2981,6 +3210,7 @@ function rules(a, b) {
|
|
|
2981
3210
|
enumerable: false,
|
|
2982
3211
|
configurable: true
|
|
2983
3212
|
});
|
|
3213
|
+
attachGrammarReflection(cache, collectGrammarReflection(Object.keys(definitions).map((key) => [key, cache[key]])));
|
|
2984
3214
|
return cache;
|
|
2985
3215
|
}
|
|
2986
3216
|
|
|
@@ -3301,13 +3531,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3301
3531
|
const collapse = opts?.collapse === true;
|
|
3302
3532
|
const captureTrivia = opts?.captureTrivia === true;
|
|
3303
3533
|
const trailingTrivia = opts?.trailingTrivia === true;
|
|
3534
|
+
const tags = opts?.tags;
|
|
3304
3535
|
if (unwrap && collapse) {
|
|
3305
3536
|
throw new Error("node() options cannot set both unwrap and collapse");
|
|
3306
3537
|
}
|
|
3307
3538
|
if (project !== void 0 && (unwrap || collapse)) {
|
|
3308
3539
|
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
3309
3540
|
}
|
|
3310
|
-
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {} } : baseDef;
|
|
3541
|
+
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
|
|
3311
3542
|
const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
3312
3543
|
const clonesState = build ? buildReadsState(def) : project === void 0;
|
|
3313
3544
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
@@ -3353,7 +3584,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3353
3584
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3354
3585
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3355
3586
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3356
|
-
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
3587
|
+
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
3357
3588
|
const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
|
|
3358
3589
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3359
3590
|
pushCstChild(ctx, built, rawEntry);
|
|
@@ -3429,101 +3660,6 @@ function field(name, combinator) {
|
|
|
3429
3660
|
};
|
|
3430
3661
|
}
|
|
3431
3662
|
|
|
3432
|
-
// src/combinators/grammar.ts
|
|
3433
|
-
function annotateResultLines(result, index) {
|
|
3434
|
-
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
3435
|
-
const errors = annotated.errors;
|
|
3436
|
-
if (errors) {
|
|
3437
|
-
;
|
|
3438
|
-
annotated.errors = errors.map((error) => ({
|
|
3439
|
-
...error,
|
|
3440
|
-
span: annotateSpan(error.span, index)
|
|
3441
|
-
}));
|
|
3442
|
-
}
|
|
3443
|
-
return annotated;
|
|
3444
|
-
}
|
|
3445
|
-
function createParseLineContext(input, pos) {
|
|
3446
|
-
const lineIndex = createLineIndex();
|
|
3447
|
-
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
3448
|
-
return { lineIndex, lineScannedTo: pos };
|
|
3449
|
-
}
|
|
3450
|
-
function parser(opts, root) {
|
|
3451
|
-
const clearTrivia = opts.trivia === null;
|
|
3452
|
-
return {
|
|
3453
|
-
_tag: "grammar",
|
|
3454
|
-
_meta: root._meta,
|
|
3455
|
-
_def: {
|
|
3456
|
-
tag: "grammar",
|
|
3457
|
-
parser: root,
|
|
3458
|
-
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
3459
|
-
clearTrivia,
|
|
3460
|
-
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
3461
|
-
trackLines: opts.trackLines ?? false
|
|
3462
|
-
},
|
|
3463
|
-
parse(input, pos, _ctx) {
|
|
3464
|
-
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
3465
|
-
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
3466
|
-
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
3467
|
-
const ctx = {
|
|
3468
|
-
..._ctx,
|
|
3469
|
-
trackLines,
|
|
3470
|
-
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
3471
|
-
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
3472
|
-
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
3473
|
-
...clearTrivia ? {
|
|
3474
|
-
trivia: void 0,
|
|
3475
|
-
triviaKindLabels: void 0
|
|
3476
|
-
} : opts.trivia != null ? {
|
|
3477
|
-
trivia: opts.trivia,
|
|
3478
|
-
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
3479
|
-
} : {},
|
|
3480
|
-
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
3481
|
-
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
3482
|
-
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
3483
|
-
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
3484
|
-
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
3485
|
-
// (capture all).
|
|
3486
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
3487
|
-
};
|
|
3488
|
-
const result = root.parse(input, pos ?? 0, ctx);
|
|
3489
|
-
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
3490
|
-
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
3491
|
-
}
|
|
3492
|
-
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
3493
|
-
}
|
|
3494
|
-
};
|
|
3495
|
-
}
|
|
3496
|
-
function noTrivia(root) {
|
|
3497
|
-
return parser({ trivia: null }, root);
|
|
3498
|
-
}
|
|
3499
|
-
var _analyzed = /* @__PURE__ */ new WeakSet();
|
|
3500
|
-
function parse(combinator, input, opts = {}) {
|
|
3501
|
-
if (!_analyzed.has(combinator)) {
|
|
3502
|
-
_analyzed.add(combinator);
|
|
3503
|
-
markUnusedValues(combinator);
|
|
3504
|
-
}
|
|
3505
|
-
const trackLines = opts.trackLines ?? false;
|
|
3506
|
-
const lineContext = trackLines ? createParseLineContext(input, 0) : void 0;
|
|
3507
|
-
const lineIndex = lineContext?.lineIndex;
|
|
3508
|
-
const _errors = opts.recover ? [] : void 0;
|
|
3509
|
-
const _probe = opts.recover ? { offset: input.length, best: null } : void 0;
|
|
3510
|
-
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
3511
|
-
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
3512
|
-
const ctx = {
|
|
3513
|
-
trackLines,
|
|
3514
|
-
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
3515
|
-
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
3516
|
-
...grammarTrivia !== void 0 ? { trivia: grammarTrivia, ...grammarTrivia._meta.triviaKindLabels ? { triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {} } : {},
|
|
3517
|
-
...grammarScanSkip !== void 0 ? { scanSkip: grammarScanSkip } : {},
|
|
3518
|
-
..._errors !== void 0 ? { _errors } : {},
|
|
3519
|
-
..._probe !== void 0 ? { _probe } : {}
|
|
3520
|
-
};
|
|
3521
|
-
const result = combinator.parse(input, 0, ctx);
|
|
3522
|
-
if (!result.ok) return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
3523
|
-
const withErrors = _errors !== void 0 ? { ...result, errors: _errors, furthestFail: _probe?.best ?? null } : result;
|
|
3524
|
-
return lineIndex ? annotateResultLines(withErrors, normalizeLineIndex(lineIndex)) : withErrors;
|
|
3525
|
-
}
|
|
3526
|
-
|
|
3527
3663
|
// src/combinators/token.ts
|
|
3528
3664
|
function token(root) {
|
|
3529
3665
|
const meta = {
|
|
@@ -3620,7 +3756,7 @@ function leaf(root, fn) {
|
|
|
3620
3756
|
}
|
|
3621
3757
|
|
|
3622
3758
|
// src/version.ts
|
|
3623
|
-
var PARSEMAN_VERSION = "0.
|
|
3759
|
+
var PARSEMAN_VERSION = "0.43.0";
|
|
3624
3760
|
|
|
3625
3761
|
// src/cst/host-mode.ts
|
|
3626
3762
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -3686,7 +3822,7 @@ var SUGGESTIONS = {
|
|
|
3686
3822
|
function classifyBroadArm(arm, resolve) {
|
|
3687
3823
|
const seen = /* @__PURE__ */ new Set();
|
|
3688
3824
|
const relabel = (inner, cause, detail) => ({ cause, detail, ...inner?.unresolvedExternal ? { unresolvedExternal: true } : {} });
|
|
3689
|
-
const
|
|
3825
|
+
const walk = (p) => {
|
|
3690
3826
|
if (seen.has(p)) return { cause: "ref-cycle", detail: "ref cycle" };
|
|
3691
3827
|
seen.add(p);
|
|
3692
3828
|
const d = p._def;
|
|
@@ -3700,7 +3836,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3700
3836
|
// peek() CARRIES its body's first-set, so it is only broad when the body is
|
|
3701
3837
|
// (or the body is nullable) — walk in for the real cause.
|
|
3702
3838
|
case "peek":
|
|
3703
|
-
return
|
|
3839
|
+
return walk(d.parser);
|
|
3704
3840
|
case "scanTo":
|
|
3705
3841
|
return { cause: "broad-recognizer", detail: "scanTo (any first char)" };
|
|
3706
3842
|
// `guard` (the `gate()` state predicate) has a genuinely-`any` first-set of
|
|
@@ -3714,7 +3850,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3714
3850
|
case "attempt":
|
|
3715
3851
|
case "withCtx":
|
|
3716
3852
|
case "recover":
|
|
3717
|
-
return
|
|
3853
|
+
return walk(d.parser);
|
|
3718
3854
|
case "lazy": {
|
|
3719
3855
|
const name = p._ruleName;
|
|
3720
3856
|
let target;
|
|
@@ -3726,13 +3862,13 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3726
3862
|
return { cause: "cross-artifact-ref", detail: `unresolved ref${name ? ` g.${name}` : ""}`, unresolvedExternal: name !== void 0 };
|
|
3727
3863
|
target = bound;
|
|
3728
3864
|
}
|
|
3729
|
-
const inner =
|
|
3865
|
+
const inner = walk(target);
|
|
3730
3866
|
if (name !== void 0) return inner ? relabel(inner, "cross-artifact-ref", `via ref g.${name} \u2192 ${inner.detail}`) : null;
|
|
3731
3867
|
return inner;
|
|
3732
3868
|
}
|
|
3733
3869
|
case "optional":
|
|
3734
3870
|
case "many": {
|
|
3735
|
-
const inner =
|
|
3871
|
+
const inner = walk(d.parser);
|
|
3736
3872
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3737
3873
|
}
|
|
3738
3874
|
case "oneOrMore":
|
|
@@ -3745,9 +3881,9 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3745
3881
|
case "node":
|
|
3746
3882
|
case "grammar":
|
|
3747
3883
|
case "expect":
|
|
3748
|
-
return
|
|
3884
|
+
return walk(d.parser);
|
|
3749
3885
|
case "skip":
|
|
3750
|
-
return
|
|
3886
|
+
return walk(d.main);
|
|
3751
3887
|
case "sequence": {
|
|
3752
3888
|
let sawNullablePrefix = false;
|
|
3753
3889
|
for (const t of d.parsers) {
|
|
@@ -3756,7 +3892,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3756
3892
|
continue;
|
|
3757
3893
|
}
|
|
3758
3894
|
if (isAny(firstSetOf(t, /* @__PURE__ */ new Set(), resolve))) {
|
|
3759
|
-
const inner =
|
|
3895
|
+
const inner = walk(t);
|
|
3760
3896
|
if (sawNullablePrefix)
|
|
3761
3897
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3762
3898
|
return inner ?? { cause: "broad-recognizer", detail: "sequence leading term is broad" };
|
|
@@ -3771,18 +3907,18 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3771
3907
|
}
|
|
3772
3908
|
case "choice": {
|
|
3773
3909
|
for (const a of d.parsers) {
|
|
3774
|
-
const r =
|
|
3910
|
+
const r = walk(a);
|
|
3775
3911
|
if (r) return relabel(r, r.cause, `choice arm \u2192 ${r.detail}`);
|
|
3776
3912
|
}
|
|
3777
3913
|
return null;
|
|
3778
3914
|
}
|
|
3779
3915
|
case "dispatch":
|
|
3780
|
-
return
|
|
3916
|
+
return walk(d.selector);
|
|
3781
3917
|
default:
|
|
3782
3918
|
return { cause: "broad-recognizer", detail: `unmodeled construct (${d.tag})` };
|
|
3783
3919
|
}
|
|
3784
3920
|
};
|
|
3785
|
-
return
|
|
3921
|
+
return walk(arm) ?? { cause: "broad-recognizer", detail: "broad (cause not localized)" };
|
|
3786
3922
|
}
|
|
3787
3923
|
function peelToLeading(arm) {
|
|
3788
3924
|
let d = arm._def;
|
|
@@ -3984,7 +4120,7 @@ function formatGatingWarnings(report) {
|
|
|
3984
4120
|
|
|
3985
4121
|
// src/analysis/duplication.ts
|
|
3986
4122
|
var siteToString = (s) => s.path === "" ? s.rule : `${s.rule} \u203A ${s.path}`;
|
|
3987
|
-
function
|
|
4123
|
+
function childrenOf2(d) {
|
|
3988
4124
|
switch (d.tag) {
|
|
3989
4125
|
case "sequence":
|
|
3990
4126
|
case "choice":
|
|
@@ -4118,7 +4254,7 @@ function render(p, depth = 3) {
|
|
|
4118
4254
|
break;
|
|
4119
4255
|
}
|
|
4120
4256
|
if (depth <= 0) return `${d.tag}(\u2026)`;
|
|
4121
|
-
const kids =
|
|
4257
|
+
const kids = childrenOf2(d).map((k) => render(k, depth - 1));
|
|
4122
4258
|
switch (d.tag) {
|
|
4123
4259
|
case "sequence":
|
|
4124
4260
|
return `sequence(${kids.join(", ")})`;
|
|
@@ -4313,7 +4449,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4313
4449
|
if (hit !== void 0) return hit;
|
|
4314
4450
|
const d = p._def;
|
|
4315
4451
|
shapeCache.set(p, interner.hole);
|
|
4316
|
-
const kids =
|
|
4452
|
+
const kids = childrenOf2(d);
|
|
4317
4453
|
const id = interner.of(`${payloadKey(p, d)}|${kids.map(shapeOf).join(",")}`);
|
|
4318
4454
|
shapeCache.set(p, id);
|
|
4319
4455
|
return id;
|
|
@@ -4323,7 +4459,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4323
4459
|
if (hit !== void 0) return hit;
|
|
4324
4460
|
sizeCache.set(p, 1);
|
|
4325
4461
|
let n = 1;
|
|
4326
|
-
for (const k of
|
|
4462
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4327
4463
|
sizeCache.set(p, n);
|
|
4328
4464
|
return n;
|
|
4329
4465
|
};
|
|
@@ -4336,7 +4472,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4336
4472
|
visited.set(p, { p, d, site: here, shape: shapeOf(p), size: sizeOf(p), enclosingNode, enclosingReducer });
|
|
4337
4473
|
const inner = d.tag === "node" ? d.type ?? "(anonymous)" : enclosingNode;
|
|
4338
4474
|
const innerReducer = enclosingReducer || d.tag === "node" && (d.build !== void 0 || d.buildSrc !== void 0) || d.tag === "transform" || d.tag === "leaf";
|
|
4339
|
-
const kids =
|
|
4475
|
+
const kids = childrenOf2(d);
|
|
4340
4476
|
kids.forEach((k, i) => {
|
|
4341
4477
|
const seg = segment(d, i);
|
|
4342
4478
|
visit(k, here.rule, here.path === "" ? seg : `${here.path} \u203A ${seg}`, inner, innerReducer);
|
|
@@ -4396,7 +4532,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4396
4532
|
function markSubtree(p, into) {
|
|
4397
4533
|
if (into.has(p)) return;
|
|
4398
4534
|
into.add(p);
|
|
4399
|
-
for (const k of
|
|
4535
|
+
for (const k of childrenOf2(p._def)) markSubtree(k, into);
|
|
4400
4536
|
}
|
|
4401
4537
|
var stripMembers = (f) => {
|
|
4402
4538
|
const { _members, ...rest } = f;
|
|
@@ -4436,7 +4572,7 @@ function findNearDuplicates(visited, interner, shapeOf, minSize) {
|
|
|
4436
4572
|
if (hit !== void 0) return hit;
|
|
4437
4573
|
holeCache.set(p, []);
|
|
4438
4574
|
const d = p._def;
|
|
4439
|
-
const kids =
|
|
4575
|
+
const kids = childrenOf2(d);
|
|
4440
4576
|
const kidShapes = kids.map(shapeOf);
|
|
4441
4577
|
const payload = payloadKey(p, d);
|
|
4442
4578
|
const out2 = [];
|
|
@@ -4497,7 +4633,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4497
4633
|
let cur = [...members];
|
|
4498
4634
|
for (let guard2 = 0; guard2 < 64; guard2++) {
|
|
4499
4635
|
const d0 = cur[0]._def;
|
|
4500
|
-
const kidLists = cur.map((c) =>
|
|
4636
|
+
const kidLists = cur.map((c) => childrenOf2(c._def));
|
|
4501
4637
|
const arity = kidLists[0].length;
|
|
4502
4638
|
if (kidLists.some((k) => k.length !== arity) || arity === 0) break;
|
|
4503
4639
|
const diff = [];
|
|
@@ -4510,7 +4646,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4510
4646
|
path.push(i);
|
|
4511
4647
|
defs.push(d0);
|
|
4512
4648
|
cur = kidLists.map((k) => k[i]);
|
|
4513
|
-
const nextArity =
|
|
4649
|
+
const nextArity = childrenOf2(cur[0]._def).length;
|
|
4514
4650
|
const samePayload = cur.every((c) => payloadKey(c, c._def) === payloadKey(cur[0], cur[0]._def));
|
|
4515
4651
|
if (!samePayload || nextArity === 0) break;
|
|
4516
4652
|
}
|
|
@@ -4518,7 +4654,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4518
4654
|
let slotSize = 0;
|
|
4519
4655
|
const sizeOf = (p) => {
|
|
4520
4656
|
let n = 1;
|
|
4521
|
-
for (const k of
|
|
4657
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4522
4658
|
return n;
|
|
4523
4659
|
};
|
|
4524
4660
|
for (const c of cur) slotSize = Math.max(slotSize, sizeOf(c));
|
|
@@ -4527,7 +4663,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4527
4663
|
function renderWithHole(p, path, depth = 0) {
|
|
4528
4664
|
if (depth === path.length) return "\u2039slot\u203A";
|
|
4529
4665
|
const d = p._def;
|
|
4530
|
-
const kids =
|
|
4666
|
+
const kids = childrenOf2(d);
|
|
4531
4667
|
const idx = path[depth];
|
|
4532
4668
|
const parts = kids.map((k, i) => i === idx ? renderWithHole(k, path, depth + 1) : render(k, 2));
|
|
4533
4669
|
switch (d.tag) {
|
|
@@ -4985,7 +5121,7 @@ function capturesPositionally(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4985
5121
|
seen.add(p);
|
|
4986
5122
|
const d = p._def;
|
|
4987
5123
|
if (d.tag === "field" || d.tag === "label") return true;
|
|
4988
|
-
for (const k of
|
|
5124
|
+
for (const k of childrenOf2(d)) if (capturesPositionally(k, seen)) return true;
|
|
4989
5125
|
return false;
|
|
4990
5126
|
}
|
|
4991
5127
|
function detectHandRolledSepBy(terms, shapeOf) {
|
|
@@ -5091,7 +5227,7 @@ function nestedNodeTypes(root, out, seen, isRoot) {
|
|
|
5091
5227
|
}
|
|
5092
5228
|
return;
|
|
5093
5229
|
}
|
|
5094
|
-
for (const k of
|
|
5230
|
+
for (const k of childrenOf2(d)) nestedNodeTypes(k, out, seen, false);
|
|
5095
5231
|
}
|
|
5096
5232
|
var MAX_LOST_TYPES = 8;
|
|
5097
5233
|
function findStructureLoss(visited, resolve) {
|
|
@@ -6980,13 +7116,16 @@ function reindentStmts(stmts, targetLevels) {
|
|
|
6980
7116
|
const targetPrefix = " ".repeat(targetLevels);
|
|
6981
7117
|
return stmts.map((s) => s.trim().length === 0 ? "" : targetPrefix + s.slice(minLeading));
|
|
6982
7118
|
}
|
|
6983
|
-
function failReturn(expected, posExpr) {
|
|
7119
|
+
function failReturn(ctx, expected, posExpr) {
|
|
7120
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [${expected}], span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6984
7121
|
return `return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6985
7122
|
}
|
|
6986
|
-
function failReturnArr(expectedArr, posExpr) {
|
|
7123
|
+
function failReturnArr(ctx, expectedArr, posExpr) {
|
|
7124
|
+
if (ctx.lineTracking) return `return { ok: false, expected: ${expectedArr}, span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6987
7125
|
return `return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6988
7126
|
}
|
|
6989
|
-
function committedReturnArr(expectedArr, posExpr) {
|
|
7127
|
+
function committedReturnArr(ctx, expectedArr, posExpr) {
|
|
7128
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [...${expectedArr}], span: ${emitSpanExpr(ctx, posExpr, posExpr)}, committed: true }`;
|
|
6990
7129
|
return `return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} }, committed: true }`;
|
|
6991
7130
|
}
|
|
6992
7131
|
function hoistExpected(ctx, constArrSource) {
|
|
@@ -7011,7 +7150,7 @@ function failBody(ctx, expected, posExpr) {
|
|
|
7011
7150
|
if (!ctx.recordFail) return probe ? `{ ${probe}${trace}break ${ctx.failLabel} }` : trace ? `{ ${trace}break ${ctx.failLabel} }` : `break ${ctx.failLabel}`;
|
|
7012
7151
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${hoistExpected(ctx, `[${expected}]`)}; ${trace}break ${ctx.failLabel} }`;
|
|
7013
7152
|
}
|
|
7014
|
-
return probe + trace + failReturn(expected, posExpr);
|
|
7153
|
+
return probe + trace + failReturn(ctx, expected, posExpr);
|
|
7015
7154
|
}
|
|
7016
7155
|
function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
7017
7156
|
const probe = probeUpdate(ctx, expectedArr, posExpr, constant);
|
|
@@ -7021,18 +7160,19 @@ function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
|
7021
7160
|
const fx = constant ? hoistExpected(ctx, expectedArr) : expectedArr;
|
|
7022
7161
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${fx}; ${trace}break ${ctx.failLabel} }`;
|
|
7023
7162
|
}
|
|
7024
|
-
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
7025
|
-
return probe + trace + failReturnArr(expectedArr, posExpr);
|
|
7163
|
+
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: ${ctx.lineTracking ? emitSpanExpr(ctx, posExpr, posExpr) : `{ start: ${posExpr}, end: ${posExpr} }`} }`;
|
|
7164
|
+
return probe + trace + failReturnArr(ctx, expectedArr, posExpr);
|
|
7026
7165
|
}
|
|
7027
|
-
function resultFromRecorded(feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
7028
|
-
|
|
7166
|
+
function resultFromRecorded(ctx, feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
7167
|
+
const spanExpr = ctx.lineTracking ? emitSpanExpr(ctx, feExpr, feExpr) : `{ start: ${feExpr}, end: ${feExpr} }`;
|
|
7168
|
+
return `return { ok: false, expected: [...${fxExpr}], span: ${spanExpr}, ...(_ctx._fc ? { committed: true } : {}) }`;
|
|
7029
7169
|
}
|
|
7030
7170
|
function committedFailBody(ctx, expectedArr = "_ctx._fx", posExpr = "_ctx._fe") {
|
|
7031
7171
|
if (ctx.failLabel) {
|
|
7032
7172
|
if (!ctx.recordFail) return `{ _ctx._fc = true; break ${ctx.failLabel} }`;
|
|
7033
7173
|
return `{ _ctx._fc = true; _ctx._fe = ${posExpr}; _ctx._fx = ${expectedArr}; break ${ctx.failLabel} }`;
|
|
7034
7174
|
}
|
|
7035
|
-
return committedReturnArr(expectedArr, posExpr);
|
|
7175
|
+
return committedReturnArr(ctx, expectedArr, posExpr);
|
|
7036
7176
|
}
|
|
7037
7177
|
function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
7038
7178
|
if (srcCtx !== "_ctx") {
|
|
@@ -7040,10 +7180,10 @@ function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
|
7040
7180
|
if (!ctx.recordFail) return `break ${ctx.failLabel}`;
|
|
7041
7181
|
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; break ${ctx.failLabel} }`;
|
|
7042
7182
|
}
|
|
7043
|
-
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded()} }`;
|
|
7183
|
+
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded(ctx)} }`;
|
|
7044
7184
|
}
|
|
7045
7185
|
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
7046
|
-
return resultFromRecorded();
|
|
7186
|
+
return resultFromRecorded(ctx);
|
|
7047
7187
|
}
|
|
7048
7188
|
function emitIfFail(ctx, cond, body) {
|
|
7049
7189
|
return [
|
|
@@ -8274,7 +8414,7 @@ function routedNeedsContextBridge(p, ctx, seen = /* @__PURE__ */ new Set()) {
|
|
|
8274
8414
|
const d = p._def;
|
|
8275
8415
|
if (d.tag === "dispatch") return false;
|
|
8276
8416
|
if (d.tag === "withCtx") return parserUsesRouted2(d.parser);
|
|
8277
|
-
return
|
|
8417
|
+
return childrenOf3(d).some((child) => routedNeedsContextBridge(child, ctx, seen));
|
|
8278
8418
|
}
|
|
8279
8419
|
function armReplayInScope(arm, ctx) {
|
|
8280
8420
|
let p = arm;
|
|
@@ -8476,7 +8616,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8476
8616
|
if (!ctx.recovery && !ctx.coverage && needsFirstSetGuard(def.parser)) {
|
|
8477
8617
|
const gcV = v(ctx, "_agc");
|
|
8478
8618
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8479
|
-
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(gExp, pos)} }`;
|
|
8619
|
+
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(ctx, gExp, pos)} }`;
|
|
8480
8620
|
preGuard.push(
|
|
8481
8621
|
`${ind(ctx)}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8482
8622
|
`${ind(ctx)}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8975,7 +9115,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8975
9115
|
if (!ctx.recovery && !ctx.coverage && (capturesChildren || structural) && needsFirstSetGuard(def.parser)) {
|
|
8976
9116
|
const gcV = v(ctx, "_ngc");
|
|
8977
9117
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8978
|
-
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(gExp, pos);
|
|
9118
|
+
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(ctx, gExp, pos);
|
|
8979
9119
|
preGuard.push(
|
|
8980
9120
|
`${i}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8981
9121
|
`${i}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -9037,7 +9177,8 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
9037
9177
|
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
9038
9178
|
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
9039
9179
|
const buildExpr = structural ? `{ _tag: 'node', type: ${JSON.stringify(def.type)}, span: ${nodeSpanV}, state: ${stV} ?? null, children: ${chV} }` : mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, nodeSpanV, tlV) : def.project !== void 0 ? emitNodeProjectExpr(def.type, def.project, chV) : `${buildRef(ctx)}[${buildIdx}](${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV})`;
|
|
9040
|
-
const
|
|
9180
|
+
const hostBuildArgs = `${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV}${def.tags !== void 0 && def.tags.length > 0 ? `, ${JSON.stringify(def.tags)}` : ""}`;
|
|
9181
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${hostBuildArgs})`;
|
|
9041
9182
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
9042
9183
|
const hostCollapseExpr = structural ? `_ctx.build !== undefined && _ctx.build._parsemanCstCollapse !== undefined && ${chV}.length === 1 && ${rawV}.length === 1 && _ctx.build._parsemanCstCollapse(${JSON.stringify(def.type)}, ${chV}[0], ${chV}, ${rawV}) ? ${chV}[0] : (${ndExpr})` : ndExpr;
|
|
9043
9184
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -9491,6 +9632,7 @@ function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9491
9632
|
if (seen.has(p)) return false;
|
|
9492
9633
|
seen.add(p);
|
|
9493
9634
|
const d = p._def;
|
|
9635
|
+
if (p._meta.grammarTrackLines) return true;
|
|
9494
9636
|
if (d.tag === "grammar" && d.trackLines) return true;
|
|
9495
9637
|
if (d.tag === "lazy") {
|
|
9496
9638
|
try {
|
|
@@ -9499,7 +9641,7 @@ function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9499
9641
|
return false;
|
|
9500
9642
|
}
|
|
9501
9643
|
}
|
|
9502
|
-
return
|
|
9644
|
+
return childrenOf3(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9503
9645
|
}
|
|
9504
9646
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9505
9647
|
if (seen.has(p)) return false;
|
|
@@ -9518,7 +9660,7 @@ function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9518
9660
|
case "dispatch":
|
|
9519
9661
|
return false;
|
|
9520
9662
|
default:
|
|
9521
|
-
return
|
|
9663
|
+
return childrenOf3(d).some((child) => parserUsesRouted2(child, seen));
|
|
9522
9664
|
}
|
|
9523
9665
|
}
|
|
9524
9666
|
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -9533,9 +9675,9 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9533
9675
|
return false;
|
|
9534
9676
|
}
|
|
9535
9677
|
}
|
|
9536
|
-
return
|
|
9678
|
+
return childrenOf3(d).some((child) => hasDirectBuildDef(child, seen));
|
|
9537
9679
|
}
|
|
9538
|
-
function
|
|
9680
|
+
function childrenOf3(def) {
|
|
9539
9681
|
switch (def.tag) {
|
|
9540
9682
|
case "sequence":
|
|
9541
9683
|
case "choice":
|
|
@@ -9610,7 +9752,7 @@ function subtreeSizes(roots) {
|
|
|
9610
9752
|
const def = p._def;
|
|
9611
9753
|
let s = 1;
|
|
9612
9754
|
if (def.tag !== "lazy") {
|
|
9613
|
-
for (const child of
|
|
9755
|
+
for (const child of childrenOf3(def)) s += child._def.tag === "lazy" ? 1 : sz(child);
|
|
9614
9756
|
}
|
|
9615
9757
|
sizes.set(p, s);
|
|
9616
9758
|
return s;
|
|
@@ -9631,7 +9773,7 @@ function subtreeSizes(roots) {
|
|
|
9631
9773
|
return;
|
|
9632
9774
|
}
|
|
9633
9775
|
sz(p);
|
|
9634
|
-
for (const child of
|
|
9776
|
+
for (const child of childrenOf3(def)) visit(child);
|
|
9635
9777
|
};
|
|
9636
9778
|
for (const root of roots) visit(root);
|
|
9637
9779
|
return sizes;
|
|
@@ -9641,7 +9783,7 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9641
9783
|
const recursive = /* @__PURE__ */ new Set();
|
|
9642
9784
|
const descended = /* @__PURE__ */ new Set();
|
|
9643
9785
|
const active = /* @__PURE__ */ new Set();
|
|
9644
|
-
function
|
|
9786
|
+
function walk(p) {
|
|
9645
9787
|
const def = p._def;
|
|
9646
9788
|
if (def.tag === "lazy") {
|
|
9647
9789
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
@@ -9658,17 +9800,17 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9658
9800
|
return;
|
|
9659
9801
|
}
|
|
9660
9802
|
active.add(p);
|
|
9661
|
-
|
|
9803
|
+
walk(resolved);
|
|
9662
9804
|
active.delete(p);
|
|
9663
9805
|
return;
|
|
9664
9806
|
}
|
|
9665
9807
|
if (isHoistableTag(def.tag)) {
|
|
9666
9808
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
9667
9809
|
}
|
|
9668
|
-
for (const child of
|
|
9810
|
+
for (const child of childrenOf3(def)) walk(child);
|
|
9669
9811
|
}
|
|
9670
9812
|
const rootsArr = [...roots];
|
|
9671
|
-
for (const root of rootsArr)
|
|
9813
|
+
for (const root of rootsArr) walk(root);
|
|
9672
9814
|
return { counts, recursive, sizes: subtreeSizes(rootsArr) };
|
|
9673
9815
|
}
|
|
9674
9816
|
function ruleDependencies(ruleMap) {
|
|
@@ -9678,7 +9820,7 @@ function ruleDependencies(ruleMap) {
|
|
|
9678
9820
|
for (const [name, comb] of ruleMap) {
|
|
9679
9821
|
const found = /* @__PURE__ */ new Set();
|
|
9680
9822
|
const seen = /* @__PURE__ */ new Set();
|
|
9681
|
-
const
|
|
9823
|
+
const walk = (p, isRoot) => {
|
|
9682
9824
|
const def = p._def;
|
|
9683
9825
|
const boundary = def.tag === "lazy" ? nameOf.get(p) ?? p._ruleName : nameOf.get(p);
|
|
9684
9826
|
if (!isRoot && boundary !== void 0) {
|
|
@@ -9694,12 +9836,12 @@ function ruleDependencies(ruleMap) {
|
|
|
9694
9836
|
} catch {
|
|
9695
9837
|
return;
|
|
9696
9838
|
}
|
|
9697
|
-
|
|
9839
|
+
walk(resolved, false);
|
|
9698
9840
|
return;
|
|
9699
9841
|
}
|
|
9700
|
-
for (const child of
|
|
9842
|
+
for (const child of childrenOf3(def)) walk(child, false);
|
|
9701
9843
|
};
|
|
9702
|
-
|
|
9844
|
+
walk(comb, true);
|
|
9703
9845
|
deps.set(name, [...found]);
|
|
9704
9846
|
}
|
|
9705
9847
|
return deps;
|
|
@@ -9848,6 +9990,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9848
9990
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
9849
9991
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9850
9992
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9993
|
+
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
9851
9994
|
const ctx = {
|
|
9852
9995
|
vars: 0,
|
|
9853
9996
|
indent: 1,
|
|
@@ -9868,7 +10011,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9868
10011
|
capturing: hasNodeDef(combinator),
|
|
9869
10012
|
recovery: opts?.recovery ?? false,
|
|
9870
10013
|
hostMode: opts?.hostMode ?? grammarHostMode ?? "ast",
|
|
9871
|
-
lineTracking: opts?.trackLines === true || hasLineTrackingDef(combinator),
|
|
10014
|
+
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9872
10015
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9873
10016
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9874
10017
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -10032,6 +10175,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10032
10175
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
10033
10176
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
10034
10177
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10178
|
+
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
10035
10179
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
10036
10180
|
const d = val._def;
|
|
10037
10181
|
if (d.tag !== "lazy") return true;
|
|
@@ -10042,6 +10186,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10042
10186
|
return false;
|
|
10043
10187
|
}
|
|
10044
10188
|
});
|
|
10189
|
+
const nodeMeta = new Map(ruleMap.map(([name, rule]) => [name, collectGrammarReflection([[name, rule]], { followLazy: false })]));
|
|
10045
10190
|
const ctx = {
|
|
10046
10191
|
vars: 0,
|
|
10047
10192
|
indent: 1,
|
|
@@ -10066,6 +10211,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10066
10211
|
capturing: opts?.captureTerminals === true || ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
10067
10212
|
recovery: opts?.recovery ?? false,
|
|
10068
10213
|
hostMode: grammarHostMode ?? "ast",
|
|
10214
|
+
lineTracking: grammarTrackLines,
|
|
10069
10215
|
...opts?.coverage ? { coverage: { plan: opts.coverage } } : {},
|
|
10070
10216
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10071
10217
|
ns,
|
|
@@ -10116,7 +10262,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10116
10262
|
scanExternal(resolved);
|
|
10117
10263
|
return;
|
|
10118
10264
|
}
|
|
10119
|
-
for (const child of
|
|
10265
|
+
for (const child of childrenOf3(def)) scanExternal(child);
|
|
10120
10266
|
};
|
|
10121
10267
|
for (const [, rule] of ruleMap) scanExternal(rule);
|
|
10122
10268
|
}
|
|
@@ -10162,6 +10308,10 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10162
10308
|
perEntry.push({ key, rule, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
10163
10309
|
}
|
|
10164
10310
|
if (ctx.runtimeParsers.length !== 0) return null;
|
|
10311
|
+
if (ctx.lineTracking) {
|
|
10312
|
+
ctx.needsLineTrack = true;
|
|
10313
|
+
ctx.needsLineSpan = true;
|
|
10314
|
+
}
|
|
10165
10315
|
const mfSrcs = ctx.mapFns.length > 0 && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : null;
|
|
10166
10316
|
const buildSrcs = ctx.buildFns.length > 0 && ctx.buildSrcs.every((s) => s !== null) ? ctx.buildSrcs : null;
|
|
10167
10317
|
const ruleFns = /* @__PURE__ */ new Map();
|
|
@@ -10175,6 +10325,8 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10175
10325
|
const mfDecl = ctx.mapFns.length === 0 ? "" : mfSrcs ? `const ${mfRef(ctx)} = [${mfSrcs.join(", ")}]` : `const ${mfRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "mf")}]`;
|
|
10176
10326
|
const buildDecl = ctx.buildFns.length === 0 ? "" : buildSrcs ? `const ${buildRef(ctx)} = [${buildSrcs.join(", ")}]` : `const ${buildRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "build")}]`;
|
|
10177
10327
|
const prelude = [
|
|
10328
|
+
ctx.needsLineTrack ? LINE_TRACK_DECL : "",
|
|
10329
|
+
ctx.needsLineSpan ? LINE_SPAN_DECL : "",
|
|
10178
10330
|
...ctx.regexDecls,
|
|
10179
10331
|
...ctx.expectedDecls,
|
|
10180
10332
|
mfDecl,
|
|
@@ -10183,11 +10335,18 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10183
10335
|
].filter(Boolean);
|
|
10184
10336
|
const wrappers = /* @__PURE__ */ new Map();
|
|
10185
10337
|
for (const { key, rule, r } of perEntry) {
|
|
10338
|
+
const linePreamble = ctx.lineTracking ? [
|
|
10339
|
+
` if (_ctx._lineStarts === undefined) _ctx = { ..._ctx, trackLines: true, _lineStarts: [0], _lineScannedTo: 0 }`,
|
|
10340
|
+
` else _ctx.trackLines = true`,
|
|
10341
|
+
` if (_pos > (_ctx._lineScannedTo ?? 0)) _trackLines(_ctx, input, 0, _pos)`
|
|
10342
|
+
] : [];
|
|
10343
|
+
const resultSpan = ctx.lineTracking ? `_spanLines(_ctx, _pos, ${r.endVar})` : `{ start: _pos, end: ${r.endVar} }`;
|
|
10186
10344
|
wrappers.set(key, publicRuleWrapperSource(rule, [
|
|
10187
10345
|
`function(input, _pos, _ctx) {`,
|
|
10346
|
+
...linePreamble,
|
|
10188
10347
|
` let pos = _pos`,
|
|
10189
10348
|
...r.stmts,
|
|
10190
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10349
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
10191
10350
|
`}`
|
|
10192
10351
|
].join("\n"), ctx.triviaKindLabels));
|
|
10193
10352
|
}
|
|
@@ -10225,6 +10384,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10225
10384
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10226
10385
|
hasDirectBuilders: ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
10227
10386
|
isRecognitionOnly: !hasSemanticReduction(ruleMap.map(([, rule]) => rule), externalRefs),
|
|
10387
|
+
nodeMeta,
|
|
10228
10388
|
mfFns: mfSrcs ? [] : ctx.mapFns,
|
|
10229
10389
|
buildFns: buildSrcs ? [] : ctx.buildFns
|
|
10230
10390
|
};
|
|
@@ -10245,7 +10405,7 @@ function hasExternalRuleRef(ruleMap) {
|
|
|
10245
10405
|
if (resolved === void 0) return p._ruleName !== void 0;
|
|
10246
10406
|
return visit(resolved);
|
|
10247
10407
|
}
|
|
10248
|
-
return
|
|
10408
|
+
return childrenOf3(def).some(visit);
|
|
10249
10409
|
};
|
|
10250
10410
|
return ruleMap.some(([, rule]) => visit(rule));
|
|
10251
10411
|
}
|
|
@@ -10267,7 +10427,7 @@ function hasSemanticReduction(roots, externalRefs) {
|
|
|
10267
10427
|
return true;
|
|
10268
10428
|
}
|
|
10269
10429
|
}
|
|
10270
|
-
return
|
|
10430
|
+
return childrenOf3(def).some(visit);
|
|
10271
10431
|
};
|
|
10272
10432
|
return roots.some(visit);
|
|
10273
10433
|
}
|
|
@@ -10340,7 +10500,7 @@ function withCtx(extra, combinator) {
|
|
|
10340
10500
|
}
|
|
10341
10501
|
|
|
10342
10502
|
// src/compiler/ir-serialize.ts
|
|
10343
|
-
function
|
|
10503
|
+
function childrenOf4(def) {
|
|
10344
10504
|
switch (def.tag) {
|
|
10345
10505
|
case "sequence":
|
|
10346
10506
|
case "choice":
|
|
@@ -10404,6 +10564,10 @@ function projectOpt(project) {
|
|
|
10404
10564
|
if (project === void 0) return void 0;
|
|
10405
10565
|
return `project: ${project}`;
|
|
10406
10566
|
}
|
|
10567
|
+
function tagsOpt(tags) {
|
|
10568
|
+
if (tags === void 0 || tags.length === 0) return void 0;
|
|
10569
|
+
return `tags: ${JSON.stringify(tags)}`;
|
|
10570
|
+
}
|
|
10407
10571
|
function matcherExpr(entry) {
|
|
10408
10572
|
switch (entry.kind) {
|
|
10409
10573
|
case "startsWith":
|
|
@@ -10617,7 +10781,7 @@ var Serializer = class {
|
|
|
10617
10781
|
if (target) this.assertNoRuleRef(target, seen);
|
|
10618
10782
|
return;
|
|
10619
10783
|
}
|
|
10620
|
-
for (const child of
|
|
10784
|
+
for (const child of childrenOf4(c._def)) this.assertNoRuleRef(child, seen);
|
|
10621
10785
|
}
|
|
10622
10786
|
/** A `rules()` map wraps each rule value in a named `lazy` proxy; the real body is
|
|
10623
10787
|
* its target (compileLinkable unwraps the same way). A ref INSIDE a body stays a
|
|
@@ -10681,7 +10845,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10681
10845
|
this.counts.set(c, (this.counts.get(c) ?? 0) + 1);
|
|
10682
10846
|
if ((this.counts.get(c) ?? 0) > 1) return;
|
|
10683
10847
|
active.add(c);
|
|
10684
|
-
for (const child of
|
|
10848
|
+
for (const child of childrenOf4(def)) this.analyze(child, active);
|
|
10685
10849
|
active.delete(c);
|
|
10686
10850
|
}
|
|
10687
10851
|
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
@@ -10798,12 +10962,14 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10798
10962
|
case "node": {
|
|
10799
10963
|
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
10800
10964
|
const projectEntry = projectOpt(def.project);
|
|
10965
|
+
const tagEntry = tagsOpt(def.tags);
|
|
10801
10966
|
const optEntries = [
|
|
10802
10967
|
...def.unwrap ? ["unwrap: true"] : [],
|
|
10803
10968
|
...def.collapse ? ["collapse: true"] : [],
|
|
10804
10969
|
...projectEntry === void 0 ? [] : [projectEntry],
|
|
10805
10970
|
...def.captureTrivia ? ["captureTrivia: true"] : [],
|
|
10806
|
-
...def.trailingTrivia ? ["trailingTrivia: true"] : []
|
|
10971
|
+
...def.trailingTrivia ? ["trailingTrivia: true"] : [],
|
|
10972
|
+
...tagEntry === void 0 ? [] : [tagEntry]
|
|
10807
10973
|
];
|
|
10808
10974
|
const opts = optEntries.length > 0 ? `, { ${optEntries.join(", ")} }` : "";
|
|
10809
10975
|
if (def.type === void 0) {
|
|
@@ -10851,15 +11017,16 @@ function normalizeCstCollapse(collapse) {
|
|
|
10851
11017
|
}
|
|
10852
11018
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10853
11019
|
}
|
|
10854
|
-
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10855
|
-
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
11020
|
+
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
11021
|
+
return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children2] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
10856
11022
|
}
|
|
10857
|
-
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
11023
|
+
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
10858
11024
|
if (typeof typeOrOptions === "string") {
|
|
10859
11025
|
return buildCstNode(typeOrOptions, children2 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
10860
11026
|
}
|
|
10861
11027
|
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
10862
|
-
const
|
|
11028
|
+
const materializeTags = typeOrOptions?.tags === true;
|
|
11029
|
+
const host = (type, children3, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children3 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
10863
11030
|
host._parsemanCstOutput = true;
|
|
10864
11031
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
10865
11032
|
return host;
|
|
@@ -10901,6 +11068,7 @@ function fusedBody(pieces) {
|
|
|
10901
11068
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
10902
11069
|
];
|
|
10903
11070
|
const wrapperEntries = [...winner].map(([k, p]) => `${JSON.stringify(k)}: ${p.wrappers.get(k)}`);
|
|
11071
|
+
const reflection = mergeGrammarReflections([...winner].map(([k, p]) => p.nodeMeta.get(k) ?? { nodes: [] }));
|
|
10904
11072
|
const { mode, elided } = hostModeOfPieces(pieces);
|
|
10905
11073
|
const rawBody = [
|
|
10906
11074
|
...lines,
|
|
@@ -10909,6 +11077,7 @@ function fusedBody(pieces) {
|
|
|
10909
11077
|
"}",
|
|
10910
11078
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_MODE.description)}), { value: ${JSON.stringify(mode)}, enumerable: false })`,
|
|
10911
11079
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_ELIDED.description)}), { value: ${JSON.stringify(elided)}, enumerable: false })`,
|
|
11080
|
+
`Object.defineProperty(_map, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`,
|
|
10912
11081
|
// …and on each rule FUNCTION, because `run(map.Rule, …)` is handed the rule, not the
|
|
10913
11082
|
// map, and would otherwise have nothing to check against. Done once at fuse time,
|
|
10914
11083
|
// before any rule has been called, so it costs nothing per parse.
|
|
@@ -11075,7 +11244,8 @@ function materializePiece(p, trivia2, captureTerminals = false, hostMode) {
|
|
|
11075
11244
|
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, {
|
|
11076
11245
|
...trivia2 ? { trivia: trivia2 } : {},
|
|
11077
11246
|
...captureTerminals ? { captureTerminals: true } : {},
|
|
11078
|
-
...hostMode ? { hostMode } : {}
|
|
11247
|
+
...hostMode ? { hostMode } : {},
|
|
11248
|
+
...p.trackLines ? { trackLines: true } : {}
|
|
11079
11249
|
});
|
|
11080
11250
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
11081
11251
|
return pieces;
|
|
@@ -12336,38 +12506,48 @@ function buildTriviaIndex(root, input = "", opts) {
|
|
|
12336
12506
|
}
|
|
12337
12507
|
|
|
12338
12508
|
// src/cst/walk.ts
|
|
12339
|
-
function
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
|
|
12346
|
-
|
|
12347
|
-
|
|
12348
|
-
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
const
|
|
12352
|
-
|
|
12353
|
-
|
|
12354
|
-
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
|
|
12509
|
+
function isCombinator(value) {
|
|
12510
|
+
return !!value && typeof value === "object" && "_def" in value && "_meta" in value && typeof value.parse === "function";
|
|
12511
|
+
}
|
|
12512
|
+
function reflectionFor(grammar) {
|
|
12513
|
+
const stamped = grammarReflectionOf(grammar);
|
|
12514
|
+
if (stamped) return stamped;
|
|
12515
|
+
const entries = Object.entries(grammar).filter((entry) => isCombinator(entry[1]));
|
|
12516
|
+
return collectGrammarReflection(entries);
|
|
12517
|
+
}
|
|
12518
|
+
function createVisitor(grammar, spec) {
|
|
12519
|
+
const reflection = reflectionFor(grammar);
|
|
12520
|
+
const typeHandlers = spec.type;
|
|
12521
|
+
const tagSpec = spec.tag;
|
|
12522
|
+
const tagHandlersByType = /* @__PURE__ */ new Map();
|
|
12523
|
+
if (tagSpec !== void 0) {
|
|
12524
|
+
for (const node2 of reflection.nodes) {
|
|
12525
|
+
const handlers = [];
|
|
12526
|
+
for (const tag of node2.tags) {
|
|
12527
|
+
const handler = tagSpec[tag];
|
|
12528
|
+
if (handler) handlers.push(handler);
|
|
12529
|
+
}
|
|
12530
|
+
if (handlers.length > 0) tagHandlersByType.set(node2.type, handlers);
|
|
12531
|
+
}
|
|
12532
|
+
}
|
|
12533
|
+
return (root, ctx = void 0) => {
|
|
12534
|
+
const go = (node2, parent) => {
|
|
12535
|
+
const descend = spec.enter ? spec.enter(node2, parent, ctx) : void 0;
|
|
12536
|
+
if (node2._tag === "node" && node2.type !== void 0) {
|
|
12537
|
+
typeHandlers?.[node2.type]?.(node2, parent, ctx);
|
|
12538
|
+
const tagHandlers = tagHandlersByType.get(node2.type);
|
|
12539
|
+
if (tagHandlers !== void 0) {
|
|
12540
|
+
for (const handler of tagHandlers) handler(node2, parent, ctx);
|
|
12365
12541
|
}
|
|
12366
12542
|
}
|
|
12367
|
-
|
|
12368
|
-
|
|
12543
|
+
const children2 = node2.children;
|
|
12544
|
+
if (descend !== false && Array.isArray(children2)) {
|
|
12545
|
+
for (const child of children2) go(child, node2);
|
|
12546
|
+
}
|
|
12547
|
+
spec.leave?.(node2, parent, ctx);
|
|
12548
|
+
};
|
|
12549
|
+
go(root, null);
|
|
12369
12550
|
};
|
|
12370
|
-
return (node2) => api.visit(node2);
|
|
12371
12551
|
}
|
|
12372
12552
|
|
|
12373
12553
|
// src/cst/offset-model.ts
|