@thomasfosterau/effect-parse 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +247 -230
- package/dist/Ascii.d.ts +32 -53
- package/dist/Ascii.d.ts.map +1 -1
- package/dist/Ascii.js +576 -571
- package/dist/Ascii.js.map +1 -1
- package/dist/Binary.d.ts +6 -29
- package/dist/Binary.d.ts.map +1 -1
- package/dist/Binary.js +129 -116
- package/dist/Binary.js.map +1 -1
- package/dist/Bits.d.ts +4 -2
- package/dist/Bits.d.ts.map +1 -1
- package/dist/Bits.js +121 -123
- package/dist/Bits.js.map +1 -1
- package/dist/Compiler.d.ts +39 -0
- package/dist/Compiler.d.ts.map +1 -0
- package/dist/Compiler.js +48 -0
- package/dist/Compiler.js.map +1 -0
- package/dist/Encoding.d.ts +29 -46
- package/dist/Encoding.d.ts.map +1 -1
- package/dist/Encoding.js +76 -75
- package/dist/Encoding.js.map +1 -1
- package/dist/Expression.d.ts +15 -49
- package/dist/Expression.d.ts.map +1 -1
- package/dist/Expression.js +143 -131
- package/dist/Expression.js.map +1 -1
- package/dist/Input.d.ts +206 -177
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +317 -299
- package/dist/Input.js.map +1 -1
- package/dist/Nom.d.ts +44 -84
- package/dist/Nom.d.ts.map +1 -1
- package/dist/Nom.js +423 -453
- package/dist/Nom.js.map +1 -1
- package/dist/ParseError.d.ts +54 -49
- package/dist/ParseError.d.ts.map +1 -1
- package/dist/ParseError.js +233 -275
- package/dist/ParseError.js.map +1 -1
- package/dist/Parser.d.ts +345 -313
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +2010 -1802
- package/dist/Parser.js.map +1 -1
- package/dist/ParserSchema.d.ts +8 -7
- package/dist/ParserSchema.d.ts.map +1 -1
- package/dist/ParserSchema.js +49 -49
- package/dist/ParserSchema.js.map +1 -1
- package/dist/ParserStream.d.ts +26 -20
- package/dist/ParserStream.d.ts.map +1 -1
- package/dist/ParserStream.js +267 -255
- package/dist/ParserStream.js.map +1 -1
- package/dist/Syntax.d.ts +401 -0
- package/dist/Syntax.d.ts.map +1 -0
- package/dist/Syntax.js +717 -0
- package/dist/Syntax.js.map +1 -0
- package/dist/Text.d.ts +98 -134
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +534 -496
- package/dist/Text.js.map +1 -1
- package/dist/Token.d.ts +60 -42
- package/dist/Token.d.ts.map +1 -1
- package/dist/Token.js +331 -265
- package/dist/Token.js.map +1 -1
- package/dist/index.d.ts +16 -17
- package/dist/index.js +16 -17
- package/dist/internal/compiler/closure.d.ts +14 -16
- package/dist/internal/compiler/closure.d.ts.map +1 -1
- package/dist/internal/compiler/closure.js +1458 -1637
- package/dist/internal/compiler/closure.js.map +1 -1
- package/dist/internal/compiler/entries.d.ts +11 -11
- package/dist/internal/compiler/entries.d.ts.map +1 -1
- package/dist/internal/compiler/entries.js +36 -26
- package/dist/internal/compiler/entries.js.map +1 -1
- package/dist/internal/compiler/first.d.ts +19 -19
- package/dist/internal/compiler/first.d.ts.map +1 -1
- package/dist/internal/compiler/first.js +251 -227
- package/dist/internal/compiler/first.js.map +1 -1
- package/dist/internal/compiler/jit.d.ts +6 -17
- package/dist/internal/compiler/jit.d.ts.map +1 -1
- package/dist/internal/compiler/jit.js +860 -988
- package/dist/internal/compiler/jit.js.map +1 -1
- package/dist/internal/compiler/registry.d.ts +20 -21
- package/dist/internal/compiler/registry.d.ts.map +1 -1
- package/dist/internal/compiler/registry.js +21 -41
- package/dist/internal/compiler/registry.js.map +1 -1
- package/dist/internal/compiler/sets.d.ts +9 -13
- package/dist/internal/compiler/sets.d.ts.map +1 -1
- package/dist/internal/compiler/sets.js +76 -73
- package/dist/internal/compiler/sets.js.map +1 -1
- package/dist/internal/entries.d.ts +3 -3
- package/dist/internal/entries.d.ts.map +1 -1
- package/dist/internal/entries.js +38 -30
- package/dist/internal/entries.js.map +1 -1
- package/dist/internal/node.d.ts +177 -173
- package/dist/internal/node.d.ts.map +1 -1
- package/dist/internal/node.js +77 -66
- package/dist/internal/node.js.map +1 -1
- package/dist/internal/numbers.d.ts +7 -8
- package/dist/internal/numbers.d.ts.map +1 -1
- package/dist/internal/numbers.js +246 -276
- package/dist/internal/numbers.js.map +1 -1
- package/dist/internal/resume.d.ts +6 -24
- package/dist/internal/resume.d.ts.map +1 -1
- package/dist/internal/resume.js +30 -29
- package/dist/internal/resume.js.map +1 -1
- package/dist/internal/run.d.ts +15 -0
- package/dist/internal/run.d.ts.map +1 -0
- package/dist/internal/run.js +36 -0
- package/dist/internal/run.js.map +1 -0
- package/dist/internal/stack.d.ts +16 -0
- package/dist/internal/stack.d.ts.map +1 -0
- package/dist/internal/stack.js +26 -0
- package/dist/internal/stack.js.map +1 -0
- package/dist/internal/syntax.d.ts +146 -0
- package/dist/internal/syntax.d.ts.map +1 -0
- package/dist/internal/syntax.js +305 -0
- package/dist/internal/syntax.js.map +1 -0
- package/dist/internal/text.d.ts +10 -2
- package/dist/internal/text.d.ts.map +1 -1
- package/dist/internal/text.js +295 -345
- package/dist/internal/text.js.map +1 -1
- package/dist/internal/tokens.d.ts +25 -30
- package/dist/internal/tokens.d.ts.map +1 -1
- package/dist/internal/tokens.js +369 -363
- package/dist/internal/tokens.js.map +1 -1
- package/package.json +42 -28
- package/src/Ascii.ts +278 -187
- package/src/Binary.ts +150 -44
- package/src/Bits.ts +6 -3
- package/src/Compiler.ts +98 -0
- package/src/Expression.ts +10 -5
- package/src/Input.ts +106 -28
- package/src/Nom.ts +4 -3
- package/src/ParseError.ts +48 -51
- package/src/Parser.ts +1163 -795
- package/src/ParserStream.ts +104 -80
- package/src/Syntax.ts +900 -0
- package/src/Text.ts +272 -187
- package/src/Token.ts +180 -87
- package/src/index.ts +2 -0
- package/src/internal/compiler/closure.ts +121 -88
- package/src/internal/compiler/entries.ts +21 -8
- package/src/internal/compiler/first.ts +17 -15
- package/src/internal/compiler/jit.ts +360 -157
- package/src/internal/compiler/registry.ts +12 -33
- package/src/internal/compiler/sets.ts +17 -11
- package/src/internal/entries.ts +4 -2
- package/src/internal/node.ts +51 -37
- package/src/internal/numbers.ts +22 -20
- package/src/internal/resume.ts +8 -4
- package/src/internal/run.ts +41 -0
- package/src/internal/stack.ts +36 -0
- package/src/internal/syntax.ts +421 -0
- package/src/internal/text.ts +32 -25
- package/src/internal/tokens.ts +96 -51
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/Input.js
CHANGED
|
@@ -1,312 +1,330 @@
|
|
|
1
|
-
|
|
2
|
-
* Input types and the mutable parse {@link State} cursor.
|
|
3
|
-
*
|
|
4
|
-
* Like winnow, effect-parse parsers advance a mutable cursor rather than
|
|
5
|
-
* returning the remaining input. A {@link State} wraps the original input
|
|
6
|
-
* together with the current offset, the streaming (partial) flag, the
|
|
7
|
-
* services available to the parser, and the details of the most recent
|
|
8
|
-
* failure.
|
|
9
|
-
*
|
|
10
|
-
* Most users never touch `State` directly. It is exposed for writing custom
|
|
11
|
-
* low-level parsers with `Parser.make`.
|
|
12
|
-
*
|
|
13
|
-
* @since 0.1.0
|
|
14
|
-
*/
|
|
1
|
+
import * as Predicate from "effect/Predicate";
|
|
15
2
|
import * as Context from "effect/Context";
|
|
3
|
+
//#region src/Input.ts
|
|
4
|
+
/**
|
|
5
|
+
* Input types and the mutable parse {@link State} cursor.
|
|
6
|
+
*
|
|
7
|
+
* Like winnow, effect-parse parsers advance a mutable cursor rather than
|
|
8
|
+
* returning the remaining input. A {@link State} wraps the original input
|
|
9
|
+
* together with the current offset, the streaming (partial) flag, the
|
|
10
|
+
* services available to the parser, and the details of the most recent
|
|
11
|
+
* failure.
|
|
12
|
+
*
|
|
13
|
+
* Most users never touch `State` directly. It is exposed for writing custom
|
|
14
|
+
* low-level parsers with `Parser.make`, and for drivers that run a parser's
|
|
15
|
+
* `step` many times over one input, reusing a state with {@link State.reset}.
|
|
16
|
+
*
|
|
17
|
+
* @since 0.1.0
|
|
18
|
+
*/
|
|
16
19
|
/**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// An explicit length fixes the view's size even for a resizable buffer
|
|
36
|
-
if (isArrayBufferLike(source))
|
|
37
|
-
return new Uint8Array(source, 0, source.byteLength);
|
|
38
|
-
return source;
|
|
20
|
+
* Converts a {@link Source} to the input parsers read: binary data becomes a
|
|
21
|
+
* `Uint8Array` view of the same memory, everything else is returned as is.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { Input } from "@thomasfosterau/effect-parse"
|
|
26
|
+
*
|
|
27
|
+
* Input.fromSource(new Uint16Array([0x41]).buffer) // Uint8Array [0x41, 0x00]
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @since 0.1.0
|
|
31
|
+
* @category constructors
|
|
32
|
+
*/
|
|
33
|
+
const fromSource = (source) => {
|
|
34
|
+
if (Predicate.isString(source) || source instanceof Uint8Array || Array.isArray(source)) return source;
|
|
35
|
+
if (ArrayBuffer.isView(source)) return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
|
|
36
|
+
if (isArrayBufferLike(source)) return new Uint8Array(source, 0, source.byteLength);
|
|
37
|
+
return source;
|
|
39
38
|
};
|
|
40
|
-
const isArrayBufferLike = (u) => u instanceof ArrayBuffer ||
|
|
39
|
+
const isArrayBufferLike = (u) => u instanceof ArrayBuffer || globalThis.SharedArrayBuffer !== void 0 && u instanceof SharedArrayBuffer;
|
|
41
40
|
/**
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
* Sentinel returned by a parser step to signal failure. The failure details
|
|
42
|
+
* are stored on the {@link State}.
|
|
43
|
+
*
|
|
44
|
+
* @since 0.1.0
|
|
45
|
+
* @category failure
|
|
46
|
+
*/
|
|
47
|
+
const Fail = /*#__PURE__*/ Symbol.for("effect-parse/Fail");
|
|
49
48
|
/**
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
/** A user supplied (typed) cause. */
|
|
76
|
-
cause,
|
|
77
|
-
/** An optional free-form message. */
|
|
78
|
-
message,
|
|
79
|
-
/** For `Incomplete` failures, how many more tokens are needed (0 if unknown). */
|
|
80
|
-
needed) {
|
|
81
|
-
this.offset = offset;
|
|
82
|
-
this.kind = kind;
|
|
83
|
-
this.expected = expected;
|
|
84
|
-
this.context = context;
|
|
85
|
-
this.hasCause = hasCause;
|
|
86
|
-
this.cause = cause;
|
|
87
|
-
this.message = message;
|
|
88
|
-
this.needed = needed;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
49
|
+
* The details of a parse failure.
|
|
50
|
+
*
|
|
51
|
+
* @since 0.1.0
|
|
52
|
+
* @category failure
|
|
53
|
+
*/
|
|
54
|
+
var Failure = class {
|
|
55
|
+
offset;
|
|
56
|
+
kind;
|
|
57
|
+
expected;
|
|
58
|
+
context;
|
|
59
|
+
hasCause;
|
|
60
|
+
cause;
|
|
61
|
+
message;
|
|
62
|
+
needed;
|
|
63
|
+
constructor(offset, kind, expected, context, hasCause, cause, message, needed) {
|
|
64
|
+
this.offset = offset;
|
|
65
|
+
this.kind = kind;
|
|
66
|
+
this.expected = expected;
|
|
67
|
+
this.context = context;
|
|
68
|
+
this.hasCause = hasCause;
|
|
69
|
+
this.cause = cause;
|
|
70
|
+
this.message = message;
|
|
71
|
+
this.needed = needed;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
91
74
|
const empty = [];
|
|
75
|
+
/** The failure a {@link State} starts with, before any step has failed. */
|
|
76
|
+
const initialFailure = /*#__PURE__*/ new Failure(0, "Fail", empty, empty, false, void 0, void 0, 0);
|
|
92
77
|
/** @internal */
|
|
93
|
-
|
|
78
|
+
const emptyStrings = empty;
|
|
94
79
|
/**
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}
|
|
80
|
+
* The mutable parsing cursor.
|
|
81
|
+
*
|
|
82
|
+
* @since 0.1.0
|
|
83
|
+
* @category models
|
|
84
|
+
*/
|
|
85
|
+
var State = class {
|
|
86
|
+
/** The full input being parsed. */
|
|
87
|
+
input;
|
|
88
|
+
/** The end offset (the input's length; in bits inside `Bits.bits`). */
|
|
89
|
+
end;
|
|
90
|
+
/** 0 = string, 1 = Uint8Array, 2 = array. */
|
|
91
|
+
inputKind;
|
|
92
|
+
/** Whether the input is partial (streaming): running out yields `Incomplete`. */
|
|
93
|
+
partial;
|
|
94
|
+
/** Services available to `Parser.service`. */
|
|
95
|
+
context;
|
|
96
|
+
/** Mode of the latest failure. Only meaningful after a step returned {@link Fail}. */
|
|
97
|
+
mode = "Backtrack";
|
|
98
|
+
/** Details of the latest failure. Only meaningful after a step returned {@link Fail}. */
|
|
99
|
+
failure;
|
|
100
|
+
/**
|
|
101
|
+
* The offset of a recoverable failure that occurred without consuming
|
|
102
|
+
* input (for example the last attempt of a `repeat`). Its
|
|
103
|
+
* expectations are merged into new failures at the same offset, producing
|
|
104
|
+
* messages like `expected digit or ")"`.
|
|
105
|
+
*/
|
|
106
|
+
hintOffset = -1;
|
|
107
|
+
/** The expectations of the hint at {@link hintOffset}. */
|
|
108
|
+
hintExpected = empty;
|
|
109
|
+
/**
|
|
110
|
+
* The furthest recoverable failure seen so far, including failures that
|
|
111
|
+
* were later swallowed by backtracking (for example a trailing separator
|
|
112
|
+
* followed by an invalid element). It is reported instead of the final
|
|
113
|
+
* failure when it lies further into the input. This is the classic PEG
|
|
114
|
+
* "farthest failure" heuristic. `Parser.cut` keeps only the failures
|
|
115
|
+
* recorded inside it when it commits, and `Parser.peek` and `Parser.not`
|
|
116
|
+
* forget the failures of a lookahead that succeeded.
|
|
117
|
+
*/
|
|
118
|
+
deepest = void 0;
|
|
119
|
+
/** When defined, `Parser.resumeAfter`/`retryAfter` record failures here. */
|
|
120
|
+
recovered = void 0;
|
|
121
|
+
/** When defined, `Parser.trace` reports events here. */
|
|
122
|
+
tracer = void 0;
|
|
123
|
+
/** Current tracing depth. */
|
|
124
|
+
depth = 0;
|
|
125
|
+
/**
|
|
126
|
+
* The text encoding of a byte input, recorded by `Text` parsers when they
|
|
127
|
+
* fail so that errors can show the input as text.
|
|
128
|
+
*/
|
|
129
|
+
encoding = void 0;
|
|
130
|
+
/**
|
|
131
|
+
* The checkpoints of a resumable streaming parse (see
|
|
132
|
+
* `ParserStream.parseAll`); `undefined` otherwise.
|
|
133
|
+
*
|
|
134
|
+
* @internal
|
|
135
|
+
*/
|
|
136
|
+
resume = void 0;
|
|
137
|
+
/**
|
|
138
|
+
* The tree builder of a `Syntax` parse; `undefined` otherwise.
|
|
139
|
+
*
|
|
140
|
+
* @internal
|
|
141
|
+
*/
|
|
142
|
+
syntax = void 0;
|
|
143
|
+
constructor(source, options) {
|
|
144
|
+
const input = fromSource(source);
|
|
145
|
+
this.input = input;
|
|
146
|
+
this.end = input.length;
|
|
147
|
+
this.pos = options?.offset ?? 0;
|
|
148
|
+
this.partial = options?.partial ?? false;
|
|
149
|
+
this.context = options?.context ?? Context.empty();
|
|
150
|
+
this.inputKind = Predicate.isString(input) ? 0 : input instanceof Uint8Array ? 1 : 2;
|
|
151
|
+
this.failure = initialFailure;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Prepares the state for another run over the same input, starting at
|
|
155
|
+
* `offset`: afterwards it behaves exactly like
|
|
156
|
+
* `new State(state.input, { ...options, offset })`, without allocating a
|
|
157
|
+
* new state.
|
|
158
|
+
*
|
|
159
|
+
* Every per-run field is reset: the cursor and end, the latest failure,
|
|
160
|
+
* hints and furthest failure, recorded recoveries, the tracer and tracing
|
|
161
|
+
* depth, the recorded encoding and streaming checkpoints. Like the
|
|
162
|
+
* constructor, `partial` defaults to `false` and `context` to the empty
|
|
163
|
+
* context, so pass them again on every reset.
|
|
164
|
+
*
|
|
165
|
+
* Use it to run many small parses over one buffer, for example one per
|
|
166
|
+
* token, with `parser.step`. A state can be reused after any run,
|
|
167
|
+
* including one that failed, returned `Incomplete` or threw.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```ts
|
|
171
|
+
* import { Ascii, Input } from "@thomasfosterau/effect-parse"
|
|
172
|
+
*
|
|
173
|
+
* const state = new Input.State("12 34")
|
|
174
|
+
* Ascii.decUint.step(state) // 12
|
|
175
|
+
* state.reset(3)
|
|
176
|
+
* Ascii.decUint.step(state) // 34
|
|
177
|
+
* ```
|
|
178
|
+
*
|
|
179
|
+
* @since 0.2.0
|
|
180
|
+
*/
|
|
181
|
+
reset(offset = 0, options) {
|
|
182
|
+
this.pos = offset;
|
|
183
|
+
this.end = this.input.length;
|
|
184
|
+
this.partial = options?.partial ?? false;
|
|
185
|
+
this.context = options?.context ?? Context.empty();
|
|
186
|
+
this.mode = "Backtrack";
|
|
187
|
+
this.failure = initialFailure;
|
|
188
|
+
this.hintOffset = -1;
|
|
189
|
+
this.hintExpected = empty;
|
|
190
|
+
this.deepest = void 0;
|
|
191
|
+
this.recovered = void 0;
|
|
192
|
+
this.tracer = void 0;
|
|
193
|
+
this.depth = 0;
|
|
194
|
+
this.encoding = void 0;
|
|
195
|
+
this.resume = void 0;
|
|
196
|
+
return this;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* The number of input units (code units, bytes or elements) remaining.
|
|
200
|
+
*/
|
|
201
|
+
remaining() {
|
|
202
|
+
return this.end - this.pos;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Whether the cursor is at the end of the input.
|
|
206
|
+
*/
|
|
207
|
+
atEnd() {
|
|
208
|
+
return this.pos >= this.end;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Extracts the slice `[start, end)` of the input.
|
|
212
|
+
*/
|
|
213
|
+
slice(start, end) {
|
|
214
|
+
const input = this.input;
|
|
215
|
+
switch (this.inputKind) {
|
|
216
|
+
case 0: return input.slice(start, end);
|
|
217
|
+
case 1: return input.subarray(start, end);
|
|
218
|
+
default: return input.slice(start, end);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Records a recoverable failure at the current offset and returns {@link Fail}.
|
|
223
|
+
*/
|
|
224
|
+
backtrack(kind, expected = empty, offset = this.pos) {
|
|
225
|
+
return this.failWith("Backtrack", this.makeFailure(offset, kind, expected));
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Records an unrecoverable failure at the current offset and returns {@link Fail}.
|
|
229
|
+
*/
|
|
230
|
+
cut(kind, expected = empty, offset = this.pos) {
|
|
231
|
+
return this.failWith("Cut", this.makeFailure(offset, kind, expected));
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Records an `Incomplete` failure (only meaningful for partial input) and
|
|
235
|
+
* returns {@link Fail}.
|
|
236
|
+
*/
|
|
237
|
+
incomplete(needed, expected = empty) {
|
|
238
|
+
return this.failWith("Incomplete", new Failure(this.pos, "Incomplete", expected, empty, false, void 0, void 0, needed));
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Fails because the input ended: `Incomplete` for partial input, otherwise
|
|
242
|
+
* a `Backtrack` failure of the given kind.
|
|
243
|
+
*/
|
|
244
|
+
eoi(kind, expected, needed) {
|
|
245
|
+
return this.partial ? this.incomplete(needed, expected) : this.backtrack(kind, expected);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Records a failure carrying a user supplied cause.
|
|
249
|
+
*/
|
|
250
|
+
failCause(mode, kind, cause, offset = this.pos) {
|
|
251
|
+
return this.failWith(mode, new Failure(offset, kind, empty, empty, true, cause, void 0, 0));
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Records a failure carrying a message.
|
|
255
|
+
*/
|
|
256
|
+
failMessage(mode, kind, message, offset = this.pos) {
|
|
257
|
+
return this.failWith(mode, new Failure(offset, kind, empty, empty, false, void 0, message, 0));
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Records the given failure and returns {@link Fail}.
|
|
261
|
+
*/
|
|
262
|
+
failWith(mode, failure) {
|
|
263
|
+
this.mode = mode;
|
|
264
|
+
this.failure = failure;
|
|
265
|
+
if (mode === "Backtrack" && (this.deepest === void 0 || failure.offset >= this.deepest.offset)) this.deepest = failure;
|
|
266
|
+
return Fail;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Replaces the details of the current failure (for example to add context),
|
|
270
|
+
* keeping the record of the furthest failure consistent.
|
|
271
|
+
*/
|
|
272
|
+
replaceFailure(failure) {
|
|
273
|
+
if (this.deepest === this.failure) this.deepest = failure;
|
|
274
|
+
this.failure = failure;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* The failure to report to the user: the current failure, or the furthest
|
|
278
|
+
* failure if it lies beyond the current one and the current failure is a
|
|
279
|
+
* plain syntax error (no user cause or message).
|
|
280
|
+
*/
|
|
281
|
+
reportedFailure() {
|
|
282
|
+
const f = this.failure;
|
|
283
|
+
const d = this.deepest;
|
|
284
|
+
if (d === void 0 || d === f || d.offset <= f.offset || this.mode === "Incomplete" || f.hasCause || f.message !== void 0) return f;
|
|
285
|
+
const context = d.context.length === 0 ? f.context : [...d.context, ...f.context.filter((l) => !d.context.includes(l))];
|
|
286
|
+
return new Failure(d.offset, d.kind, d.expected, context, d.hasCause, d.cause, d.message, d.needed);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Records that, at `offset`, any of `expected` could also have been
|
|
290
|
+
* accepted. Used by parsers that stop without failing, such as `opt`,
|
|
291
|
+
* `repeat` and `Ascii.digit1`.
|
|
292
|
+
*/
|
|
293
|
+
setHint(offset, expected) {
|
|
294
|
+
if (this.hintOffset === offset) this.hintExpected = mergeExpected(this.hintExpected, expected);
|
|
295
|
+
else {
|
|
296
|
+
this.hintOffset = offset;
|
|
297
|
+
this.hintExpected = expected;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/** @internal */
|
|
301
|
+
makeFailure(offset, kind, expected) {
|
|
302
|
+
if (this.hintOffset === offset && this.hintExpected.length > 0) expected = mergeExpected(this.hintExpected, expected);
|
|
303
|
+
return new Failure(offset, kind, expected, empty, false, void 0, void 0, 0);
|
|
304
|
+
}
|
|
305
|
+
};
|
|
283
306
|
/** @internal */
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
for (const e of b) {
|
|
291
|
-
if (!out.includes(e))
|
|
292
|
-
out.push(e);
|
|
293
|
-
}
|
|
294
|
-
return out;
|
|
307
|
+
const mergeExpected = (a, b) => {
|
|
308
|
+
if (a.length === 0) return b;
|
|
309
|
+
if (b.length === 0) return a;
|
|
310
|
+
const out = a.slice();
|
|
311
|
+
for (const e of b) if (!out.includes(e)) out.push(e);
|
|
312
|
+
return out;
|
|
295
313
|
};
|
|
296
314
|
/**
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
if (expected === b.expected)
|
|
309
|
-
return b;
|
|
310
|
-
return new Failure(b.offset, b.kind, expected, b.context.length > 0 ? b.context : a.context, b.hasCause || a.hasCause, b.hasCause ? b.cause : a.cause, b.message ?? a.message, b.needed);
|
|
315
|
+
* Combines the failures of two alternatives: the furthest failure wins, and
|
|
316
|
+
* failures at the same offset have their expectations merged.
|
|
317
|
+
*
|
|
318
|
+
* @internal
|
|
319
|
+
*/
|
|
320
|
+
const mergeFailures = (a, b) => {
|
|
321
|
+
if (a.offset > b.offset) return a;
|
|
322
|
+
if (b.offset > a.offset) return b;
|
|
323
|
+
const expected = mergeExpected(a.expected, b.expected);
|
|
324
|
+
if (expected === b.expected) return b;
|
|
325
|
+
return new Failure(b.offset, b.kind, expected, b.context.length > 0 ? b.context : a.context, b.hasCause || a.hasCause, b.hasCause ? b.cause : a.cause, b.message ?? a.message, b.needed);
|
|
311
326
|
};
|
|
327
|
+
//#endregion
|
|
328
|
+
export { Fail, Failure, State, emptyStrings, fromSource, mergeExpected, mergeFailures };
|
|
329
|
+
|
|
312
330
|
//# sourceMappingURL=Input.js.map
|