parseman 0.47.1 → 0.48.1
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 +27 -21
- package/dist/analysis/diagnostics.js +2964 -347
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +2960 -343
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/expect.d.ts +1 -0
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/expected.d.ts +8 -0
- package/dist/combinators/expected.d.ts.map +1 -0
- package/dist/combinators/first-set.d.ts +8 -0
- 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 +4 -0
- package/dist/combinators/keywords.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/not.d.ts.map +1 -1
- package/dist/combinators/peek.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/sequence.d.ts.map +1 -1
- package/dist/combinators/trivia-skip.d.ts +16 -3
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/compiler/direct-projection.d.ts +12 -0
- package/dist/compiler/direct-projection.d.ts.map +1 -0
- package/dist/compiler/token-alphabet.d.ts +845 -5
- package/dist/compiler/token-alphabet.d.ts.map +1 -1
- package/dist/compiler/token-capability.d.ts +3 -0
- package/dist/compiler/token-capability.d.ts.map +1 -0
- package/dist/compiler/token-capability.js +3192 -0
- package/dist/compiler/token-capability.js.map +6 -0
- package/dist/cst/trivia-charscan.d.ts +3 -0
- package/dist/cst/trivia-charscan.d.ts.map +1 -1
- package/dist/cst/trivia-css-scanner.d.ts +5 -0
- package/dist/cst/trivia-css-scanner.d.ts.map +1 -0
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/index.js +2973 -343
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js +5 -1
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/index.js +2982 -352
- package/dist/plugin/index.js.map +3 -3
- package/dist/spec/index.js +325 -47
- package/dist/spec/index.js.map +3 -3
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/child-slots.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +3 -1
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts +12 -13
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/emit.d.ts.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/exec-baseline.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/index.js +2937 -311
- package/dist/table/index.js.map +3 -3
- package/dist/table/lex-body.d.ts +9 -0
- package/dist/table/lex-body.d.ts.map +1 -0
- package/dist/table/lex-program.d.ts +25 -0
- package/dist/table/lex-program.d.ts.map +1 -0
- package/dist/table/ops.d.ts +47 -11
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/program.d.ts +50 -2
- package/dist/table/program.d.ts.map +1 -1
- package/dist/table/scalar-terminal.d.ts +13 -0
- package/dist/table/scalar-terminal.d.ts.map +1 -0
- package/dist/table/site-labels.d.ts.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +11 -11
- package/src/combinators/choice.ts +10 -1
- package/src/combinators/expect.ts +1 -0
- package/src/combinators/expected.ts +17 -0
- package/src/combinators/first-set.ts +58 -5
- package/src/combinators/grammar.ts +8 -3
- package/src/combinators/keywords.ts +22 -6
- package/src/combinators/literal.ts +2 -1
- package/src/combinators/not.ts +5 -1
- package/src/combinators/peek.ts +5 -1
- package/src/combinators/regex.ts +5 -3
- package/src/combinators/repeat.ts +4 -10
- package/src/combinators/sequence.ts +17 -14
- package/src/combinators/trivia-skip.ts +46 -13
- package/src/compiler/direct-projection.ts +43 -0
- package/src/compiler/token-alphabet.ts +4316 -12
- package/src/compiler/token-capability.ts +6 -0
- package/src/cst/trivia-charscan.ts +34 -0
- package/src/cst/trivia-css-scanner.ts +142 -0
- package/src/cst/trivia-kinds.ts +3 -1
- package/src/plugin/index.ts +4 -4
- package/src/table/assemble.ts +1253 -240
- package/src/table/child-slots.ts +2 -1
- package/src/table/compile-rule-map.ts +21 -3
- package/src/table/emit-assembly.ts +335 -87
- package/src/table/emit.ts +16 -2
- package/src/table/encode.ts +248 -60
- package/src/table/exec-baseline.ts +3 -7
- package/src/table/exec.ts +134 -25
- package/src/table/lex-body.ts +30 -0
- package/src/table/lex-program.ts +431 -0
- package/src/table/ops.ts +49 -11
- package/src/table/program.ts +46 -2
- package/src/table/scalar-terminal.ts +51 -0
- package/src/table/site-labels.ts +11 -1
- package/src/table/stamp.ts +1 -1
- package/src/types.ts +1 -1
- package/src/version.ts +1 -1
- package/dist/analysis/diagnostics.cjs +0 -13824
- package/dist/analysis/diagnostics.cjs.map +0 -6
- package/dist/cli/index.cjs +0 -14925
- package/dist/cli/index.cjs.map +0 -6
- package/dist/index.cjs +0 -16391
- package/dist/index.cjs.map +0 -6
- package/dist/language-service/index.cjs +0 -1304
- package/dist/language-service/index.cjs.map +0 -6
- package/dist/oracle/index.cjs +0 -254
- package/dist/oracle/index.cjs.map +0 -6
- package/dist/plugin/index.cjs +0 -16097
- package/dist/plugin/index.cjs.map +0 -6
- package/dist/run/index.cjs +0 -577
- package/dist/run/index.cjs.map +0 -6
- package/dist/spec/index.cjs +0 -6236
- package/dist/spec/index.cjs.map +0 -6
- package/dist/table/index.cjs +0 -11463
- package/dist/table/index.cjs.map +0 -6
|
@@ -1,1304 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/language-service/index.ts
|
|
21
|
-
var language_service_exports = {};
|
|
22
|
-
__export(language_service_exports, {
|
|
23
|
-
languageService: () => languageService
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(language_service_exports);
|
|
26
|
-
|
|
27
|
-
// src/line-index.ts
|
|
28
|
-
function recordLineRange(index, input, start, end) {
|
|
29
|
-
const lineStarts = index.lineStarts;
|
|
30
|
-
for (let i = start; i < end; i++) {
|
|
31
|
-
if (input.charCodeAt(i) === 10) lineStarts.push(i + 1);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
function recordLineRangeFromContext(ctx, input, _startHint, end) {
|
|
35
|
-
if (!ctx.trackLines) return;
|
|
36
|
-
const from = ctx._lineScannedTo ?? 0;
|
|
37
|
-
if (end <= from) return;
|
|
38
|
-
const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
|
|
39
|
-
if (!index) return;
|
|
40
|
-
recordLineRange(index, input, from, end);
|
|
41
|
-
ctx._lineScannedTo = end;
|
|
42
|
-
}
|
|
43
|
-
function offsetToLineCol(index, offset) {
|
|
44
|
-
const { lineStarts } = index;
|
|
45
|
-
let lo = 0;
|
|
46
|
-
let hi = lineStarts.length - 1;
|
|
47
|
-
while (lo < hi) {
|
|
48
|
-
const mid = lo + hi + 1 >> 1;
|
|
49
|
-
if (lineStarts[mid] <= offset) lo = mid;
|
|
50
|
-
else hi = mid - 1;
|
|
51
|
-
}
|
|
52
|
-
return { line: lo + 1, col: offset - lineStarts[lo] + 1 };
|
|
53
|
-
}
|
|
54
|
-
function annotateSpan(span, index) {
|
|
55
|
-
const s = offsetToLineCol(index, span.start);
|
|
56
|
-
const e = offsetToLineCol(index, span.end);
|
|
57
|
-
return {
|
|
58
|
-
...span,
|
|
59
|
-
startLine: s.line,
|
|
60
|
-
startColumn: s.col,
|
|
61
|
-
endLine: e.line,
|
|
62
|
-
endColumn: e.col
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
function annotateSpanFromLineContext(span, ctx) {
|
|
66
|
-
if (!ctx.trackLines) return span;
|
|
67
|
-
const index = ctx._lineIndex ?? (ctx._lineStarts ? { lineStarts: ctx._lineStarts } : void 0);
|
|
68
|
-
return index ? annotateSpan(span, index) : span;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// src/cst/capture-buffer.ts
|
|
72
|
-
function cstCaptureActive(ctx) {
|
|
73
|
-
return ctx._cstBuf !== void 0 || ctx._cstLeaves !== void 0;
|
|
74
|
-
}
|
|
75
|
-
function pushCstChild(ctx, built, rawEntry2) {
|
|
76
|
-
const b = ctx._cstBuf;
|
|
77
|
-
if (b) {
|
|
78
|
-
if (b.rawOnly !== true) {
|
|
79
|
-
if (b.ch) b.ch.push(built);
|
|
80
|
-
else if (b.single !== void 0) {
|
|
81
|
-
b.ch = [b.single, built];
|
|
82
|
-
b.single = void 0;
|
|
83
|
-
} else b.single = built;
|
|
84
|
-
}
|
|
85
|
-
if (b.raw) b.raw.push(rawEntry2);
|
|
86
|
-
else if (b.rawSingle !== void 0) {
|
|
87
|
-
b.raw = [b.rawSingle, rawEntry2];
|
|
88
|
-
b.rawSingle = void 0;
|
|
89
|
-
} else b.rawSingle = rawEntry2;
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
if (ctx._cstChildren) ctx._cstChildren.push(built);
|
|
93
|
-
else if (ctx._cstLeaves) ctx._cstLeaves.push(built);
|
|
94
|
-
if (ctx._cstRawChildren) ctx._cstRawChildren.push(rawEntry2);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// src/recovery/scan.ts
|
|
98
|
-
function probeAt(sentinel, input, pos, ctx) {
|
|
99
|
-
const s = {
|
|
100
|
-
_probe: ctx._probe,
|
|
101
|
-
_errors: ctx._errors,
|
|
102
|
-
_cstLeaves: ctx._cstLeaves,
|
|
103
|
-
_cstChildren: ctx._cstChildren,
|
|
104
|
-
_cstRawChildren: ctx._cstRawChildren,
|
|
105
|
-
_cstTriviaLog: ctx._cstTriviaLog,
|
|
106
|
-
_triviaLog: ctx._triviaLog,
|
|
107
|
-
_rootTriviaLog: ctx._rootTriviaLog,
|
|
108
|
-
_fields: ctx._fields,
|
|
109
|
-
_cstBuf: ctx._cstBuf,
|
|
110
|
-
_tolerant: ctx._tolerant,
|
|
111
|
-
_sync: ctx._sync
|
|
112
|
-
};
|
|
113
|
-
ctx._probe = void 0;
|
|
114
|
-
ctx._errors = void 0;
|
|
115
|
-
ctx._cstLeaves = void 0;
|
|
116
|
-
ctx._cstChildren = void 0;
|
|
117
|
-
ctx._cstRawChildren = void 0;
|
|
118
|
-
ctx._cstTriviaLog = void 0;
|
|
119
|
-
ctx._triviaLog = void 0;
|
|
120
|
-
ctx._rootTriviaLog = void 0;
|
|
121
|
-
ctx._fields = void 0;
|
|
122
|
-
ctx._cstBuf = void 0;
|
|
123
|
-
ctx._tolerant = void 0;
|
|
124
|
-
ctx._sync = void 0;
|
|
125
|
-
try {
|
|
126
|
-
return sentinel.parse(input, pos, ctx).ok;
|
|
127
|
-
} finally {
|
|
128
|
-
ctx._probe = s._probe;
|
|
129
|
-
ctx._errors = s._errors;
|
|
130
|
-
ctx._cstLeaves = s._cstLeaves;
|
|
131
|
-
ctx._cstChildren = s._cstChildren;
|
|
132
|
-
ctx._cstRawChildren = s._cstRawChildren;
|
|
133
|
-
ctx._cstTriviaLog = s._cstTriviaLog;
|
|
134
|
-
ctx._triviaLog = s._triviaLog;
|
|
135
|
-
ctx._rootTriviaLog = s._rootTriviaLog;
|
|
136
|
-
ctx._fields = s._fields;
|
|
137
|
-
ctx._cstBuf = s._cstBuf;
|
|
138
|
-
ctx._tolerant = s._tolerant;
|
|
139
|
-
ctx._sync = s._sync;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
function orSentinel(a, b) {
|
|
143
|
-
if (b === void 0) return a;
|
|
144
|
-
return {
|
|
145
|
-
_tag: "orSentinel",
|
|
146
|
-
_meta: { firstSet: { kind: "any" }, canMatchNewline: false, isTrivia: false },
|
|
147
|
-
_def: { tag: "unknown" },
|
|
148
|
-
parse(input, pos, ctx) {
|
|
149
|
-
const ra = a.parse(input, pos, ctx);
|
|
150
|
-
if (ra.ok) return ra;
|
|
151
|
-
return b.parse(input, pos, ctx);
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
function firstSetSentinel(fs) {
|
|
156
|
-
if (fs.kind !== "ranges" || fs.ranges.length === 0) return null;
|
|
157
|
-
const ranges = fs.ranges;
|
|
158
|
-
return {
|
|
159
|
-
_tag: "firstSetSentinel",
|
|
160
|
-
_meta: { firstSet: fs, canMatchNewline: false, isTrivia: false },
|
|
161
|
-
_def: { tag: "unknown" },
|
|
162
|
-
parse(input, pos) {
|
|
163
|
-
const code = pos < input.length ? input.codePointAt(pos) : void 0;
|
|
164
|
-
if (code !== void 0) {
|
|
165
|
-
for (const r of ranges) {
|
|
166
|
-
if (code >= r.lo && code <= r.hi) return { ok: true, value: null, span: { start: pos, end: pos } };
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return { ok: false, expected: [], span: { start: pos, end: pos } };
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
function recoverScan(input, from, ctx, sync, expected) {
|
|
174
|
-
let scanPos = from;
|
|
175
|
-
while (scanPos < input.length && !probeAt(sync, input, scanPos, ctx)) scanPos++;
|
|
176
|
-
const span = { start: from, end: scanPos };
|
|
177
|
-
if (ctx.trackLines) recordLineRangeFromContext(ctx, input, from, scanPos);
|
|
178
|
-
const error = { _tag: "parseError", span: ctx.trackLines ? annotateSpanFromLineContext(span, ctx) : span, expected };
|
|
179
|
-
ctx._errors?.push(error);
|
|
180
|
-
return { error, end: scanPos };
|
|
181
|
-
}
|
|
182
|
-
function matchesAt(sentinel, input, pos, ctx) {
|
|
183
|
-
return probeAt(sentinel, input, pos, ctx);
|
|
184
|
-
}
|
|
185
|
-
function captureError(ctx, error) {
|
|
186
|
-
if (cstCaptureActive(ctx)) pushCstChild(ctx, error, error);
|
|
187
|
-
}
|
|
188
|
-
var REC = { scan: recoverScan, at: matchesAt, or: orSentinel, sentinel: firstSetSentinel, capture: captureError };
|
|
189
|
-
|
|
190
|
-
// src/parse-context.ts
|
|
191
|
-
function createParseContext() {
|
|
192
|
-
return {
|
|
193
|
-
trivia: void 0,
|
|
194
|
-
scanSkip: void 0,
|
|
195
|
-
triviaKindLabels: void 0,
|
|
196
|
-
captureTrivia: void 0,
|
|
197
|
-
_triviaCaptureMask: void 0,
|
|
198
|
-
trackLines: false,
|
|
199
|
-
state: void 0,
|
|
200
|
-
build: void 0,
|
|
201
|
-
_errors: void 0,
|
|
202
|
-
_tolerant: void 0,
|
|
203
|
-
_sync: void 0,
|
|
204
|
-
_rec: void 0,
|
|
205
|
-
_fe: void 0,
|
|
206
|
-
_fx: void 0,
|
|
207
|
-
_fc: void 0,
|
|
208
|
-
_probe: void 0,
|
|
209
|
-
_cstChildren: void 0,
|
|
210
|
-
_cstLeaves: void 0,
|
|
211
|
-
_cstRawChildren: void 0,
|
|
212
|
-
_triviaLog: void 0,
|
|
213
|
-
_rootTriviaLog: void 0,
|
|
214
|
-
_rootTriviaKindIndex: void 0,
|
|
215
|
-
_rootTriviaStrictScopes: void 0,
|
|
216
|
-
_rootTriviaCapture: void 0,
|
|
217
|
-
_cstTriviaLog: void 0,
|
|
218
|
-
_fields: void 0,
|
|
219
|
-
_cstBuf: void 0,
|
|
220
|
-
_routed: void 0,
|
|
221
|
-
_lineStarts: void 0,
|
|
222
|
-
_lineIndex: void 0,
|
|
223
|
-
_lineScannedTo: void 0,
|
|
224
|
-
_grammarCoverage: void 0,
|
|
225
|
-
_grammarTrace: void 0
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// src/cst/trivia-entries.ts
|
|
230
|
-
var EMPTY_INDICES = Object.freeze([]);
|
|
231
|
-
var EMPTY_GAPS = Object.freeze([]);
|
|
232
|
-
var SELECTED_ROOT_STRIDE = 5;
|
|
233
|
-
function buildRootTriviaIndex(log, labels) {
|
|
234
|
-
const length = Math.floor(log.length / SELECTED_ROOT_STRIDE);
|
|
235
|
-
const markerOffset = (i) => i * SELECTED_ROOT_STRIDE;
|
|
236
|
-
const ownedRangeStart = (i) => log[markerOffset(i)];
|
|
237
|
-
const ownedRangeEnd = (i) => log[markerOffset(i) + 1];
|
|
238
|
-
const markerStart = (i) => log[markerOffset(i) + 2];
|
|
239
|
-
const markerEnd = (i) => log[markerOffset(i) + 3];
|
|
240
|
-
const markerKind = (i) => log[markerOffset(i) + 4];
|
|
241
|
-
const entries = {
|
|
242
|
-
length,
|
|
243
|
-
labels,
|
|
244
|
-
stride: SELECTED_ROOT_STRIDE,
|
|
245
|
-
start: markerStart,
|
|
246
|
-
end: markerEnd,
|
|
247
|
-
insertIndex: () => void 0,
|
|
248
|
-
kindIndex: markerKind,
|
|
249
|
-
kind(i) {
|
|
250
|
-
return labels[markerKind(i)];
|
|
251
|
-
},
|
|
252
|
-
text(i, input) {
|
|
253
|
-
return input.slice(markerStart(i), markerEnd(i));
|
|
254
|
-
}
|
|
255
|
-
};
|
|
256
|
-
const lowerBound = (offset, by) => {
|
|
257
|
-
let lo = 0;
|
|
258
|
-
let hi = length;
|
|
259
|
-
while (lo < hi) {
|
|
260
|
-
const mid = lo + hi >>> 1;
|
|
261
|
-
if (by(mid) < offset) lo = mid + 1;
|
|
262
|
-
else hi = mid;
|
|
263
|
-
}
|
|
264
|
-
return lo;
|
|
265
|
-
};
|
|
266
|
-
const gapRowsAt = (offset, direction) => {
|
|
267
|
-
const edge = direction === "before" ? ownedRangeEnd : ownedRangeStart;
|
|
268
|
-
let first = lowerBound(offset, edge);
|
|
269
|
-
if (first === length || edge(first) !== offset) return void 0;
|
|
270
|
-
const start = ownedRangeStart(first);
|
|
271
|
-
const end = ownedRangeEnd(first);
|
|
272
|
-
while (first > 0 && ownedRangeStart(first - 1) === start && ownedRangeEnd(first - 1) === end) first--;
|
|
273
|
-
let last = first + 1;
|
|
274
|
-
while (last < length && ownedRangeStart(last) === start && ownedRangeEnd(last) === end) last++;
|
|
275
|
-
return [first, last];
|
|
276
|
-
};
|
|
277
|
-
const indices = (first, last) => {
|
|
278
|
-
const out = [];
|
|
279
|
-
for (let i = first; i < last; i++) out.push(i);
|
|
280
|
-
return out;
|
|
281
|
-
};
|
|
282
|
-
const makeGap = (first, last) => {
|
|
283
|
-
const start = ownedRangeStart(first);
|
|
284
|
-
const end = ownedRangeEnd(first);
|
|
285
|
-
let entryIndices;
|
|
286
|
-
return {
|
|
287
|
-
start,
|
|
288
|
-
end,
|
|
289
|
-
get entryIndices() {
|
|
290
|
-
return entryIndices ??= indices(first, last);
|
|
291
|
-
},
|
|
292
|
-
hasKind(kind) {
|
|
293
|
-
for (let i = first; i < last; i++) {
|
|
294
|
-
if (labels[markerKind(i)] === kind) return true;
|
|
295
|
-
}
|
|
296
|
-
return false;
|
|
297
|
-
},
|
|
298
|
-
text(input) {
|
|
299
|
-
return input.slice(start, end);
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
};
|
|
303
|
-
let maps;
|
|
304
|
-
const getMaps = () => {
|
|
305
|
-
if (maps !== void 0) return maps;
|
|
306
|
-
const before = /* @__PURE__ */ new Map();
|
|
307
|
-
const after = /* @__PURE__ */ new Map();
|
|
308
|
-
const beforeGaps = /* @__PURE__ */ new Map();
|
|
309
|
-
const afterGaps = /* @__PURE__ */ new Map();
|
|
310
|
-
const gaps = [];
|
|
311
|
-
for (let first = 0; first < length; ) {
|
|
312
|
-
let last = first + 1;
|
|
313
|
-
while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
|
|
314
|
-
const gap = makeGap(first, last);
|
|
315
|
-
gaps.push(gap);
|
|
316
|
-
afterGaps.set(gap.start, gap);
|
|
317
|
-
beforeGaps.set(gap.end, gap);
|
|
318
|
-
after.set(gap.start, [...gap.entryIndices]);
|
|
319
|
-
before.set(gap.end, [...gap.entryIndices]);
|
|
320
|
-
first = last;
|
|
321
|
-
}
|
|
322
|
-
maps = { before, after, beforeGaps, afterGaps, gaps };
|
|
323
|
-
return maps;
|
|
324
|
-
};
|
|
325
|
-
return {
|
|
326
|
-
entries,
|
|
327
|
-
labels,
|
|
328
|
-
get before() {
|
|
329
|
-
return getMaps().before;
|
|
330
|
-
},
|
|
331
|
-
get after() {
|
|
332
|
-
return getMaps().after;
|
|
333
|
-
},
|
|
334
|
-
entryIndicesBefore(offset) {
|
|
335
|
-
const rows = gapRowsAt(offset, "before");
|
|
336
|
-
return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
|
|
337
|
-
},
|
|
338
|
-
entryIndicesAfter(offset) {
|
|
339
|
-
const rows = gapRowsAt(offset, "after");
|
|
340
|
-
return rows ? indices(rows[0], rows[1]) : EMPTY_INDICES;
|
|
341
|
-
},
|
|
342
|
-
gapBefore(offset) {
|
|
343
|
-
const rows = gapRowsAt(offset, "before");
|
|
344
|
-
return rows ? makeGap(rows[0], rows[1]) : void 0;
|
|
345
|
-
},
|
|
346
|
-
gapAfter(offset) {
|
|
347
|
-
const rows = gapRowsAt(offset, "after");
|
|
348
|
-
return rows ? makeGap(rows[0], rows[1]) : void 0;
|
|
349
|
-
},
|
|
350
|
-
gaps() {
|
|
351
|
-
return getMaps().gaps;
|
|
352
|
-
},
|
|
353
|
-
gapsWithKind(kind) {
|
|
354
|
-
const kinds = typeof kind === "string" ? [kind] : kind;
|
|
355
|
-
const matches2 = [];
|
|
356
|
-
for (let first = 0; first < length; ) {
|
|
357
|
-
let last = first + 1;
|
|
358
|
-
while (last < length && ownedRangeStart(last) === ownedRangeStart(first) && ownedRangeEnd(last) === ownedRangeEnd(first)) last++;
|
|
359
|
-
let matched = false;
|
|
360
|
-
for (let i = first; i < last && !matched; i++) {
|
|
361
|
-
const label2 = labels[markerKind(i)];
|
|
362
|
-
for (const kind2 of kinds) {
|
|
363
|
-
if (label2 === kind2) {
|
|
364
|
-
matched = true;
|
|
365
|
-
break;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
if (matched) matches2.push(makeGap(first, last));
|
|
370
|
-
first = last;
|
|
371
|
-
}
|
|
372
|
-
return matches2.length === 0 ? EMPTY_GAPS : matches2;
|
|
373
|
-
}
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// src/cst/host-mode.ts
|
|
378
|
-
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
379
|
-
var FUSED_HOST_ELIDED = /* @__PURE__ */ Symbol.for("parseman.fusedHostElided");
|
|
380
|
-
function assertHostModeCompatible(mode, build, hostBranchElided = true) {
|
|
381
|
-
const isCstHost = build?._parsemanCstOutput === true;
|
|
382
|
-
if (mode === "ast" && isCstHost && hostBranchElided) {
|
|
383
|
-
throw new Error(
|
|
384
|
-
"parseman: this parser was compiled for host mode \"ast\" (the default), so its nodes build through their own `build` callbacks and no positioned-CST branch was emitted. It cannot be driven with a positioned-CST host (cstBuildHost / a language-service host). Compile a second artifact from the SAME grammar with `compile(grammar, { hostMode: 'cst' })` \u2014 or, under the macro, a second `rules({ hostMode: 'cst' }, factory)` call site \u2014 and drive that one instead."
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
if (mode === "cst" && !isCstHost) {
|
|
388
|
-
throw new Error(
|
|
389
|
-
'parseman: this parser was compiled for host mode "cst", so every node builds through a positioned-CST `ctx.build` host. Pass one (e.g. `{ build: cstBuildHost }`), or use an artifact compiled with the default `hostMode: "ast"` to get the grammar\'s own AST.'
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
// src/functional/run.ts
|
|
395
|
-
var SELECT_EXAMPLE = "run(entry, input, { rootTrivia: { select: ['blockComment', 'lineComment'] } })";
|
|
396
|
-
var REMOVED_RUN_RESULT_FIELDS = [
|
|
397
|
-
[
|
|
398
|
-
"triviaMap",
|
|
399
|
-
`It was a dense root-trivia index built on every parse; root trivia is now an OPT-IN sparse capture, because most grammars paid for an index they never read. Migration: name the trivia labels your grammar defines \u2014 ${SELECT_EXAMPLE} \u2014 and read \`RunResult.rootTrivia\`, whose \`.index\` carries the labels and gap lookups \`triviaMap\` exposed.`
|
|
400
|
-
],
|
|
401
|
-
[
|
|
402
|
-
"triviaLog",
|
|
403
|
-
`It was the flat \`start, end[, kindIndex]\` log every other trivia view was derived from, and it is no longer allocated at all \u2014 not empty, absent. Migration: request the labels you need \u2014 ${SELECT_EXAMPLE} \u2014 and read \`RunResult.rootTrivia.rows\`. Do NOT reuse a stride-2/3 reader: rows are a different width and a different unit (one row per SELECTED marker, not one per trivia chunk), so an old loop reads confidently wrong offsets rather than failing.`
|
|
404
|
-
],
|
|
405
|
-
[
|
|
406
|
-
"triviaKindLabels",
|
|
407
|
-
`It was already optional, so nothing ever flagged its disappearance \u2014 and \`triviaKindMask(undefined, \u2026)\` means "capture everything", so reading it now silently WIDENS capture instead of erroring. Migration: request labels \u2014 ${SELECT_EXAMPLE} \u2014 then the set you asked for is \`RunResult.rootTrivia.select\` and the resolved table is \`RunResult.rootTrivia.index.labels\`.`
|
|
408
|
-
]
|
|
409
|
-
];
|
|
410
|
-
var RunResultRecord = class {
|
|
411
|
-
constructor(ok, value, span, expected, errors, unconsumedFrom) {
|
|
412
|
-
this.ok = ok;
|
|
413
|
-
this.value = value;
|
|
414
|
-
this.span = span;
|
|
415
|
-
this.expected = expected;
|
|
416
|
-
this.errors = errors;
|
|
417
|
-
this.unconsumedFrom = unconsumedFrom;
|
|
418
|
-
}
|
|
419
|
-
};
|
|
420
|
-
var RunResultWithRootTrivia = class {
|
|
421
|
-
constructor(ok, value, span, expected, errors, rootTrivia, unconsumedFrom) {
|
|
422
|
-
this.ok = ok;
|
|
423
|
-
this.value = value;
|
|
424
|
-
this.span = span;
|
|
425
|
-
this.expected = expected;
|
|
426
|
-
this.errors = errors;
|
|
427
|
-
this.rootTrivia = rootTrivia;
|
|
428
|
-
this.unconsumedFrom = unconsumedFrom;
|
|
429
|
-
}
|
|
430
|
-
};
|
|
431
|
-
for (const proto of [RunResultRecord.prototype, RunResultWithRootTrivia.prototype]) {
|
|
432
|
-
for (const [name, detail] of REMOVED_RUN_RESULT_FIELDS) {
|
|
433
|
-
Object.defineProperty(proto, name, {
|
|
434
|
-
configurable: true,
|
|
435
|
-
enumerable: false,
|
|
436
|
-
get() {
|
|
437
|
-
throw new TypeError(
|
|
438
|
-
`RunResult.${name} was REMOVED in parseman 0.44.0 and has no default replacement. ${detail}`
|
|
439
|
-
);
|
|
440
|
-
}
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
var invoke = (r, input, pos, ctx) => typeof r === "function" ? r(input, pos, ctx) : r.parse(input, pos, ctx);
|
|
445
|
-
function ambientTriviaFromRunnable(r) {
|
|
446
|
-
if (!r) return void 0;
|
|
447
|
-
if (typeof r === "function") return r._meta?.grammarTrivia;
|
|
448
|
-
if (r._meta.isTrivia) return void 0;
|
|
449
|
-
return r._meta.grammarTrivia ?? (r._def.tag === "grammar" ? r._def.triviaParser : void 0);
|
|
450
|
-
}
|
|
451
|
-
function triviaKindLabelsFromRunnable(r) {
|
|
452
|
-
if (!r) return void 0;
|
|
453
|
-
if (typeof r === "function") return r._meta?.triviaKindLabels;
|
|
454
|
-
const grammarTrivia = r._meta.grammarTrivia;
|
|
455
|
-
return grammarTrivia?._meta.triviaKindLabels ?? r._meta.triviaKindLabels ?? (r._def.tag === "grammar" ? r._def.triviaParser?._meta.triviaKindLabels : void 0);
|
|
456
|
-
}
|
|
457
|
-
function rootTriviaClassifiedFromRunnable(r) {
|
|
458
|
-
if (!r) return false;
|
|
459
|
-
if (typeof r === "function") return r._meta?.rootTriviaClassified === true;
|
|
460
|
-
const grammarTrivia = r._meta.grammarTrivia;
|
|
461
|
-
return grammarTrivia?._meta.rootTriviaClassified === true || r._meta.rootTriviaClassified === true;
|
|
462
|
-
}
|
|
463
|
-
function makeSelectedRootLabelIndex(labels) {
|
|
464
|
-
const index = /* @__PURE__ */ Object.create(null);
|
|
465
|
-
for (let i = 0; i < labels.length; i++) {
|
|
466
|
-
if (index[labels[i]] === void 0) index[labels[i]] = i;
|
|
467
|
-
}
|
|
468
|
-
return index;
|
|
469
|
-
}
|
|
470
|
-
function growSpanEnd(span, input, end) {
|
|
471
|
-
if (span.endLine === void 0 || span.endColumn === void 0) {
|
|
472
|
-
return { start: span.start, end };
|
|
473
|
-
}
|
|
474
|
-
let line = span.endLine;
|
|
475
|
-
let column = span.endColumn;
|
|
476
|
-
for (let i = span.end; i < end; i++) {
|
|
477
|
-
if (input.charCodeAt(i) === 10) {
|
|
478
|
-
line++;
|
|
479
|
-
column = 1;
|
|
480
|
-
} else {
|
|
481
|
-
column++;
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
return { ...span, end, endLine: line, endColumn: column };
|
|
485
|
-
}
|
|
486
|
-
function runOnce(entry, input, options) {
|
|
487
|
-
if (typeof entry !== "function" && typeof entry?.parse !== "function") {
|
|
488
|
-
throw new TypeError(
|
|
489
|
-
`run(): start production is ${entry === null ? "null" : typeof entry}, not a rule \u2014 the requested grammar rule does not exist (check the rule name).`
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
const rootTriviaSelection = options.rootTrivia?.select;
|
|
493
|
-
const captureRootTrivia = rootTriviaSelection !== void 0 && rootTriviaSelection.length > 0;
|
|
494
|
-
const selectedRootLog = captureRootTrivia ? [] : void 0;
|
|
495
|
-
const selectedRootLabelIndex = captureRootTrivia ? makeSelectedRootLabelIndex(rootTriviaSelection) : void 0;
|
|
496
|
-
const errors = [];
|
|
497
|
-
const grammarTrivia = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
|
|
498
|
-
const grammarScanSkip = typeof entry !== "function" ? entry._meta.grammarScanSkip : void 0;
|
|
499
|
-
const triviaKindLabels = triviaKindLabelsFromRunnable(entry) ?? triviaKindLabelsFromRunnable(options.trivia);
|
|
500
|
-
if (captureRootTrivia && triviaKindLabels === void 0) {
|
|
501
|
-
throw new TypeError("run(): rootTrivia.select requires labeled grammar trivia.");
|
|
502
|
-
}
|
|
503
|
-
if (captureRootTrivia) {
|
|
504
|
-
for (const label2 of rootTriviaSelection) {
|
|
505
|
-
if (!triviaKindLabels.includes(label2)) {
|
|
506
|
-
throw new TypeError(`run(): rootTrivia.select contains unknown trivia label ${JSON.stringify(label2)}.`);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
if (captureRootTrivia && !rootTriviaClassifiedFromRunnable(entry) && !rootTriviaClassifiedFromRunnable(options.trivia)) {
|
|
511
|
-
throw new TypeError(
|
|
512
|
-
"run(): rootTrivia.select requires classifiedTrivia() at the root."
|
|
513
|
-
);
|
|
514
|
-
}
|
|
515
|
-
const stamped = entry;
|
|
516
|
-
assertHostModeCompatible(
|
|
517
|
-
typeof entry === "function" ? stamped[FUSED_HOST_MODE] ?? "ast" : entry._meta.grammarHostMode ?? "ast",
|
|
518
|
-
options.build,
|
|
519
|
-
typeof entry === "function" && stamped[FUSED_HOST_ELIDED] === true
|
|
520
|
-
);
|
|
521
|
-
const ctx = createParseContext();
|
|
522
|
-
if (captureRootTrivia) {
|
|
523
|
-
ctx._rootTriviaLog = selectedRootLog;
|
|
524
|
-
ctx._rootTriviaKindIndex = selectedRootLabelIndex;
|
|
525
|
-
ctx._rootTriviaStrictScopes = true;
|
|
526
|
-
}
|
|
527
|
-
ctx._errors = errors;
|
|
528
|
-
ctx.build = options.build;
|
|
529
|
-
ctx.state = options.state;
|
|
530
|
-
if (grammarTrivia !== void 0) ctx.trivia = grammarTrivia;
|
|
531
|
-
if (triviaKindLabels) ctx.triviaKindLabels = triviaKindLabels;
|
|
532
|
-
if (grammarScanSkip !== void 0) ctx.scanSkip = grammarScanSkip;
|
|
533
|
-
if (options.triviaCaptureMask !== void 0) ctx._triviaCaptureMask = options.triviaCaptureMask;
|
|
534
|
-
if (options.tolerant) {
|
|
535
|
-
ctx._tolerant = true;
|
|
536
|
-
ctx._rec = REC;
|
|
537
|
-
}
|
|
538
|
-
if (options.instrumentation !== void 0) {
|
|
539
|
-
ctx._grammarCoverage = options.instrumentation._grammarCoverage;
|
|
540
|
-
ctx._grammarTrace = options.instrumentation._grammarTrace;
|
|
541
|
-
}
|
|
542
|
-
const r = invoke(entry, input, 0, ctx);
|
|
543
|
-
const value = r.ok ? r.value : void 0;
|
|
544
|
-
let span = r.span ?? { start: 0, end: 0 };
|
|
545
|
-
const expected = r.ok ? [] : r.expected ?? [];
|
|
546
|
-
let unconsumedFrom = null;
|
|
547
|
-
if (r.ok) {
|
|
548
|
-
let pos = span.end;
|
|
549
|
-
const tail = options.trivia ?? ambientTriviaFromRunnable(entry);
|
|
550
|
-
if (tail !== void 0 && pos < input.length) {
|
|
551
|
-
const t = invoke(tail, input, pos, createParseContext());
|
|
552
|
-
if (t.ok && t.span.end > pos) {
|
|
553
|
-
span = growSpanEnd(span, input, t.span.end);
|
|
554
|
-
pos = t.span.end;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
unconsumedFrom = pos < input.length ? pos : null;
|
|
558
|
-
}
|
|
559
|
-
return selectedRootLog !== void 0 && selectedRootLog.length > 0 ? new RunResultWithRootTrivia(
|
|
560
|
-
r.ok,
|
|
561
|
-
value,
|
|
562
|
-
span,
|
|
563
|
-
expected,
|
|
564
|
-
errors,
|
|
565
|
-
{
|
|
566
|
-
rows: selectedRootLog,
|
|
567
|
-
select: rootTriviaSelection,
|
|
568
|
-
index: buildRootTriviaIndex(selectedRootLog, rootTriviaSelection)
|
|
569
|
-
},
|
|
570
|
-
unconsumedFrom
|
|
571
|
-
) : new RunResultRecord(r.ok, value, span, expected, errors, unconsumedFrom);
|
|
572
|
-
}
|
|
573
|
-
function run(entry, input, options = {}) {
|
|
574
|
-
return runOnce(entry, input, options);
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
// src/combinators/completions.ts
|
|
578
|
-
function completionsAt(target, input, offset, options = {}) {
|
|
579
|
-
const probe = { offset, best: null };
|
|
580
|
-
const ctx = createParseContext();
|
|
581
|
-
ctx._probe = probe;
|
|
582
|
-
if (options.tolerant) {
|
|
583
|
-
ctx._tolerant = true;
|
|
584
|
-
ctx._rec = REC;
|
|
585
|
-
}
|
|
586
|
-
const sliced = input.slice(0, offset);
|
|
587
|
-
const result = "parseWithContext" in target ? target.parseWithContext(sliced, ctx, 0) : target.parse(sliced, 0, ctx);
|
|
588
|
-
if (result.ok) return options.tolerant ? probe.best?.expected ?? [] : [];
|
|
589
|
-
const best = deeperFail(probe.best, result);
|
|
590
|
-
return best?.expected ?? [];
|
|
591
|
-
}
|
|
592
|
-
function deeperFail(a, b) {
|
|
593
|
-
if (!a) return b;
|
|
594
|
-
if (!b) return a;
|
|
595
|
-
return a.span.start >= b.span.start ? a : b;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// src/regex/classes.ts
|
|
599
|
-
var META = new Set("()[]{}*+?|^$.".split(""));
|
|
600
|
-
|
|
601
|
-
// src/table/ops.ts
|
|
602
|
-
var OP_LIT = 1;
|
|
603
|
-
var OP_RX = 2;
|
|
604
|
-
var OP_SEQ = 3;
|
|
605
|
-
var OP_SEQV = 4;
|
|
606
|
-
var OP_CHOICE = 5;
|
|
607
|
-
var OP_REP = 6;
|
|
608
|
-
var OP_REPV = 7;
|
|
609
|
-
var OP_OPT = 8;
|
|
610
|
-
var OP_XFORM = 9;
|
|
611
|
-
var OP_NODE = 10;
|
|
612
|
-
var OP_RULE = 11;
|
|
613
|
-
var OP_GATE = 12;
|
|
614
|
-
var OP_NOT = 13;
|
|
615
|
-
var OP_PEEK = 14;
|
|
616
|
-
var OP_LEAF = 15;
|
|
617
|
-
var OP_EMPTY = 16;
|
|
618
|
-
var OP_LIT_TRACK = 17;
|
|
619
|
-
var OP_RX_TRACK = 18;
|
|
620
|
-
var OP_NODE_TRACK = 19;
|
|
621
|
-
var OP_SCOPE = 20;
|
|
622
|
-
var OP_EXPECT = 21;
|
|
623
|
-
var OP_SEQX = 22;
|
|
624
|
-
var OP_SCAN = 23;
|
|
625
|
-
var OP_FIELD = 24;
|
|
626
|
-
var OP_LIT_CI = 27;
|
|
627
|
-
var OP_LIT_CI_TRACK = 28;
|
|
628
|
-
var OP_TOKEN = 29;
|
|
629
|
-
var OP_SCOPE_CAP = 30;
|
|
630
|
-
var OP_WITHCTX = 31;
|
|
631
|
-
var OP_GUARD = 32;
|
|
632
|
-
var OP_ADJ = 33;
|
|
633
|
-
var OP_GREEDY = 34;
|
|
634
|
-
var OP_REJECT = 35;
|
|
635
|
-
var OP_ARMGATE = 36;
|
|
636
|
-
var OP_LIVE = 37;
|
|
637
|
-
var OP_ATTEMPT = 38;
|
|
638
|
-
var OP_LABEL = 39;
|
|
639
|
-
var OP_COV = 40;
|
|
640
|
-
var OP_SCOPE_PLAIN = 41;
|
|
641
|
-
var OP_DISPATCH = 25;
|
|
642
|
-
var OP_ROUTED = 26;
|
|
643
|
-
var OP_NAMES = {
|
|
644
|
-
[OP_LIT]: "LIT",
|
|
645
|
-
[OP_RX]: "RX",
|
|
646
|
-
[OP_SEQ]: "SEQ",
|
|
647
|
-
[OP_SEQV]: "SEQV",
|
|
648
|
-
[OP_CHOICE]: "CHOICE",
|
|
649
|
-
[OP_REP]: "REP",
|
|
650
|
-
[OP_REPV]: "REPV",
|
|
651
|
-
[OP_OPT]: "OPT",
|
|
652
|
-
[OP_XFORM]: "XFORM",
|
|
653
|
-
[OP_NODE]: "NODE",
|
|
654
|
-
[OP_RULE]: "RULE",
|
|
655
|
-
[OP_GATE]: "GATE",
|
|
656
|
-
[OP_NOT]: "NOT",
|
|
657
|
-
[OP_PEEK]: "PEEK",
|
|
658
|
-
[OP_LEAF]: "LEAF",
|
|
659
|
-
[OP_EMPTY]: "EMPTY",
|
|
660
|
-
[OP_LIT_TRACK]: "LIT_TRACK",
|
|
661
|
-
[OP_RX_TRACK]: "RX_TRACK",
|
|
662
|
-
[OP_NODE_TRACK]: "NODE_TRACK",
|
|
663
|
-
[OP_SCOPE]: "SCOPE",
|
|
664
|
-
[OP_EXPECT]: "EXPECT",
|
|
665
|
-
[OP_SEQX]: "SEQX",
|
|
666
|
-
[OP_SCAN]: "SCAN",
|
|
667
|
-
[OP_FIELD]: "FIELD",
|
|
668
|
-
[OP_LIT_CI]: "LIT_CI",
|
|
669
|
-
[OP_LIT_CI_TRACK]: "LIT_CI_TRACK",
|
|
670
|
-
[OP_DISPATCH]: "DISPATCH",
|
|
671
|
-
[OP_ROUTED]: "ROUTED",
|
|
672
|
-
[OP_TOKEN]: "TOKEN",
|
|
673
|
-
[OP_SCOPE_CAP]: "SCOPE_CAP",
|
|
674
|
-
[OP_WITHCTX]: "WITHCTX",
|
|
675
|
-
[OP_GUARD]: "GUARD",
|
|
676
|
-
[OP_ADJ]: "ADJ",
|
|
677
|
-
[OP_GREEDY]: "GREEDY",
|
|
678
|
-
[OP_REJECT]: "REJECT",
|
|
679
|
-
[OP_ARMGATE]: "ARMGATE",
|
|
680
|
-
[OP_LIVE]: "LIVE",
|
|
681
|
-
[OP_ATTEMPT]: "ATTEMPT",
|
|
682
|
-
[OP_LABEL]: "LABEL",
|
|
683
|
-
[OP_COV]: "COV",
|
|
684
|
-
[OP_SCOPE_PLAIN]: "SCOPE_PLAIN"
|
|
685
|
-
};
|
|
686
|
-
|
|
687
|
-
// src/table/scan-shapes.ts
|
|
688
|
-
var META2 = new Set("()[]{}*+?|^$.".split(""));
|
|
689
|
-
|
|
690
|
-
// src/table/assemble.ts
|
|
691
|
-
var EMIT_ENABLED = globalThis.process?.env?.PM_TABLE_EMIT !== "0";
|
|
692
|
-
var EMPTY_TL = Object.freeze([]);
|
|
693
|
-
var EMPTY_SENTS = Object.freeze([]);
|
|
694
|
-
|
|
695
|
-
// src/analysis/duplication.ts
|
|
696
|
-
var WORD_RE_SRC = "-?[A-Za-z][A-Za-z0-9_-]*";
|
|
697
|
-
var WORDS_RE = new RegExp(`^${WORD_RE_SRC}(?:\\|${WORD_RE_SRC})*$`);
|
|
698
|
-
|
|
699
|
-
// src/compiler/linker.ts
|
|
700
|
-
function normalizeCstCollapse(collapse) {
|
|
701
|
-
if (collapse === true) return () => true;
|
|
702
|
-
if (Array.isArray(collapse)) {
|
|
703
|
-
const types = new Set(collapse);
|
|
704
|
-
return (type) => types.has(type);
|
|
705
|
-
}
|
|
706
|
-
return typeof collapse === "function" ? collapse : void 0;
|
|
707
|
-
}
|
|
708
|
-
function buildCstNode(type, children, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
709
|
-
return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children] };
|
|
710
|
-
}
|
|
711
|
-
function cstBuildHost(typeOrOptions, children, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
712
|
-
if (typeof typeOrOptions === "string") {
|
|
713
|
-
return buildCstNode(typeOrOptions, children ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
714
|
-
}
|
|
715
|
-
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
716
|
-
const materializeTags = typeOrOptions?.tags === true;
|
|
717
|
-
const host = (type, children2, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children2 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
718
|
-
host._parsemanCstOutput = true;
|
|
719
|
-
if (collapse) host._parsemanCstCollapse = collapse;
|
|
720
|
-
return host;
|
|
721
|
-
}
|
|
722
|
-
cstBuildHost._parsemanCstOutput = true;
|
|
723
|
-
function fusedHostModeOf(registry) {
|
|
724
|
-
const m = registry[FUSED_HOST_MODE];
|
|
725
|
-
return m === "cst" ? "cst" : "ast";
|
|
726
|
-
}
|
|
727
|
-
function fusedHostElidedOf(registry) {
|
|
728
|
-
return registry[FUSED_HOST_ELIDED] === true;
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
// src/cst/relative-spans.ts
|
|
732
|
-
function relativizeCST(node2, parentBase = 0) {
|
|
733
|
-
const span = { start: node2.span.start - parentBase, end: node2.span.end - parentBase };
|
|
734
|
-
if (node2.children) {
|
|
735
|
-
const base = node2.span.start;
|
|
736
|
-
return { ...node2, span, children: node2.children.map((c) => relativizeCST(c, base)) };
|
|
737
|
-
}
|
|
738
|
-
return { ...node2, span };
|
|
739
|
-
}
|
|
740
|
-
function absolutizeCST(node2, parentBase = 0) {
|
|
741
|
-
const start = parentBase + node2.span.start;
|
|
742
|
-
const span = { start, end: parentBase + node2.span.end };
|
|
743
|
-
if (node2.children) {
|
|
744
|
-
return { ...node2, span, children: node2.children.map((c) => absolutizeCST(c, start)) };
|
|
745
|
-
}
|
|
746
|
-
return { ...node2, span };
|
|
747
|
-
}
|
|
748
|
-
function absoluteSpanCST(root, path) {
|
|
749
|
-
let base = 0;
|
|
750
|
-
let node2 = root;
|
|
751
|
-
for (const idx of path) {
|
|
752
|
-
base += node2.span.start;
|
|
753
|
-
const child = node2.children?.[idx];
|
|
754
|
-
if (!child) throw new RangeError(`absoluteSpanCST: no child ${idx} on path ${path.join(".")}`);
|
|
755
|
-
node2 = child;
|
|
756
|
-
}
|
|
757
|
-
return { start: base + node2.span.start, end: base + node2.span.end };
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
// src/functional/doc.ts
|
|
761
|
-
function mkCtx(rawState, build, tolerant) {
|
|
762
|
-
const state = rawState ?? void 0;
|
|
763
|
-
return tolerant ? { trackLines: false, state, build, _tolerant: true, _rec: REC, _errors: [] } : { trackLines: false, state, build };
|
|
764
|
-
}
|
|
765
|
-
function asRuleFn(entry) {
|
|
766
|
-
return typeof entry === "function" ? entry : (input, pos, ctx) => entry.parse(input, pos, ctx);
|
|
767
|
-
}
|
|
768
|
-
function defOf(entry) {
|
|
769
|
-
return typeof entry === "object" && entry !== null && "_def" in entry ? entry._def : void 0;
|
|
770
|
-
}
|
|
771
|
-
function literalTextOf(parser2, depth = 0) {
|
|
772
|
-
const def = defOf(parser2);
|
|
773
|
-
if (!def || depth > 24) return null;
|
|
774
|
-
const d = def;
|
|
775
|
-
switch (d.tag) {
|
|
776
|
-
case "literal":
|
|
777
|
-
return d.caseInsensitive ? null : d.value;
|
|
778
|
-
case "lazy": {
|
|
779
|
-
const thunk = d.thunk;
|
|
780
|
-
try {
|
|
781
|
-
return typeof thunk === "function" ? literalTextOf(thunk(), depth + 1) : null;
|
|
782
|
-
} catch {
|
|
783
|
-
return null;
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
case "node":
|
|
787
|
-
case "transform":
|
|
788
|
-
case "attempt":
|
|
789
|
-
case "token":
|
|
790
|
-
case "leaf":
|
|
791
|
-
case "label":
|
|
792
|
-
case "field":
|
|
793
|
-
case "expect":
|
|
794
|
-
case "withCtx":
|
|
795
|
-
case "grammar":
|
|
796
|
-
return literalTextOf(d.parser, depth + 1);
|
|
797
|
-
default:
|
|
798
|
-
return null;
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
function producesRepetition(def, depth = 0) {
|
|
802
|
-
if (!def || depth > 24) return null;
|
|
803
|
-
const d = def;
|
|
804
|
-
switch (d.tag) {
|
|
805
|
-
case "sepBy": {
|
|
806
|
-
if (d.keepSeparators) return null;
|
|
807
|
-
const text = literalTextOf(d.separator);
|
|
808
|
-
return text === null || text.length === 0 ? null : { kind: "sep", text };
|
|
809
|
-
}
|
|
810
|
-
case "many":
|
|
811
|
-
case "oneOrMore":
|
|
812
|
-
return { kind: "bare" };
|
|
813
|
-
// Rule entries and `ref`s wrap their body in a `lazy` thunk — resolve it. The
|
|
814
|
-
// `depth` cap bounds any self-referential cycle (a repetition, if present, is
|
|
815
|
-
// found shallowly before recursion goes deep).
|
|
816
|
-
case "lazy": {
|
|
817
|
-
const thunk = d.thunk;
|
|
818
|
-
let inner;
|
|
819
|
-
try {
|
|
820
|
-
inner = typeof thunk === "function" ? thunk() : void 0;
|
|
821
|
-
} catch {
|
|
822
|
-
return null;
|
|
823
|
-
}
|
|
824
|
-
return producesRepetition(inner?._def, depth + 1);
|
|
825
|
-
}
|
|
826
|
-
// Transparent wrappers — look through to the inner parser.
|
|
827
|
-
case "node":
|
|
828
|
-
case "transform":
|
|
829
|
-
case "attempt":
|
|
830
|
-
case "token":
|
|
831
|
-
case "leaf":
|
|
832
|
-
case "label":
|
|
833
|
-
case "field":
|
|
834
|
-
case "expect":
|
|
835
|
-
case "withCtx":
|
|
836
|
-
case "grammar":
|
|
837
|
-
case "optional":
|
|
838
|
-
return producesRepetition(defOf(d.parser), depth + 1);
|
|
839
|
-
// A bracketed/anchored list is a sequence whose element run is a repetition.
|
|
840
|
-
case "sequence": {
|
|
841
|
-
for (const p of d.parsers) {
|
|
842
|
-
const rep = producesRepetition(defOf(p), depth + 1);
|
|
843
|
-
if (rep) return rep;
|
|
844
|
-
}
|
|
845
|
-
return null;
|
|
846
|
-
}
|
|
847
|
-
default:
|
|
848
|
-
return null;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
var REENTRY_MAX_SPAN_FRACTION = 0.5;
|
|
852
|
-
function isNode(x) {
|
|
853
|
-
return typeof x === "object" && x !== null && x._tag === "node";
|
|
854
|
-
}
|
|
855
|
-
function findContaining(node2, nodeAbsStart, pos, path = []) {
|
|
856
|
-
for (let i = 0; i < node2.children.length; i++) {
|
|
857
|
-
const child = node2.children[i];
|
|
858
|
-
if (!isNode(child)) continue;
|
|
859
|
-
const childAbsStart = nodeAbsStart + child.span.start;
|
|
860
|
-
const childAbsEnd = nodeAbsStart + child.span.end;
|
|
861
|
-
if (childAbsStart <= pos && pos < childAbsEnd) {
|
|
862
|
-
const inner = findContaining(child, childAbsStart, pos, [...path, i]);
|
|
863
|
-
return inner ?? { node: child, path: [...path, i] };
|
|
864
|
-
}
|
|
865
|
-
}
|
|
866
|
-
return null;
|
|
867
|
-
}
|
|
868
|
-
function ancestorsAt(root, path) {
|
|
869
|
-
const ancestors = [root];
|
|
870
|
-
let cur = root;
|
|
871
|
-
for (const idx of path.slice(0, -1)) {
|
|
872
|
-
const child = cur.children[idx];
|
|
873
|
-
if (!child || !isNode(child)) break;
|
|
874
|
-
ancestors.push(child);
|
|
875
|
-
cur = child;
|
|
876
|
-
}
|
|
877
|
-
return ancestors;
|
|
878
|
-
}
|
|
879
|
-
function replaceAtPath(rebuild, root, path, newNode) {
|
|
880
|
-
if (path.length === 0) return newNode;
|
|
881
|
-
const [idx, ...rest] = path;
|
|
882
|
-
const newChildren = [...root.children];
|
|
883
|
-
newChildren[idx] = rest.length === 0 ? newNode : replaceAtPath(rebuild, root.children[idx], rest, newNode);
|
|
884
|
-
return rebuild(root, newChildren);
|
|
885
|
-
}
|
|
886
|
-
function defaultRebuild(node2, children) {
|
|
887
|
-
return { ...node2, children };
|
|
888
|
-
}
|
|
889
|
-
function shiftRelStart(child, delta) {
|
|
890
|
-
const c = child;
|
|
891
|
-
return { ...c, span: { start: c.span.start + delta, end: c.span.end + delta } };
|
|
892
|
-
}
|
|
893
|
-
function graftRelative(root, path, newNode, delta) {
|
|
894
|
-
if (path.length === 0) return newNode;
|
|
895
|
-
const [idx, ...rest] = path;
|
|
896
|
-
const oldChildren = root.children;
|
|
897
|
-
const newChildren = oldChildren.map((child, i) => {
|
|
898
|
-
if (i < idx) return child;
|
|
899
|
-
if (i === idx) {
|
|
900
|
-
return rest.length === 0 ? newNode : graftRelative(child, rest, newNode, delta);
|
|
901
|
-
}
|
|
902
|
-
return shiftRelStart(child, delta);
|
|
903
|
-
});
|
|
904
|
-
return {
|
|
905
|
-
...root,
|
|
906
|
-
span: { start: root.span.start, end: root.span.end + delta },
|
|
907
|
-
children: newChildren
|
|
908
|
-
};
|
|
909
|
-
}
|
|
910
|
-
function parseMiddle(input, reStart, reEnd, cStart, ruleFn, separator, startsAtElement, build, tolerant) {
|
|
911
|
-
const ctx = mkCtx(null, build, tolerant);
|
|
912
|
-
const out = [];
|
|
913
|
-
let pos = reStart;
|
|
914
|
-
let guard = 0;
|
|
915
|
-
let expectElement = separator === null ? true : startsAtElement;
|
|
916
|
-
while (pos < reEnd) {
|
|
917
|
-
if (++guard > reEnd - reStart + 2) return null;
|
|
918
|
-
if (separator !== null && !expectElement) {
|
|
919
|
-
if (pos + separator.length > reEnd || !input.startsWith(separator, pos)) return null;
|
|
920
|
-
pos += separator.length;
|
|
921
|
-
expectElement = true;
|
|
922
|
-
continue;
|
|
923
|
-
}
|
|
924
|
-
let r;
|
|
925
|
-
try {
|
|
926
|
-
r = ruleFn(input, pos, ctx);
|
|
927
|
-
} catch {
|
|
928
|
-
return null;
|
|
929
|
-
}
|
|
930
|
-
if (!r.ok || r.span.end <= pos || r.span.end > reEnd) return null;
|
|
931
|
-
out.push(relativizeCST(r.value, cStart));
|
|
932
|
-
pos = r.span.end;
|
|
933
|
-
if (separator !== null) expectElement = false;
|
|
934
|
-
}
|
|
935
|
-
return pos === reEnd && expectElement ? out : null;
|
|
936
|
-
}
|
|
937
|
-
function tryListSplice(root, path, C, cStart, newInput, from, to, delta, rep, registry, build, tolerant) {
|
|
938
|
-
const kids = C.children;
|
|
939
|
-
if (kids.length === 0) return null;
|
|
940
|
-
let h = 0;
|
|
941
|
-
while (h < kids.length && cStart + kids[h].span.end <= from) h++;
|
|
942
|
-
let t = kids.length;
|
|
943
|
-
while (t > h && cStart + kids[t - 1].span.start >= to) t--;
|
|
944
|
-
while (t < kids.length && kids[t]._tag !== "node") t++;
|
|
945
|
-
if (t >= kids.length) return null;
|
|
946
|
-
for (let i = t; i < kids.length; i++) {
|
|
947
|
-
if (kids[i]._tag === "node" && kids[i].state != null) return null;
|
|
948
|
-
}
|
|
949
|
-
let elemType;
|
|
950
|
-
let elemCount = 0;
|
|
951
|
-
for (const k of kids) {
|
|
952
|
-
if (k._tag !== "node") continue;
|
|
953
|
-
elemCount++;
|
|
954
|
-
if (elemType === void 0) elemType = k.type;
|
|
955
|
-
else if (k.type !== elemType) return null;
|
|
956
|
-
}
|
|
957
|
-
if (elemType === void 0 || elemCount < 2) return null;
|
|
958
|
-
const ruleFn = registry[elemType];
|
|
959
|
-
if (!ruleFn) return null;
|
|
960
|
-
const separator = rep.kind === "sep" ? rep.text : null;
|
|
961
|
-
const first = kids[0];
|
|
962
|
-
const last = kids[kids.length - 1];
|
|
963
|
-
if (first._tag === "leaf" && first.value !== separator && from < cStart + first.span.end) return null;
|
|
964
|
-
if (last._tag === "leaf" && last.value !== separator && to > cStart + last.span.start) return null;
|
|
965
|
-
const reStart = h > 0 ? cStart + kids[h - 1].span.end : cStart;
|
|
966
|
-
const reEnd = cStart + kids[t].span.start + delta;
|
|
967
|
-
if (reEnd < reStart) return null;
|
|
968
|
-
const startsAtElement = !(h > 0 && kids[h - 1]._tag === "node");
|
|
969
|
-
const middle = parseMiddle(newInput, reStart, reEnd, cStart, ruleFn, separator, startsAtElement, build, tolerant);
|
|
970
|
-
if (!middle) return null;
|
|
971
|
-
if (reEnd < newInput.length) {
|
|
972
|
-
for (const sentinel of [" ", "\uFFFF"]) {
|
|
973
|
-
if (newInput[reEnd] === sentinel) continue;
|
|
974
|
-
const probed = newInput.slice(0, reEnd) + sentinel.repeat(newInput.length - reEnd);
|
|
975
|
-
const probe = parseMiddle(probed, reStart, reEnd, cStart, ruleFn, separator, startsAtElement, build, tolerant);
|
|
976
|
-
if (!probe || probe.length !== middle.length) return null;
|
|
977
|
-
for (let i = 0; i < middle.length; i++) if (!structurallyEqual(probe[i], middle[i])) return null;
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
const head = kids.slice(0, h);
|
|
981
|
-
const tail = kids.slice(t).map((k) => shiftRelStart(k, delta));
|
|
982
|
-
const newC = {
|
|
983
|
-
...C,
|
|
984
|
-
span: { start: C.span.start, end: C.span.end + delta },
|
|
985
|
-
children: [...head, ...middle, ...tail]
|
|
986
|
-
};
|
|
987
|
-
return graftRelative(root, path, newC, delta);
|
|
988
|
-
}
|
|
989
|
-
function structurallyEqual(a, b) {
|
|
990
|
-
if (a === b) return true;
|
|
991
|
-
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
|
|
992
|
-
const at = a._tag;
|
|
993
|
-
const bt = b._tag;
|
|
994
|
-
if (at !== bt) return false;
|
|
995
|
-
const as = a.span;
|
|
996
|
-
const bs = b.span;
|
|
997
|
-
if (as || bs) {
|
|
998
|
-
if (!as || !bs || as.start !== bs.start || as.end !== bs.end) return false;
|
|
999
|
-
}
|
|
1000
|
-
if (at === "leaf" || at === "trivia") {
|
|
1001
|
-
return a.value === b.value;
|
|
1002
|
-
}
|
|
1003
|
-
if (at === "parseError") {
|
|
1004
|
-
const ae = a.expected ?? [];
|
|
1005
|
-
const be = b.expected ?? [];
|
|
1006
|
-
return ae.length === be.length && ae.every((x, i) => x === be[i]);
|
|
1007
|
-
}
|
|
1008
|
-
if (a.type !== b.type) return false;
|
|
1009
|
-
const ac = a.children;
|
|
1010
|
-
const bc = b.children;
|
|
1011
|
-
if (ac || bc) {
|
|
1012
|
-
if (!ac || !bc || ac.length !== bc.length) return false;
|
|
1013
|
-
for (let i = 0; i < ac.length; i++) if (!structurallyEqual(ac[i], bc[i])) return false;
|
|
1014
|
-
}
|
|
1015
|
-
return true;
|
|
1016
|
-
}
|
|
1017
|
-
function boundaryIsSafe(ruleFn, newInput, start, boundary, state, build, produced, tolerant) {
|
|
1018
|
-
if (!produced.ok) return false;
|
|
1019
|
-
if (boundary >= newInput.length) return true;
|
|
1020
|
-
for (const sentinel of [" ", "\uFFFF"]) {
|
|
1021
|
-
if (newInput[boundary] === sentinel) continue;
|
|
1022
|
-
const probed = newInput.slice(0, boundary) + sentinel.repeat(newInput.length - boundary);
|
|
1023
|
-
const ctx = mkCtx(state, build, tolerant);
|
|
1024
|
-
let r;
|
|
1025
|
-
try {
|
|
1026
|
-
r = ruleFn(probed, start, ctx);
|
|
1027
|
-
} catch {
|
|
1028
|
-
return false;
|
|
1029
|
-
}
|
|
1030
|
-
if (!r.ok || r.span.end !== produced.span.end) return false;
|
|
1031
|
-
if (!structurallyEqual(r.value, produced.value)) return false;
|
|
1032
|
-
}
|
|
1033
|
-
return true;
|
|
1034
|
-
}
|
|
1035
|
-
var ParseDocImpl = class _ParseDocImpl {
|
|
1036
|
-
_registry;
|
|
1037
|
-
/** Registry entries normalized to callable parse functions (memoized once). */
|
|
1038
|
-
_fns;
|
|
1039
|
-
/**
|
|
1040
|
-
* Rule names the grammar proves are genuine repetitions — the ONLY splice-safe
|
|
1041
|
-
* types — mapped to the repetition shape (and, for a `sepBy`, the separator text
|
|
1042
|
-
* its construction pins). A rule whose separator isn't recoverable is absent.
|
|
1043
|
-
*/
|
|
1044
|
-
_reps;
|
|
1045
|
-
_rootRule;
|
|
1046
|
-
_opts;
|
|
1047
|
-
/**
|
|
1048
|
-
* The tree, held in whichever coordinate system it arrived in. A fresh parse
|
|
1049
|
-
* arrives ABSOLUTE (`_abs` set); an incremental graft arrives PARENT-RELATIVE
|
|
1050
|
-
* (`_rel` set). The public `tree` is always the RELATIVE form (so untouched
|
|
1051
|
-
* subtrees stay shared by identity across edits and reads are O(1)); it's
|
|
1052
|
-
* materialized from `_abs` once, on demand, and memoized. `undefined` = not yet
|
|
1053
|
-
* computed; `null` = failed parse. A fresh parse that's never edited nor
|
|
1054
|
-
* tree-read pays no conversion — important for the full-reparse fallback path.
|
|
1055
|
-
*/
|
|
1056
|
-
_abs;
|
|
1057
|
-
_rel;
|
|
1058
|
-
errors;
|
|
1059
|
-
unconsumedFrom;
|
|
1060
|
-
input;
|
|
1061
|
-
constructor(registry, rootRule, opts, trees, errors, unconsumedFrom, input) {
|
|
1062
|
-
this._registry = registry;
|
|
1063
|
-
this._fns = {};
|
|
1064
|
-
this._reps = /* @__PURE__ */ new Map();
|
|
1065
|
-
for (const [name, entry] of Object.entries(registry)) {
|
|
1066
|
-
this._fns[name] = asRuleFn(entry);
|
|
1067
|
-
const rep = producesRepetition(defOf(entry));
|
|
1068
|
-
if (rep) this._reps.set(name, rep);
|
|
1069
|
-
}
|
|
1070
|
-
this._rootRule = rootRule;
|
|
1071
|
-
this._opts = opts;
|
|
1072
|
-
this._abs = trees.abs;
|
|
1073
|
-
this._rel = trees.rel;
|
|
1074
|
-
this.errors = errors;
|
|
1075
|
-
this.unconsumedFrom = unconsumedFrom;
|
|
1076
|
-
this.input = input;
|
|
1077
|
-
}
|
|
1078
|
-
/**
|
|
1079
|
-
* The parse tree with PARENT-RELATIVE spans — a node's `span` is relative to
|
|
1080
|
-
* its parent's start (root base 0). This is the shareable representation:
|
|
1081
|
-
* untouched subtrees keep the same identity across `.edit()`s, and reading the
|
|
1082
|
-
* tree after a length-changing edit is O(1) (no offset rewrite). For absolute
|
|
1083
|
-
* positions use the O(depth) cursor `spanAt(path)`, or `absolutizeCST(tree)` to
|
|
1084
|
-
* materialize the whole absolute tree. (A fresh non-incremental `node().parse()`
|
|
1085
|
-
* result is unchanged — still absolute.)
|
|
1086
|
-
*/
|
|
1087
|
-
get tree() {
|
|
1088
|
-
if (this._rel === void 0) {
|
|
1089
|
-
this._rel = this._abs ? relativizeCST(this._abs, 0) : null;
|
|
1090
|
-
}
|
|
1091
|
-
return this._rel;
|
|
1092
|
-
}
|
|
1093
|
-
spanAt(path) {
|
|
1094
|
-
const rel = this.tree;
|
|
1095
|
-
if (!rel) throw new Error("spanAt on a failed parse (tree is null)");
|
|
1096
|
-
return absoluteSpanCST(rel, path);
|
|
1097
|
-
}
|
|
1098
|
-
/**
|
|
1099
|
-
* Wrap a reused (grafted/spliced) RELATIVE tree, recomputing `errors` and
|
|
1100
|
-
* `unconsumedFrom` from it so both stay consistent with the tree across the
|
|
1101
|
-
* edit (the flat errors are recovered errors embedded in the reused subtrees;
|
|
1102
|
-
* unconsumedFrom re-derives trailing junk over the new input).
|
|
1103
|
-
*/
|
|
1104
|
-
wrapReuse(newTree, newInput) {
|
|
1105
|
-
const trivia2 = triviaOf(this._registry[this._rootRule], this._opts);
|
|
1106
|
-
const end = newTree.span.end;
|
|
1107
|
-
const errors = collectEmbeddedErrors(newTree, 0, []);
|
|
1108
|
-
const unconsumedFrom = unconsumedAfter(end, newInput, trivia2);
|
|
1109
|
-
return new _ParseDocImpl(this._registry, this._rootRule, this._opts, { rel: newTree }, errors, unconsumedFrom, newInput);
|
|
1110
|
-
}
|
|
1111
|
-
edit(from, to, replacement) {
|
|
1112
|
-
const newInput = this.input.slice(0, from) + replacement + this.input.slice(to);
|
|
1113
|
-
const reparse = () => parseDoc(this._registry, this._rootRule, newInput, this._opts);
|
|
1114
|
-
const root = this.tree;
|
|
1115
|
-
if (!root) return reparse();
|
|
1116
|
-
const delta = replacement.length - (to - from);
|
|
1117
|
-
const found = findContaining(root, 0, from) ?? { node: root, path: [] };
|
|
1118
|
-
const ancestors = ancestorsAt(root, found.path);
|
|
1119
|
-
const candidates = [found];
|
|
1120
|
-
const pathCopy = [...found.path];
|
|
1121
|
-
for (let i = ancestors.length - 2; i >= 0; i--) {
|
|
1122
|
-
pathCopy.pop();
|
|
1123
|
-
candidates.push({ node: ancestors[i + 1], path: [...pathCopy] });
|
|
1124
|
-
}
|
|
1125
|
-
const rebuild = this._opts.rebuild ?? defaultRebuild;
|
|
1126
|
-
for (const { node: node2, path } of candidates) {
|
|
1127
|
-
const { start: absStart, end: absEnd } = absoluteSpanCST(root, path);
|
|
1128
|
-
if (absEnd - absStart > this.input.length * REENTRY_MAX_SPAN_FRACTION) break;
|
|
1129
|
-
const ruleFn = this._fns[node2.type];
|
|
1130
|
-
if (!ruleFn) continue;
|
|
1131
|
-
if (!(absStart <= from && to <= absEnd)) continue;
|
|
1132
|
-
const ctx = mkCtx(node2.state, this._opts.build, !!this._opts.tolerant);
|
|
1133
|
-
const r = ruleFn(newInput, absStart, ctx);
|
|
1134
|
-
if (!r.ok) continue;
|
|
1135
|
-
if (r.span.end !== absEnd + delta) continue;
|
|
1136
|
-
if (!boundaryIsSafe(ruleFn, newInput, absStart, absEnd + delta, node2.state, this._opts.build, r, !!this._opts.tolerant)) {
|
|
1137
|
-
continue;
|
|
1138
|
-
}
|
|
1139
|
-
const parentBase = absStart - node2.span.start;
|
|
1140
|
-
const newRel = relativizeCST(r.value, parentBase);
|
|
1141
|
-
if (delta === 0) {
|
|
1142
|
-
const newTree2 = replaceAtPath(rebuild, root, path, newRel);
|
|
1143
|
-
return this.wrapReuse(newTree2, newInput);
|
|
1144
|
-
}
|
|
1145
|
-
if (this._opts.rebuild) return reparse();
|
|
1146
|
-
const newTree = graftRelative(root, path, newRel, delta);
|
|
1147
|
-
return this.wrapReuse(newTree, newInput);
|
|
1148
|
-
}
|
|
1149
|
-
if (this._opts.structuralReuse && delta !== 0 && !this._opts.rebuild) {
|
|
1150
|
-
const spliceCandidates = [...candidates, { node: root, path: [] }];
|
|
1151
|
-
for (const { node: node2, path } of spliceCandidates) {
|
|
1152
|
-
const rep = this._reps.get(node2.type);
|
|
1153
|
-
if (!rep) continue;
|
|
1154
|
-
const { start: cStart, end: cEnd } = absoluteSpanCST(root, path);
|
|
1155
|
-
if (!(cStart <= from && to <= cEnd)) continue;
|
|
1156
|
-
const spliced = tryListSplice(root, path, node2, cStart, newInput, from, to, delta, rep, this._fns, this._opts.build, !!this._opts.tolerant);
|
|
1157
|
-
if (spliced) return this.wrapReuse(spliced, newInput);
|
|
1158
|
-
}
|
|
1159
|
-
}
|
|
1160
|
-
return reparse();
|
|
1161
|
-
}
|
|
1162
|
-
};
|
|
1163
|
-
function triviaOf(entry, opts) {
|
|
1164
|
-
if (opts.trivia) return opts.trivia;
|
|
1165
|
-
if (entry === void 0 || typeof entry === "function") return void 0;
|
|
1166
|
-
const meta = entry._meta;
|
|
1167
|
-
return meta ? meta.grammarTrivia : void 0;
|
|
1168
|
-
}
|
|
1169
|
-
function unconsumedAfter(end, input, trivia2) {
|
|
1170
|
-
let pos = end;
|
|
1171
|
-
if (trivia2 && pos < input.length) {
|
|
1172
|
-
const t = trivia2.parse(input, pos, createParseContext());
|
|
1173
|
-
if (t.ok && t.span.end > pos) pos = t.span.end;
|
|
1174
|
-
}
|
|
1175
|
-
return pos < input.length ? pos : null;
|
|
1176
|
-
}
|
|
1177
|
-
function collectEmbeddedErrors(node2, base, out) {
|
|
1178
|
-
const c = node2;
|
|
1179
|
-
if (!c || typeof c !== "object" || !c.span) return out;
|
|
1180
|
-
const start = base + c.span.start;
|
|
1181
|
-
if (c._tag === "parseError") {
|
|
1182
|
-
out.push({ _tag: "parseError", span: { start, end: base + c.span.end }, expected: c.expected ?? [] });
|
|
1183
|
-
return out;
|
|
1184
|
-
}
|
|
1185
|
-
if (Array.isArray(c.children)) for (const k of c.children) collectEmbeddedErrors(k, start, out);
|
|
1186
|
-
return out;
|
|
1187
|
-
}
|
|
1188
|
-
function parseDoc(registry, rootRule, input, opts = {}) {
|
|
1189
|
-
const entry = registry[rootRule];
|
|
1190
|
-
if (!entry) throw new Error(`No rule '${rootRule}' in registry`);
|
|
1191
|
-
assertHostModeCompatible(fusedHostModeOf(registry), opts.build, fusedHostElidedOf(registry));
|
|
1192
|
-
const ctx = mkCtx(opts.state, opts.build, !!opts.tolerant);
|
|
1193
|
-
const r = asRuleFn(entry)(input, 0, ctx);
|
|
1194
|
-
if (r.ok) {
|
|
1195
|
-
const errors = ctx._errors ? [...ctx._errors] : [];
|
|
1196
|
-
const unconsumedFrom = unconsumedAfter(r.span.end, input, triviaOf(entry, opts));
|
|
1197
|
-
return new ParseDocImpl(registry, rootRule, opts, { abs: r.value }, errors, unconsumedFrom, input);
|
|
1198
|
-
}
|
|
1199
|
-
const fail = { _tag: "parseError", span: r.span, expected: r.expected };
|
|
1200
|
-
return new ParseDocImpl(registry, rootRule, opts, { abs: null }, [fail], null, input);
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
// src/language-service/index.ts
|
|
1204
|
-
var errorMessage = (expected) => expected.length ? `Unexpected input; expected ${expected.join(" or ")}` : "Unexpected input";
|
|
1205
|
-
function visitTree(root, enter) {
|
|
1206
|
-
const go = (node2) => {
|
|
1207
|
-
enter(node2);
|
|
1208
|
-
const children = node2.children;
|
|
1209
|
-
if (Array.isArray(children)) for (const child of children) go(child);
|
|
1210
|
-
};
|
|
1211
|
-
go(root);
|
|
1212
|
-
}
|
|
1213
|
-
function mergeDiagnostics(tree, flat, unconsumedFrom, inputLength, config) {
|
|
1214
|
-
const out = [];
|
|
1215
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1216
|
-
const add = (d) => {
|
|
1217
|
-
const key = `${d.severity}|${d.span.start}|${d.span.end}|${d.message}`;
|
|
1218
|
-
if (seen.has(key)) return;
|
|
1219
|
-
seen.add(key);
|
|
1220
|
-
out.push(d);
|
|
1221
|
-
};
|
|
1222
|
-
if (tree) for (const d of diagnoseTree(tree, config)) add(d);
|
|
1223
|
-
for (const e of flat) add({ severity: "error", message: errorMessage(e.expected), span: e.span });
|
|
1224
|
-
if (unconsumedFrom !== null) {
|
|
1225
|
-
add({ severity: "error", message: "Unexpected input", span: { start: unconsumedFrom, end: inputLength } });
|
|
1226
|
-
}
|
|
1227
|
-
return out;
|
|
1228
|
-
}
|
|
1229
|
-
function diagnoseTree(root, config) {
|
|
1230
|
-
const out = [];
|
|
1231
|
-
const rules2 = config.diagnostics;
|
|
1232
|
-
visitTree(root, (node2) => {
|
|
1233
|
-
if (node2._tag === "parseError") {
|
|
1234
|
-
out.push({ severity: "error", message: errorMessage(node2.expected ?? []), span: node2.span });
|
|
1235
|
-
return;
|
|
1236
|
-
}
|
|
1237
|
-
const h = rules2 && node2.type !== void 0 ? rules2[node2.type] : void 0;
|
|
1238
|
-
if (h) {
|
|
1239
|
-
const d = h(node2);
|
|
1240
|
-
if (d) out.push(...Array.isArray(d) ? d : [d]);
|
|
1241
|
-
}
|
|
1242
|
-
});
|
|
1243
|
-
return out;
|
|
1244
|
-
}
|
|
1245
|
-
function languageService(grammar, config = {}) {
|
|
1246
|
-
const build = cstBuildHost();
|
|
1247
|
-
const asReg = typeof grammar === "object" && grammar !== null && "rules" in grammar;
|
|
1248
|
-
const registry = asReg ? grammar.rules : void 0;
|
|
1249
|
-
const root = asReg ? grammar.root : void 0;
|
|
1250
|
-
const entry = asReg ? registry[root] : grammar;
|
|
1251
|
-
const trivia2 = typeof entry !== "function" ? entry._meta.grammarTrivia : void 0;
|
|
1252
|
-
const parseTolerant = (src) => run(entry, src, { tolerant: true, build, ...trivia2 !== void 0 ? { trivia: trivia2 } : {} });
|
|
1253
|
-
const complete = (input, offset, treeForCursor) => {
|
|
1254
|
-
const expected = completionsAt(entry, input, offset, { tolerant: true });
|
|
1255
|
-
const rule = ruleAtCursor(treeForCursor, offset);
|
|
1256
|
-
const handler = rule !== null ? config.complete?.[rule] : void 0;
|
|
1257
|
-
if (handler) return handler({ rule, expected, offset });
|
|
1258
|
-
return expected.map((label2) => ({ label: label2 }));
|
|
1259
|
-
};
|
|
1260
|
-
return {
|
|
1261
|
-
parse(src, opts) {
|
|
1262
|
-
return run(entry, src, { tolerant: opts?.tolerant ?? true, build });
|
|
1263
|
-
},
|
|
1264
|
-
diagnostics(src) {
|
|
1265
|
-
const r = parseTolerant(src);
|
|
1266
|
-
const tree = r.value && typeof r.value === "object" ? r.value : null;
|
|
1267
|
-
return mergeDiagnostics(tree, r.errors, r.unconsumedFrom, src.length, config);
|
|
1268
|
-
},
|
|
1269
|
-
completionsAt(src, offset) {
|
|
1270
|
-
return complete(src, offset, parseTolerant(src.slice(0, offset)).value);
|
|
1271
|
-
},
|
|
1272
|
-
openDocument(src) {
|
|
1273
|
-
if (!registry || root === void 0) {
|
|
1274
|
-
throw new Error("openDocument requires languageService({ rules, root }, config) \u2014 a rules() registry, not a single entry");
|
|
1275
|
-
}
|
|
1276
|
-
const host = cstBuildHost();
|
|
1277
|
-
const make = (doc) => {
|
|
1278
|
-
const abs = doc.tree ? absolutizeCST(doc.tree) : null;
|
|
1279
|
-
return {
|
|
1280
|
-
get tree() {
|
|
1281
|
-
return abs;
|
|
1282
|
-
},
|
|
1283
|
-
edit: (from, to, replacement) => make(doc.edit(from, to, replacement)),
|
|
1284
|
-
// Same unified merge as the stateless path: embedded parseError nodes +
|
|
1285
|
-
// lint, the flat recovery errors the doc collected, and a trailing-junk
|
|
1286
|
-
// sentinel — so a live editor document surfaces missing-closers and junk.
|
|
1287
|
-
diagnostics: () => mergeDiagnostics(abs, doc.errors, doc.unconsumedFrom, doc.input.length, config),
|
|
1288
|
-
completionsAt: (offset) => complete(doc.input, offset, abs)
|
|
1289
|
-
};
|
|
1290
|
-
};
|
|
1291
|
-
return make(parseDoc(registry, root, src, { tolerant: true, structuralReuse: true, build: host }));
|
|
1292
|
-
}
|
|
1293
|
-
};
|
|
1294
|
-
}
|
|
1295
|
-
function ruleAtCursor(root, offset) {
|
|
1296
|
-
if (!root || typeof root !== "object") return null;
|
|
1297
|
-
let best = null;
|
|
1298
|
-
visitTree(root, (node2) => {
|
|
1299
|
-
const s = node2.span;
|
|
1300
|
-
if (s && s.start <= offset && offset <= s.end && node2.type !== void 0) best = node2.type;
|
|
1301
|
-
});
|
|
1302
|
-
return best;
|
|
1303
|
-
}
|
|
1304
|
-
//# sourceMappingURL=index.cjs.map
|