@thomasfosterau/effect-parse 0.1.0 → 0.3.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.
Files changed (161) hide show
  1. package/README.md +291 -231
  2. package/dist/Ascii.d.ts +32 -53
  3. package/dist/Ascii.d.ts.map +1 -1
  4. package/dist/Ascii.js +576 -571
  5. package/dist/Ascii.js.map +1 -1
  6. package/dist/Binary.d.ts +6 -29
  7. package/dist/Binary.d.ts.map +1 -1
  8. package/dist/Binary.js +129 -116
  9. package/dist/Binary.js.map +1 -1
  10. package/dist/Bits.d.ts +4 -2
  11. package/dist/Bits.d.ts.map +1 -1
  12. package/dist/Bits.js +121 -123
  13. package/dist/Bits.js.map +1 -1
  14. package/dist/Compiler.d.ts +39 -0
  15. package/dist/Compiler.d.ts.map +1 -0
  16. package/dist/Compiler.js +48 -0
  17. package/dist/Compiler.js.map +1 -0
  18. package/dist/Encoding.d.ts +29 -46
  19. package/dist/Encoding.d.ts.map +1 -1
  20. package/dist/Encoding.js +76 -75
  21. package/dist/Encoding.js.map +1 -1
  22. package/dist/Expression.d.ts +15 -49
  23. package/dist/Expression.d.ts.map +1 -1
  24. package/dist/Expression.js +151 -132
  25. package/dist/Expression.js.map +1 -1
  26. package/dist/Input.d.ts +251 -177
  27. package/dist/Input.d.ts.map +1 -1
  28. package/dist/Input.js +409 -299
  29. package/dist/Input.js.map +1 -1
  30. package/dist/Nom.d.ts +45 -85
  31. package/dist/Nom.d.ts.map +1 -1
  32. package/dist/Nom.js +423 -453
  33. package/dist/Nom.js.map +1 -1
  34. package/dist/ParseError.d.ts +54 -49
  35. package/dist/ParseError.d.ts.map +1 -1
  36. package/dist/ParseError.js +232 -275
  37. package/dist/ParseError.js.map +1 -1
  38. package/dist/Parser.d.ts +345 -313
  39. package/dist/Parser.d.ts.map +1 -1
  40. package/dist/Parser.js +2034 -1802
  41. package/dist/Parser.js.map +1 -1
  42. package/dist/ParserSchema.d.ts +206 -7
  43. package/dist/ParserSchema.d.ts.map +1 -1
  44. package/dist/ParserSchema.js +678 -49
  45. package/dist/ParserSchema.js.map +1 -1
  46. package/dist/ParserStream.d.ts +26 -20
  47. package/dist/ParserStream.d.ts.map +1 -1
  48. package/dist/ParserStream.js +267 -255
  49. package/dist/ParserStream.js.map +1 -1
  50. package/dist/Syntax.d.ts +401 -0
  51. package/dist/Syntax.d.ts.map +1 -0
  52. package/dist/Syntax.js +717 -0
  53. package/dist/Syntax.js.map +1 -0
  54. package/dist/Text.d.ts +98 -134
  55. package/dist/Text.d.ts.map +1 -1
  56. package/dist/Text.js +534 -496
  57. package/dist/Text.js.map +1 -1
  58. package/dist/Token.d.ts +60 -42
  59. package/dist/Token.d.ts.map +1 -1
  60. package/dist/Token.js +331 -265
  61. package/dist/Token.js.map +1 -1
  62. package/dist/index.d.ts +16 -17
  63. package/dist/index.js +16 -17
  64. package/dist/internal/compiler/closure.d.ts +14 -16
  65. package/dist/internal/compiler/closure.d.ts.map +1 -1
  66. package/dist/internal/compiler/closure.js +1458 -1637
  67. package/dist/internal/compiler/closure.js.map +1 -1
  68. package/dist/internal/compiler/entries.d.ts +11 -11
  69. package/dist/internal/compiler/entries.d.ts.map +1 -1
  70. package/dist/internal/compiler/entries.js +36 -26
  71. package/dist/internal/compiler/entries.js.map +1 -1
  72. package/dist/internal/compiler/first.d.ts +19 -19
  73. package/dist/internal/compiler/first.d.ts.map +1 -1
  74. package/dist/internal/compiler/first.js +251 -227
  75. package/dist/internal/compiler/first.js.map +1 -1
  76. package/dist/internal/compiler/jit.d.ts +6 -17
  77. package/dist/internal/compiler/jit.d.ts.map +1 -1
  78. package/dist/internal/compiler/jit.js +860 -988
  79. package/dist/internal/compiler/jit.js.map +1 -1
  80. package/dist/internal/compiler/registry.d.ts +20 -21
  81. package/dist/internal/compiler/registry.d.ts.map +1 -1
  82. package/dist/internal/compiler/registry.js +21 -41
  83. package/dist/internal/compiler/registry.js.map +1 -1
  84. package/dist/internal/compiler/sets.d.ts +9 -13
  85. package/dist/internal/compiler/sets.d.ts.map +1 -1
  86. package/dist/internal/compiler/sets.js +76 -73
  87. package/dist/internal/compiler/sets.js.map +1 -1
  88. package/dist/internal/entries.d.ts +3 -3
  89. package/dist/internal/entries.d.ts.map +1 -1
  90. package/dist/internal/entries.js +38 -30
  91. package/dist/internal/entries.js.map +1 -1
  92. package/dist/internal/node.d.ts +177 -173
  93. package/dist/internal/node.d.ts.map +1 -1
  94. package/dist/internal/node.js +77 -66
  95. package/dist/internal/node.js.map +1 -1
  96. package/dist/internal/numbers.d.ts +7 -8
  97. package/dist/internal/numbers.d.ts.map +1 -1
  98. package/dist/internal/numbers.js +246 -276
  99. package/dist/internal/numbers.js.map +1 -1
  100. package/dist/internal/resume.d.ts +6 -24
  101. package/dist/internal/resume.d.ts.map +1 -1
  102. package/dist/internal/resume.js +30 -29
  103. package/dist/internal/resume.js.map +1 -1
  104. package/dist/internal/run.d.ts +15 -0
  105. package/dist/internal/run.d.ts.map +1 -0
  106. package/dist/internal/run.js +36 -0
  107. package/dist/internal/run.js.map +1 -0
  108. package/dist/internal/stack.d.ts +16 -0
  109. package/dist/internal/stack.d.ts.map +1 -0
  110. package/dist/internal/stack.js +36 -0
  111. package/dist/internal/stack.js.map +1 -0
  112. package/dist/internal/syntax.d.ts +147 -0
  113. package/dist/internal/syntax.d.ts.map +1 -0
  114. package/dist/internal/syntax.js +309 -0
  115. package/dist/internal/syntax.js.map +1 -0
  116. package/dist/internal/text.d.ts +10 -2
  117. package/dist/internal/text.d.ts.map +1 -1
  118. package/dist/internal/text.js +295 -345
  119. package/dist/internal/text.js.map +1 -1
  120. package/dist/internal/ties.d.ts +30 -0
  121. package/dist/internal/ties.d.ts.map +1 -0
  122. package/dist/internal/ties.js +67 -0
  123. package/dist/internal/ties.js.map +1 -0
  124. package/dist/internal/tokens.d.ts +25 -30
  125. package/dist/internal/tokens.d.ts.map +1 -1
  126. package/dist/internal/tokens.js +369 -363
  127. package/dist/internal/tokens.js.map +1 -1
  128. package/package.json +42 -28
  129. package/src/Ascii.ts +278 -187
  130. package/src/Binary.ts +150 -44
  131. package/src/Bits.ts +6 -3
  132. package/src/Compiler.ts +98 -0
  133. package/src/Expression.ts +24 -16
  134. package/src/Input.ts +210 -35
  135. package/src/Nom.ts +4 -3
  136. package/src/ParseError.ts +49 -52
  137. package/src/Parser.ts +1199 -799
  138. package/src/ParserSchema.ts +982 -23
  139. package/src/ParserStream.ts +104 -80
  140. package/src/Syntax.ts +900 -0
  141. package/src/Text.ts +272 -187
  142. package/src/Token.ts +180 -87
  143. package/src/index.ts +2 -0
  144. package/src/internal/compiler/closure.ts +121 -88
  145. package/src/internal/compiler/entries.ts +21 -8
  146. package/src/internal/compiler/first.ts +17 -15
  147. package/src/internal/compiler/jit.ts +360 -157
  148. package/src/internal/compiler/registry.ts +12 -33
  149. package/src/internal/compiler/sets.ts +17 -11
  150. package/src/internal/entries.ts +4 -2
  151. package/src/internal/node.ts +51 -37
  152. package/src/internal/numbers.ts +22 -20
  153. package/src/internal/resume.ts +8 -4
  154. package/src/internal/run.ts +41 -0
  155. package/src/internal/stack.ts +41 -0
  156. package/src/internal/syntax.ts +426 -0
  157. package/src/internal/text.ts +32 -25
  158. package/src/internal/ties.ts +83 -0
  159. package/src/internal/tokens.ts +96 -51
  160. package/dist/index.d.ts.map +0 -1
  161. package/dist/index.js.map +0 -1
package/src/Token.ts CHANGED
@@ -20,12 +20,14 @@
20
20
  *
21
21
  * @since 0.1.0
22
22
  */
23
+ import * as Predicate from "effect/Predicate"
23
24
  import type { Input, Slice, State, Token } from "./Input.js"
24
25
  import {
25
26
  advance,
27
+ codePointPredicate,
26
28
  compileAny,
27
29
  countTokens,
28
- describeBytes,
30
+ describeLiteral,
29
31
  End,
30
32
  indexOf,
31
33
  matchLiteral,
@@ -67,9 +69,65 @@ export interface TokenRange<T> {
67
69
  */
68
70
  export const range = <T extends string | number>(from: T, to: T): TokenRange<T> => ({ _tag: "TokenRange", from, to })
69
71
 
72
+ declare const CodePointsBrand: unique symbol
73
+
74
+ /**
75
+ * A predicate over code points, made with {@link codePoints}. In a token set
76
+ * it receives each character as a number, so testing a character allocates
77
+ * nothing.
78
+ *
79
+ * @since 0.2.0
80
+ * @category models
81
+ */
82
+ export interface CodePoints {
83
+ (codePoint: number): boolean
84
+ readonly [CodePointsBrand]: true
85
+ }
86
+
87
+ /**
88
+ * Declares a character class as a predicate over code points, for token sets
89
+ * on string, `Text` and byte inputs. `name` describes it in error messages.
90
+ *
91
+ * A plain `(char: string) => boolean` predicate receives each character as a
92
+ * string, which costs an allocation per character tested; a `codePoints`
93
+ * predicate receives the code point itself (a byte, on byte input).
94
+ *
95
+ * `ranges` optionally lists the code points the predicate accepts, as
96
+ * inclusive `[from, to]` pairs. Compiled parsers then test the ranges
97
+ * instead of calling the predicate, so they must agree with it exactly.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * import { Parser, Token } from "@thomasfosterau/effect-parse"
102
+ *
103
+ * const isNameStart = Token.codePoints(
104
+ * "name start",
105
+ * (c) => (c >= 0x61 && c <= 0x7a) || c === 0x5f || c >= 0xc0,
106
+ * [[0x5f, 0x5f], [0x61, 0x7a], [0xc0, 0x10ffff]]
107
+ * )
108
+ * const name = Token.takeWhile([isNameStart, Token.range("0", "9")], { min: 1 })
109
+ * ```
110
+ *
111
+ * @since 0.2.0
112
+ * @category constructors
113
+ */
114
+ export const codePoints = (
115
+ name: string,
116
+ predicate: (codePoint: number) => boolean,
117
+ ranges?: ReadonlyArray<readonly [number, number]>
118
+ ): CodePoints =>
119
+ // Wrapped, so the caller's function is left unmarked
120
+ codePointPredicate(
121
+ name,
122
+ (c: number): boolean => predicate(c),
123
+ ranges?.map(([from, to]) => [from, to] as const)
124
+ ) as unknown as CodePoints
125
+
70
126
  /**
71
127
  * A set of string tokens: the characters of a string, a range, a predicate,
72
- * or an array of these.
128
+ * or an array of these. Strings, ranges, {@link codePoints} predicates and
129
+ * the `Ascii` and `Text` predicates test characters without allocating; a
130
+ * `(char: string) => boolean` predicate allocates a string per character.
73
131
  *
74
132
  * @since 0.1.0
75
133
  * @category models
@@ -77,6 +135,7 @@ export const range = <T extends string | number>(from: T, to: T): TokenRange<T>
77
135
  export type StringTokenSet =
78
136
  | string
79
137
  | TokenRange<string>
138
+ | CodePoints
80
139
  | ((char: string) => boolean)
81
140
  | ReadonlyArray<StringTokenSet>
82
141
 
@@ -92,6 +151,7 @@ export type ByteTokenSet =
92
151
  | string
93
152
  | Uint8Array
94
153
  | TokenRange<number>
154
+ | CodePoints
95
155
  | ((byte: number) => boolean)
96
156
  | ReadonlyArray<ByteTokenSet>
97
157
 
@@ -102,10 +162,13 @@ export type ByteTokenSet =
102
162
  * @since 0.1.0
103
163
  * @category models
104
164
  */
105
- export type TokenSet<I> = I extends string ? StringTokenSet
106
- : I extends Uint8Array ? ByteTokenSet
107
- : I extends ReadonlyArray<infer T> ? ((token: T) => boolean) | ReadonlyArray<T>
108
- : never
165
+ export type TokenSet<I> = I extends string
166
+ ? StringTokenSet
167
+ : I extends Uint8Array
168
+ ? ByteTokenSet
169
+ : I extends ReadonlyArray<infer T>
170
+ ? ((token: T) => boolean) | ReadonlyArray<T>
171
+ : never
109
172
 
110
173
  const expectedAny = ["any token"]
111
174
 
@@ -140,7 +203,7 @@ const anyStep = (state: State<Input>): unknown => {
140
203
  * @since 0.1.0
141
204
  * @category tokens
142
205
  */
143
- export const any: Parser<string> = described(anyStep as any, "any", { _tag: "Any", encoding: undefined })
206
+ export const any: Parser<string> = /*#__PURE__*/ described(anyStep as any, "any", { _tag: "Any", encoding: undefined })
144
207
 
145
208
  /**
146
209
  * Matches any single token of an input of type `I`.
@@ -182,28 +245,28 @@ export const literal: {
182
245
 
183
246
  /** @internal */
184
247
  export const literalImpl = (lit: Input, caseless: boolean): Parser<any, never, never, any> => {
185
- const description = typeof lit === "string"
186
- ? JSON.stringify(lit)
187
- : lit instanceof Uint8Array
188
- ? describeBytes(lit)
189
- : `[${lit.map((t) => JSON.stringify(t)).join(", ")}]`
248
+ const description = describeLiteral(lit)
190
249
  const expected = [caseless ? `${description} (case insensitive)` : description]
191
250
  // A string literal may also be matched against byte input (as UTF-8)
192
251
  let asBytes: Uint8Array | undefined
193
- const literalKind = typeof lit === "string" ? 0 : lit instanceof Uint8Array ? 1 : 2
194
- return described((state: State<Input>) => {
195
- const pos = state.pos
196
- const l = literalKind === 0 && state.inputKind === 1 ? (asBytes ??= new TextEncoder().encode(lit as string)) : lit
197
- const len = l.length
198
- const r = matchLiteral(state, l, caseless)
199
- if (r === -1) return state.backtrack("Literal", expected)
200
- if (r === -2) {
201
- if (state.partial) return state.incomplete(len - (state.end - pos), expected)
202
- return state.backtrack("Literal", expected)
203
- }
204
- state.pos = pos + len
205
- return caseless || state.inputKind !== literalKind ? state.slice(pos, pos + len) : lit
206
- }, description, { _tag: "Literal", literal: lit, caseless, encoding: undefined })
252
+ const literalKind = Predicate.isString(lit) ? 0 : lit instanceof Uint8Array ? 1 : 2
253
+ return described(
254
+ (state: State<Input>) => {
255
+ const pos = state.pos
256
+ const l = literalKind === 0 && state.inputKind === 1 ? (asBytes ??= new TextEncoder().encode(lit as string)) : lit
257
+ const len = l.length
258
+ const r = matchLiteral(state, l, caseless)
259
+ if (r === -1) return state.backtrack("Literal", expected)
260
+ if (r === -2) {
261
+ if (state.partial) return state.incomplete(len - (state.end - pos), expected)
262
+ return state.backtrack("Literal", expected)
263
+ }
264
+ state.pos = pos + len
265
+ return caseless || state.inputKind !== literalKind ? state.slice(pos, pos + len) : lit
266
+ },
267
+ description,
268
+ { _tag: "Literal", literal: lit, caseless, encoding: undefined }
269
+ )
207
270
  }
208
271
 
209
272
  /**
@@ -222,15 +285,21 @@ export const literalImpl = (lit: Input, caseless: boolean): Parser<any, never, n
222
285
  * @since 0.1.0
223
286
  * @category tokens
224
287
  */
225
- export const oneOf = <I extends Input = string>(set: TokenSet<I>): Parser<Token<NoInfer<I>>, never, never, NoInfer<I>> => {
288
+ export const oneOf = <I extends Input = string>(
289
+ set: TokenSet<I>
290
+ ): Parser<Token<NoInfer<I>>, never, never, NoInfer<I>> => {
226
291
  const m = compileAny(set)
227
292
  const expected = [m.description]
228
- return described((state) => {
229
- const t = nextIf(state, m, false)
230
- if (t === End) return state.eoi("OneOf", expected, 1)
231
- if (t === NoMatch) return state.backtrack("OneOf", expected)
232
- return t as Token<I>
233
- }, m.description, { _tag: "OneOf", set, negate: false, encoding: undefined })
293
+ return described(
294
+ (state) => {
295
+ const t = nextIf(state, m, false)
296
+ if (t === End) return state.eoi("OneOf", expected, 1)
297
+ if (t === NoMatch) return state.backtrack("OneOf", expected)
298
+ return t as Token<I>
299
+ },
300
+ m.description,
301
+ { _tag: "OneOf", set, negate: false, encoding: undefined }
302
+ )
234
303
  }
235
304
 
236
305
  /**
@@ -240,15 +309,21 @@ export const oneOf = <I extends Input = string>(set: TokenSet<I>): Parser<Token<
240
309
  * @since 0.1.0
241
310
  * @category tokens
242
311
  */
243
- export const noneOf = <I extends Input = string>(set: TokenSet<I>): Parser<Token<NoInfer<I>>, never, never, NoInfer<I>> => {
312
+ export const noneOf = <I extends Input = string>(
313
+ set: TokenSet<I>
314
+ ): Parser<Token<NoInfer<I>>, never, never, NoInfer<I>> => {
244
315
  const m = compileAny(set)
245
316
  const expected = [`anything but ${m.description}`]
246
- return described((state) => {
247
- const t = nextIf(state, m, true)
248
- if (t === End) return state.eoi("NoneOf", expected, 1)
249
- if (t === NoMatch) return state.backtrack("NoneOf", expected)
250
- return t as Token<I>
251
- }, expected[0], { _tag: "OneOf", set, negate: true, encoding: undefined })
317
+ return described(
318
+ (state) => {
319
+ const t = nextIf(state, m, true)
320
+ if (t === End) return state.eoi("NoneOf", expected, 1)
321
+ if (t === NoMatch) return state.backtrack("NoneOf", expected)
322
+ return t as Token<I>
323
+ },
324
+ expected[0],
325
+ { _tag: "OneOf", set, negate: true, encoding: undefined }
326
+ )
252
327
  }
253
328
 
254
329
  /**
@@ -259,18 +334,22 @@ export const noneOf = <I extends Input = string>(set: TokenSet<I>): Parser<Token
259
334
  */
260
335
  export const take = <I extends Input = string>(count: number): Parser<Slice<NoInfer<I>>, never, never, NoInfer<I>> => {
261
336
  const expected = [count === 1 ? "1 token" : `${count} tokens`]
262
- return described((state) => {
263
- const start = state.pos
264
- const { count: got, offset } = advance(state, start, count)
265
- if (got < count) return state.eoi("Take", expected, count - got)
266
- state.pos = offset
267
- return state.slice(start, offset)
268
- }, "take", { _tag: "Take", count, encoding: undefined })
337
+ return described(
338
+ (state) => {
339
+ const start = state.pos
340
+ const { count: got, offset } = advance(state, start, count)
341
+ if (got < count) return state.eoi("Take", expected, count - got)
342
+ state.pos = offset
343
+ return state.slice(start, offset)
344
+ },
345
+ "take",
346
+ { _tag: "Take", count, encoding: undefined }
347
+ )
269
348
  }
270
349
 
271
350
  const normalize = (r: Range | undefined): [number, number] => {
272
351
  if (r === undefined) return [0, Infinity]
273
- if (typeof r === "number") return [r, r]
352
+ if (Predicate.isNumber(r)) return [r, r]
274
353
  return [r.min ?? 0, r.max ?? Infinity]
275
354
  }
276
355
 
@@ -287,16 +366,20 @@ export const takeWhileImpl = <I extends Input>(
287
366
  const m = compileAny(set)
288
367
  const [min, max] = normalize(r)
289
368
  const expected = [description ?? (negate ? `anything but ${m.description}` : m.description)]
290
- return described((state) => {
291
- const start = state.pos
292
- const { count, hitEnd, offset } = scan(state, m, negate, max)
293
- if (hitEnd && state.partial) return state.incomplete(1, expected)
294
- if (count < min) return state.backtrack(kind, expected, offset)
295
- // More matching tokens would have been accepted where we stopped
296
- if (hint && count < max) state.setHint(offset, expected)
297
- state.pos = offset
298
- return state.slice(start, offset)
299
- }, name, { _tag: "TakeWhile", set, negate, min, max, encoding: undefined })
369
+ return described(
370
+ (state) => {
371
+ const start = state.pos
372
+ const { count, hitEnd, offset } = scan(state, m, negate, max)
373
+ if (hitEnd && state.partial) return state.incomplete(1, expected)
374
+ if (count < min) return state.backtrack(kind, expected, offset)
375
+ // More matching tokens would have been accepted where we stopped
376
+ if (hint && count < max) state.setHint(offset, expected)
377
+ state.pos = offset
378
+ return state.slice(start, offset)
379
+ },
380
+ name,
381
+ { _tag: "TakeWhile", set, negate, min, max, encoding: undefined }
382
+ )
300
383
  }
301
384
 
302
385
  /**
@@ -349,28 +432,30 @@ export const takeUntil: {
349
432
  <T>(literal: ReadonlyArray<T>, range?: Range): Parser<ReadonlyArray<T>, never, never, ReadonlyArray<T>>
350
433
  } = (lit: Input, r?: Range): Parser<any, never, never, any> => {
351
434
  const [min, max] = normalize(r)
352
- const description = typeof lit === "string"
353
- ? JSON.stringify(lit)
354
- : lit instanceof Uint8Array
355
- ? describeBytes(lit)
356
- : `[${lit.map((t) => JSON.stringify(t)).join(", ")}]`
435
+ const description = describeLiteral(lit)
357
436
  const expected = [description]
358
- return described((state: State<Input>) => {
359
- const start = state.pos
360
- const idx = indexOf(state, lit, start)
361
- if (idx < 0) {
362
- if (state.partial) return state.incomplete(0, expected)
363
- return state.backtrack("TakeUntil", expected, state.end)
364
- }
365
- // As in winnow, the first occurrence must lie within the range
366
- if (min > 0 || max !== Infinity) {
367
- const count = countTokens(state, start, idx)
368
- if (count < min) return state.backtrack("TakeUntil", expected, idx)
369
- if (count > max) return state.backtrack("TakeUntil", expected)
370
- }
371
- state.pos = idx
372
- return state.slice(start, idx)
373
- }, "takeUntil", { _tag: "TakeUntil", literal: lit, ...bounds(r), encoding: undefined })
437
+ return described(
438
+ (state: State<Input>) => {
439
+ const start = state.pos
440
+ const idx = indexOf(state, lit, start)
441
+ if (idx < 0) {
442
+ if (state.partial) return state.incomplete(0, expected)
443
+ return state.backtrack("TakeUntil", expected, state.end)
444
+ }
445
+ // The literal was read but is not consumed (a string literal is up to three bytes per unit of UTF-8)
446
+ state.syntax?.read(idx + lit.length * (Predicate.isString(lit) && state.inputKind === 1 ? 3 : 1))
447
+ // As in winnow, the first occurrence must lie within the range
448
+ if (min > 0 || max !== Infinity) {
449
+ const count = countTokens(state, start, idx)
450
+ if (count < min) return state.backtrack("TakeUntil", expected, idx)
451
+ if (count > max) return state.backtrack("TakeUntil", expected)
452
+ }
453
+ state.pos = idx
454
+ return state.slice(start, idx)
455
+ },
456
+ "takeUntil",
457
+ { _tag: "TakeUntil", literal: lit, ...bounds(r), encoding: undefined }
458
+ )
374
459
  }
375
460
 
376
461
  /**
@@ -379,11 +464,15 @@ export const takeUntil: {
379
464
  * @since 0.1.0
380
465
  * @category slices
381
466
  */
382
- export const rest: Parser<string> = described((state: State<any>) => {
383
- const start = state.pos
384
- state.pos = state.end
385
- return state.slice(start, state.end) as string
386
- }, "rest", { _tag: "Rest", encoding: undefined })
467
+ export const rest: Parser<string> = /*#__PURE__*/ described(
468
+ (state: State<any>) => {
469
+ const start = state.pos
470
+ state.pos = state.end
471
+ return state.slice(start, state.end) as string
472
+ },
473
+ "rest",
474
+ { _tag: "Rest", encoding: undefined }
475
+ )
387
476
 
388
477
  /**
389
478
  * Takes the rest of an input of type `I`.
@@ -400,9 +489,13 @@ export const restOf = <I extends Input = string>(): Parser<Slice<NoInfer<I>>, ne
400
489
  * @since 0.1.0
401
490
  * @category slices
402
491
  */
403
- export const restLen: Parser<number, never, never, Input> = described((state) => state.end - state.pos, "restLen", {
404
- _tag: "RestLen"
405
- })
492
+ export const restLen: Parser<number, never, never, Input> = /*#__PURE__*/ described(
493
+ (state) => state.end - state.pos,
494
+ "restLen",
495
+ {
496
+ _tag: "RestLen"
497
+ }
498
+ )
406
499
 
407
500
  /**
408
501
  * Matches a token satisfying a predicate (nom's `satisfy`). Equivalent to
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  */
4
4
  export * as Input from "./Input.js"
5
5
  export * as Parser from "./Parser.js"
6
+ export * as Compiler from "./Compiler.js"
6
7
  export * as ParseError from "./ParseError.js"
7
8
  export * as Token from "./Token.js"
8
9
  export * as Ascii from "./Ascii.js"
@@ -14,3 +15,4 @@ export * as Expression from "./Expression.js"
14
15
  export * as Nom from "./Nom.js"
15
16
  export * as ParserSchema from "./ParserSchema.js"
16
17
  export * as ParserStream from "./ParserStream.js"
18
+ export * as Syntax from "./Syntax.js"