@thomasfosterau/effect-parse 0.0.0-stage → 0.1.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 (133) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +550 -2
  3. package/dist/Ascii.d.ts +392 -0
  4. package/dist/Ascii.d.ts.map +1 -0
  5. package/dist/Ascii.js +610 -0
  6. package/dist/Ascii.js.map +1 -0
  7. package/dist/Binary.d.ts +153 -0
  8. package/dist/Binary.d.ts.map +1 -0
  9. package/dist/Binary.js +171 -0
  10. package/dist/Binary.js.map +1 -0
  11. package/dist/Bits.d.ts +60 -0
  12. package/dist/Bits.d.ts.map +1 -0
  13. package/dist/Bits.js +144 -0
  14. package/dist/Bits.js.map +1 -0
  15. package/dist/Encoding.d.ts +116 -0
  16. package/dist/Encoding.d.ts.map +1 -0
  17. package/dist/Encoding.js +85 -0
  18. package/dist/Encoding.js.map +1 -0
  19. package/dist/Expression.d.ts +124 -0
  20. package/dist/Expression.d.ts.map +1 -0
  21. package/dist/Expression.js +139 -0
  22. package/dist/Expression.js.map +1 -0
  23. package/dist/Input.d.ts +301 -0
  24. package/dist/Input.d.ts.map +1 -0
  25. package/dist/Input.js +312 -0
  26. package/dist/Input.js.map +1 -0
  27. package/dist/Nom.d.ts +518 -0
  28. package/dist/Nom.d.ts.map +1 -0
  29. package/dist/Nom.js +519 -0
  30. package/dist/Nom.js.map +1 -0
  31. package/dist/ParseError.d.ts +120 -0
  32. package/dist/ParseError.d.ts.map +1 -0
  33. package/dist/ParseError.js +301 -0
  34. package/dist/ParseError.js.map +1 -0
  35. package/dist/Parser.d.ts +1312 -0
  36. package/dist/Parser.d.ts.map +1 -0
  37. package/dist/Parser.js +1936 -0
  38. package/dist/Parser.js.map +1 -0
  39. package/dist/ParserSchema.d.ts +31 -0
  40. package/dist/ParserSchema.d.ts.map +1 -0
  41. package/dist/ParserSchema.js +56 -0
  42. package/dist/ParserSchema.js.map +1 -0
  43. package/dist/ParserStream.d.ts +127 -0
  44. package/dist/ParserStream.d.ts.map +1 -0
  45. package/dist/ParserStream.js +270 -0
  46. package/dist/ParserStream.js.map +1 -0
  47. package/dist/Text.d.ts +330 -0
  48. package/dist/Text.d.ts.map +1 -0
  49. package/dist/Text.js +529 -0
  50. package/dist/Text.js.map +1 -0
  51. package/dist/Token.d.ts +225 -0
  52. package/dist/Token.d.ts.map +1 -0
  53. package/dist/Token.js +294 -0
  54. package/dist/Token.js.map +1 -0
  55. package/dist/index.d.ts +17 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +17 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/internal/compiler/closure.d.ts +25 -0
  60. package/dist/internal/compiler/closure.d.ts.map +1 -0
  61. package/dist/internal/compiler/closure.js +1668 -0
  62. package/dist/internal/compiler/closure.js.map +1 -0
  63. package/dist/internal/compiler/entries.d.ts +19 -0
  64. package/dist/internal/compiler/entries.d.ts.map +1 -0
  65. package/dist/internal/compiler/entries.js +32 -0
  66. package/dist/internal/compiler/entries.js.map +1 -0
  67. package/dist/internal/compiler/first.d.ts +33 -0
  68. package/dist/internal/compiler/first.d.ts.map +1 -0
  69. package/dist/internal/compiler/first.js +235 -0
  70. package/dist/internal/compiler/first.js.map +1 -0
  71. package/dist/internal/compiler/jit.d.ts +20 -0
  72. package/dist/internal/compiler/jit.d.ts.map +1 -0
  73. package/dist/internal/compiler/jit.js +1030 -0
  74. package/dist/internal/compiler/jit.js.map +1 -0
  75. package/dist/internal/compiler/registry.d.ts +34 -0
  76. package/dist/internal/compiler/registry.d.ts.map +1 -0
  77. package/dist/internal/compiler/registry.js +46 -0
  78. package/dist/internal/compiler/registry.js.map +1 -0
  79. package/dist/internal/compiler/sets.d.ts +29 -0
  80. package/dist/internal/compiler/sets.d.ts.map +1 -0
  81. package/dist/internal/compiler/sets.js +85 -0
  82. package/dist/internal/compiler/sets.js.map +1 -0
  83. package/dist/internal/entries.d.ts +27 -0
  84. package/dist/internal/entries.d.ts.map +1 -0
  85. package/dist/internal/entries.js +42 -0
  86. package/dist/internal/entries.js.map +1 -0
  87. package/dist/internal/node.d.ts +251 -0
  88. package/dist/internal/node.d.ts.map +1 -0
  89. package/dist/internal/node.js +73 -0
  90. package/dist/internal/node.js.map +1 -0
  91. package/dist/internal/numbers.d.ts +41 -0
  92. package/dist/internal/numbers.d.ts.map +1 -0
  93. package/dist/internal/numbers.js +302 -0
  94. package/dist/internal/numbers.js.map +1 -0
  95. package/dist/internal/resume.d.ts +39 -0
  96. package/dist/internal/resume.d.ts.map +1 -0
  97. package/dist/internal/resume.js +37 -0
  98. package/dist/internal/resume.js.map +1 -0
  99. package/dist/internal/text.d.ts +72 -0
  100. package/dist/internal/text.d.ts.map +1 -0
  101. package/dist/internal/text.js +391 -0
  102. package/dist/internal/text.js.map +1 -0
  103. package/dist/internal/tokens.d.ts +93 -0
  104. package/dist/internal/tokens.d.ts.map +1 -0
  105. package/dist/internal/tokens.js +400 -0
  106. package/dist/internal/tokens.js.map +1 -0
  107. package/package.json +115 -3
  108. package/src/Ascii.ts +741 -0
  109. package/src/Binary.ts +228 -0
  110. package/src/Bits.ts +192 -0
  111. package/src/Encoding.ts +128 -0
  112. package/src/Expression.ts +245 -0
  113. package/src/Input.ts +429 -0
  114. package/src/Nom.ts +642 -0
  115. package/src/ParseError.ts +378 -0
  116. package/src/Parser.ts +2763 -0
  117. package/src/ParserSchema.ts +87 -0
  118. package/src/ParserStream.ts +390 -0
  119. package/src/Text.ts +757 -0
  120. package/src/Token.ts +416 -0
  121. package/src/index.ts +16 -0
  122. package/src/internal/compiler/closure.ts +1583 -0
  123. package/src/internal/compiler/entries.ts +36 -0
  124. package/src/internal/compiler/first.ts +252 -0
  125. package/src/internal/compiler/jit.ts +1091 -0
  126. package/src/internal/compiler/registry.ts +79 -0
  127. package/src/internal/compiler/sets.ts +100 -0
  128. package/src/internal/entries.ts +51 -0
  129. package/src/internal/node.ts +207 -0
  130. package/src/internal/numbers.ts +291 -0
  131. package/src/internal/resume.ts +55 -0
  132. package/src/internal/text.ts +411 -0
  133. package/src/internal/tokens.ts +409 -0
package/src/Nom.ts ADDED
@@ -0,0 +1,642 @@
1
+ /**
2
+ * nom-flavoured names for effect-parse's parsers and combinators.
3
+ *
4
+ * effect-parse's main API follows winnow's naming (in camelCase). This module
5
+ * offers the names, and argument orders, that nom users know, so grammars
6
+ * can be ported with minimal changes:
7
+ *
8
+ * | nom | effect-parse |
9
+ * |---|---|
10
+ * | `tag("abc")` | `Token.literal("abc")` |
11
+ * | `many0(p)` | `Parser.repeat(p)` |
12
+ * | `separated_list1(sep, p)` | `Parser.separated(p, sep, { min: 1 })` |
13
+ * | `map_res(p, f)` | `Parser.tryMap(p, f)` |
14
+ * | `recognize(p)` | `Parser.taken(p)` |
15
+ * | `value(v, p)` | `Parser.as(p, v)` |
16
+ *
17
+ * nom's `streaming` and `complete` variants are not separate functions here.
18
+ * Whether input is partial is decided by the runner (`Parser.parsePartial`
19
+ * vs `Parser.parse`).
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import { Result } from "effect"
24
+ * import { Nom, Parser } from "@thomasfosterau/effect-parse"
25
+ *
26
+ * const hexPrimary = Nom.mapRes(
27
+ * Nom.takeWhileMN(2, 2, (c: string) => /[0-9a-fA-F]/.test(c)),
28
+ * (s) => Result.succeed(parseInt(s, 16))
29
+ * )
30
+ * const hexColor = Nom.preceded(
31
+ * Nom.tag("#"),
32
+ * Nom.tuple(hexPrimary, hexPrimary, hexPrimary)
33
+ * )
34
+ *
35
+ * Parser.parse(hexColor, "#2F14DF") // Result.succeed([47, 20, 223])
36
+ * ```
37
+ *
38
+ * @since 0.1.0
39
+ */
40
+ import * as Option from "effect/Option"
41
+ import * as Result from "effect/Result"
42
+ import * as Ascii from "./Ascii.js"
43
+ import * as Binary from "./Binary.js"
44
+ import type { Input, Slice, Token as TokenOf } from "./Input.js"
45
+ import type { Parser } from "./Parser.js"
46
+ import * as P from "./Parser.js"
47
+ import * as Token from "./Token.js"
48
+ import type { TokenSet } from "./Token.js"
49
+
50
+ // -----------------------------------------------------------------------------
51
+ // bytes / character
52
+ // -----------------------------------------------------------------------------
53
+
54
+ /**
55
+ * Matches a literal (nom's `tag`).
56
+ *
57
+ * @since 0.1.0
58
+ * @category bytes
59
+ */
60
+ export const tag = Token.literal
61
+
62
+ /**
63
+ * Matches a literal, ignoring ASCII case (nom's `tag_no_case`).
64
+ *
65
+ * @since 0.1.0
66
+ * @category bytes
67
+ */
68
+ export const tagNoCase = Ascii.caseless
69
+
70
+ /**
71
+ * Matches a single character (nom's `char`).
72
+ *
73
+ * @since 0.1.0
74
+ * @category character
75
+ */
76
+ export const char = <const C extends string>(c: C): Parser<C> => Token.literal(c)
77
+
78
+ /**
79
+ * Matches any character (nom's `anychar`).
80
+ *
81
+ * @since 0.1.0
82
+ * @category character
83
+ */
84
+ export const anychar: Parser<string> = Token.any
85
+
86
+ /**
87
+ * @since 0.1.0
88
+ * @category character
89
+ */
90
+ export const oneOf = Token.oneOf
91
+
92
+ /**
93
+ * @since 0.1.0
94
+ * @category character
95
+ */
96
+ export const noneOf = Token.noneOf
97
+
98
+ /**
99
+ * @since 0.1.0
100
+ * @category character
101
+ */
102
+ export const satisfy = Token.satisfy
103
+
104
+ /**
105
+ * The longest non-empty run of tokens from a set (nom's `is_a`).
106
+ *
107
+ * @since 0.1.0
108
+ * @category bytes
109
+ */
110
+ export const isA = <I extends Input = string>(set: TokenSet<I>): Parser<Slice<NoInfer<I>>, never, never, NoInfer<I>> =>
111
+ Token.takeWhile<I>(set, { min: 1 })
112
+
113
+ /**
114
+ * The longest non-empty run of tokens *not* from a set (nom's `is_not`).
115
+ *
116
+ * @since 0.1.0
117
+ * @category bytes
118
+ */
119
+ export const isNot = <I extends Input = string>(set: TokenSet<I>): Parser<Slice<NoInfer<I>>, never, never, NoInfer<I>> =>
120
+ Token.takeTill<I>(set, { min: 1 })
121
+
122
+ /**
123
+ * @since 0.1.0
124
+ * @category bytes
125
+ */
126
+ export const take = Token.take
127
+
128
+ /**
129
+ * @since 0.1.0
130
+ * @category bytes
131
+ */
132
+ export const takeWhile = <I extends Input = string>(
133
+ predicate: (token: TokenOf<I>) => boolean
134
+ ): Parser<Slice<NoInfer<I>>, never, never, NoInfer<I>> => Token.takeWhile<I>(predicate as any)
135
+
136
+ /**
137
+ * @since 0.1.0
138
+ * @category bytes
139
+ */
140
+ export const takeWhile1 = <I extends Input = string>(
141
+ predicate: (token: TokenOf<I>) => boolean
142
+ ): Parser<Slice<NoInfer<I>>, never, never, NoInfer<I>> => Token.takeWhile<I>(predicate as any, { min: 1 })
143
+
144
+ /**
145
+ * @since 0.1.0
146
+ * @category bytes
147
+ */
148
+ export const takeWhileMN = <I extends Input = string>(
149
+ m: number,
150
+ n: number,
151
+ predicate: (token: TokenOf<I>) => boolean
152
+ ): Parser<Slice<NoInfer<I>>, never, never, NoInfer<I>> => Token.takeWhile<I>(predicate as any, { min: m, max: n })
153
+
154
+ /**
155
+ * @since 0.1.0
156
+ * @category bytes
157
+ */
158
+ export const takeTill = <I extends Input = string>(
159
+ predicate: (token: TokenOf<I>) => boolean
160
+ ): Parser<Slice<NoInfer<I>>, never, never, NoInfer<I>> => Token.takeTill<I>(predicate as any)
161
+
162
+ /**
163
+ * @since 0.1.0
164
+ * @category bytes
165
+ */
166
+ export const takeTill1 = <I extends Input = string>(
167
+ predicate: (token: TokenOf<I>) => boolean
168
+ ): Parser<Slice<NoInfer<I>>, never, never, NoInfer<I>> => Token.takeTill<I>(predicate as any, { min: 1 })
169
+
170
+ /**
171
+ * @since 0.1.0
172
+ * @category bytes
173
+ */
174
+ export const takeUntil = Token.takeUntil
175
+
176
+ /**
177
+ * Recognizes an escaped string (nom's `escaped`).
178
+ *
179
+ * @since 0.1.0
180
+ * @category bytes
181
+ */
182
+ export const escaped = Ascii.takeEscaped
183
+
184
+ /**
185
+ * Unescapes an escaped string (nom's `escaped_transform`).
186
+ *
187
+ * @since 0.1.0
188
+ * @category bytes
189
+ */
190
+ export const escapedTransform = Ascii.escaped
191
+
192
+ /** @since 0.1.0 @category character */
193
+ export const alpha0 = Ascii.alpha0
194
+ /** @since 0.1.0 @category character */
195
+ export const alpha1 = Ascii.alpha1
196
+ /** @since 0.1.0 @category character */
197
+ export const digit0 = Ascii.digit0
198
+ /** @since 0.1.0 @category character */
199
+ export const digit1 = Ascii.digit1
200
+ /** @since 0.1.0 @category character */
201
+ export const hexDigit0 = Ascii.hexDigit0
202
+ /** @since 0.1.0 @category character */
203
+ export const hexDigit1 = Ascii.hexDigit1
204
+ /** @since 0.1.0 @category character */
205
+ export const octDigit0 = Ascii.octDigit0
206
+ /** @since 0.1.0 @category character */
207
+ export const octDigit1 = Ascii.octDigit1
208
+ /** @since 0.1.0 @category character */
209
+ export const alphanumeric0 = Ascii.alphanumeric0
210
+ /** @since 0.1.0 @category character */
211
+ export const alphanumeric1 = Ascii.alphanumeric1
212
+ /** @since 0.1.0 @category character */
213
+ export const space0 = Ascii.space0
214
+ /** @since 0.1.0 @category character */
215
+ export const space1 = Ascii.space1
216
+ /** @since 0.1.0 @category character */
217
+ export const multispace0 = Ascii.multispace0
218
+ /** @since 0.1.0 @category character */
219
+ export const multispace1 = Ascii.multispace1
220
+ /** @since 0.1.0 @category character */
221
+ export const lineEnding = Ascii.lineEnding
222
+ /** @since 0.1.0 @category character */
223
+ export const newline = Ascii.newline
224
+ /** @since 0.1.0 @category character */
225
+ export const tab = Ascii.tab
226
+ /** @since 0.1.0 @category character */
227
+ export const crlf = Ascii.crlf
228
+ /**
229
+ * nom's `not_line_ending`.
230
+ *
231
+ * @since 0.1.0
232
+ * @category character
233
+ */
234
+ export const notLineEnding = Ascii.tillLineEnding
235
+ /**
236
+ * A decimal unsigned integer (nom's `character::complete::u64` and friends).
237
+ *
238
+ * @since 0.1.0
239
+ * @category character
240
+ */
241
+ export const u64 = Ascii.decUint
242
+ /**
243
+ * A decimal signed integer (nom's `character::complete::i64` and friends).
244
+ *
245
+ * @since 0.1.0
246
+ * @category character
247
+ */
248
+ export const i64 = Ascii.decInt
249
+
250
+ // -----------------------------------------------------------------------------
251
+ // number
252
+ // -----------------------------------------------------------------------------
253
+
254
+ /**
255
+ * nom's `double` (and `float`).
256
+ *
257
+ * @since 0.1.0
258
+ * @category number
259
+ */
260
+ export const double = Ascii.float
261
+
262
+ /**
263
+ * nom's `recognize_float`.
264
+ *
265
+ * @since 0.1.0
266
+ * @category number
267
+ */
268
+ export const recognizeFloat: Parser<string> = P.taken(Ascii.float)
269
+
270
+ /**
271
+ * nom's `hex_u32`.
272
+ *
273
+ * @since 0.1.0
274
+ * @category number
275
+ */
276
+ export const hexU32 = Ascii.hexUint
277
+
278
+ /** @since 0.1.0 @category number */
279
+ export const beU8 = Binary.u8
280
+ /** @since 0.1.0 @category number */
281
+ export const beI8 = Binary.i8
282
+ /** @since 0.1.0 @category number */
283
+ export const leU8 = Binary.u8
284
+ /** @since 0.1.0 @category number */
285
+ export const leI8 = Binary.i8
286
+ /** @since 0.1.0 @category number */
287
+ export const beU16 = Binary.beU16
288
+ /** @since 0.1.0 @category number */
289
+ export const leU16 = Binary.leU16
290
+ /** @since 0.1.0 @category number */
291
+ export const beI16 = Binary.beI16
292
+ /** @since 0.1.0 @category number */
293
+ export const leI16 = Binary.leI16
294
+ /** @since 0.1.0 @category number */
295
+ export const beU24 = Binary.beU24
296
+ /** @since 0.1.0 @category number */
297
+ export const leU24 = Binary.leU24
298
+ /** @since 0.1.0 @category number */
299
+ export const beI24 = Binary.beI24
300
+ /** @since 0.1.0 @category number */
301
+ export const leI24 = Binary.leI24
302
+ /** @since 0.1.0 @category number */
303
+ export const beU32 = Binary.beU32
304
+ /** @since 0.1.0 @category number */
305
+ export const leU32 = Binary.leU32
306
+ /** @since 0.1.0 @category number */
307
+ export const beI32 = Binary.beI32
308
+ /** @since 0.1.0 @category number */
309
+ export const leI32 = Binary.leI32
310
+ /** @since 0.1.0 @category number */
311
+ export const beU64 = Binary.beU64
312
+ /** @since 0.1.0 @category number */
313
+ export const leU64 = Binary.leU64
314
+ /** @since 0.1.0 @category number */
315
+ export const beI64 = Binary.beI64
316
+ /** @since 0.1.0 @category number */
317
+ export const leI64 = Binary.leI64
318
+ /** @since 0.1.0 @category number */
319
+ export const beU128 = Binary.beU128
320
+ /** @since 0.1.0 @category number */
321
+ export const leU128 = Binary.leU128
322
+ /** @since 0.1.0 @category number */
323
+ export const beI128 = Binary.beI128
324
+ /** @since 0.1.0 @category number */
325
+ export const leI128 = Binary.leI128
326
+ /** @since 0.1.0 @category number */
327
+ export const beF32 = Binary.beF32
328
+ /** @since 0.1.0 @category number */
329
+ export const leF32 = Binary.leF32
330
+ /** @since 0.1.0 @category number */
331
+ export const beF64 = Binary.beF64
332
+ /** @since 0.1.0 @category number */
333
+ export const leF64 = Binary.leF64
334
+
335
+ // -----------------------------------------------------------------------------
336
+ // multi
337
+ // -----------------------------------------------------------------------------
338
+
339
+ /**
340
+ * Zero or more (nom's `many0`).
341
+ *
342
+ * @since 0.1.0
343
+ * @category multi
344
+ */
345
+ export const many0 = <A, E, R, I extends Input>(parser: Parser<A, E, R, I>): Parser<Array<A>, E, R, I> =>
346
+ P.repeat(parser)
347
+
348
+ /**
349
+ * One or more (nom's `many1`).
350
+ *
351
+ * @since 0.1.0
352
+ * @category multi
353
+ */
354
+ export const many1 = <A, E, R, I extends Input>(parser: Parser<A, E, R, I>): Parser<[A, ...Array<A>], E, R, I> =>
355
+ P.repeat(parser, { min: 1 })
356
+
357
+ /**
358
+ * Between `m` and `n` times (nom's `many_m_n`).
359
+ *
360
+ * @since 0.1.0
361
+ * @category multi
362
+ */
363
+ export const manyMN = <A, E, R, I extends Input>(
364
+ m: number,
365
+ n: number,
366
+ parser: Parser<A, E, R, I>
367
+ ): Parser<Array<A>, E, R, I> => P.repeat(parser, { min: m, max: n })
368
+
369
+ /**
370
+ * Exactly `count` times (nom's `count`).
371
+ *
372
+ * @since 0.1.0
373
+ * @category multi
374
+ */
375
+ export const count = <A, E, R, I extends Input>(parser: Parser<A, E, R, I>, count: number): Parser<Array<A>, E, R, I> =>
376
+ P.repeat(parser, count)
377
+
378
+ /**
379
+ * Repeats `parser` until `end` succeeds (nom's `many_till`).
380
+ *
381
+ * @since 0.1.0
382
+ * @category multi
383
+ */
384
+ export const manyTill = <A, E, R, I extends Input, B, E2, R2, I2 extends Input>(
385
+ parser: Parser<A, E, R, I>,
386
+ end: Parser<B, E2, R2, I2>
387
+ ): Parser<[Array<A>, B], E | E2, R | R2, I & I2> => P.repeatTill(parser, end)
388
+
389
+ /**
390
+ * Zero or more `parser` separated by `separator` (nom's `separated_list0`;
391
+ * note the separator comes first).
392
+ *
393
+ * @since 0.1.0
394
+ * @category multi
395
+ */
396
+ export const separatedList0 = <S, E2, R2, I2 extends Input, A, E, R, I extends Input>(
397
+ separator: Parser<S, E2, R2, I2>,
398
+ parser: Parser<A, E, R, I>
399
+ ): Parser<Array<A>, E | E2, R | R2, I & I2> => P.separated(parser, separator)
400
+
401
+ /**
402
+ * One or more `parser` separated by `separator` (nom's `separated_list1`;
403
+ * note the separator comes first).
404
+ *
405
+ * @since 0.1.0
406
+ * @category multi
407
+ */
408
+ export const separatedList1 = <S, E2, R2, I2 extends Input, A, E, R, I extends Input>(
409
+ separator: Parser<S, E2, R2, I2>,
410
+ parser: Parser<A, E, R, I>
411
+ ): Parser<[A, ...Array<A>], E | E2, R | R2, I & I2> => P.separated(parser, separator, { min: 1 })
412
+
413
+ /**
414
+ * Folds zero or more (nom's `fold_many0`).
415
+ *
416
+ * @since 0.1.0
417
+ * @category multi
418
+ */
419
+ export const foldMany0 = <A, E, R, I extends Input, B>(
420
+ parser: Parser<A, E, R, I>,
421
+ init: () => B,
422
+ f: (acc: B, a: A) => B
423
+ ): Parser<B, E, R, I> => P.fold(parser, { init, f })
424
+
425
+ /**
426
+ * Folds one or more (nom's `fold_many1`).
427
+ *
428
+ * @since 0.1.0
429
+ * @category multi
430
+ */
431
+ export const foldMany1 = <A, E, R, I extends Input, B>(
432
+ parser: Parser<A, E, R, I>,
433
+ init: () => B,
434
+ f: (acc: B, a: A) => B
435
+ ): Parser<B, E, R, I> => P.fold(parser, { init, f, range: { min: 1 } })
436
+
437
+ /**
438
+ * Folds between `m` and `n` times (nom's `fold_many_m_n`).
439
+ *
440
+ * @since 0.1.0
441
+ * @category multi
442
+ */
443
+ export const foldManyMN = <A, E, R, I extends Input, B>(
444
+ m: number,
445
+ n: number,
446
+ parser: Parser<A, E, R, I>,
447
+ init: () => B,
448
+ f: (acc: B, a: A) => B
449
+ ): Parser<B, E, R, I> => P.fold(parser, { init, f, range: { min: m, max: n } })
450
+
451
+ /**
452
+ * nom's `length_data`.
453
+ *
454
+ * @since 0.1.0
455
+ * @category multi
456
+ */
457
+ export const lengthData = Binary.lengthTake
458
+
459
+ /**
460
+ * nom's `length_value`.
461
+ *
462
+ * @since 0.1.0
463
+ * @category multi
464
+ */
465
+ export const lengthValue = Binary.lengthAndThen
466
+
467
+ /**
468
+ * nom's `length_count`.
469
+ *
470
+ * @since 0.1.0
471
+ * @category multi
472
+ */
473
+ export const lengthCount = Binary.lengthRepeat
474
+
475
+ // -----------------------------------------------------------------------------
476
+ // sequence / branch
477
+ // -----------------------------------------------------------------------------
478
+
479
+ /**
480
+ * nom's `pair`.
481
+ *
482
+ * @since 0.1.0
483
+ * @category sequence
484
+ */
485
+ export const pair = <A, E, R, I extends Input, B, E2, R2, I2 extends Input>(
486
+ first: Parser<A, E, R, I>,
487
+ second: Parser<B, E2, R2, I2>
488
+ ): Parser<[A, B], E | E2, R | R2, I & I2> => P.zip(first, second)
489
+
490
+ /**
491
+ * nom's tuples of parsers (`(a, b, c)`, formerly `tuple`).
492
+ *
493
+ * @since 0.1.0
494
+ * @category sequence
495
+ */
496
+ export const tuple = P.seq
497
+
498
+ /** @since 0.1.0 @category sequence */
499
+ export const preceded = P.preceded
500
+ /** @since 0.1.0 @category sequence */
501
+ export const terminated = P.terminated
502
+ /** @since 0.1.0 @category sequence */
503
+ export const delimited = P.delimited
504
+ /** @since 0.1.0 @category sequence */
505
+ export const separatedPair = P.separatedPair
506
+ /** @since 0.1.0 @category branch */
507
+ export const alt = P.alt
508
+ /** @since 0.1.0 @category branch */
509
+ export const permutation = P.permutation
510
+
511
+ // -----------------------------------------------------------------------------
512
+ // combinator
513
+ // -----------------------------------------------------------------------------
514
+
515
+ /**
516
+ * nom's `map`.
517
+ *
518
+ * @since 0.1.0
519
+ * @category combinator
520
+ */
521
+ export const map = <A, E, R, I extends Input, B>(parser: Parser<A, E, R, I>, f: (a: A) => B): Parser<B, E, R, I> =>
522
+ P.map(parser, f)
523
+
524
+ /**
525
+ * nom's `map_res`: the function returns a `Result`.
526
+ *
527
+ * @since 0.1.0
528
+ * @category combinator
529
+ */
530
+ export const mapRes = <A, E, R, I extends Input, B, E2>(
531
+ parser: Parser<A, E, R, I>,
532
+ f: (a: A) => Result.Result<B, E2>
533
+ ): Parser<B, E | E2, R, I> => P.tryMap(parser, f)
534
+
535
+ /**
536
+ * nom's `map_opt`: the function returns an `Option`.
537
+ *
538
+ * @since 0.1.0
539
+ * @category combinator
540
+ */
541
+ export const mapOpt = <A, E, R, I extends Input, B>(
542
+ parser: Parser<A, E, R, I>,
543
+ f: (a: A) => Option.Option<B>
544
+ ): Parser<B, E, R, I> => P.filterMap(parser, f)
545
+
546
+ /**
547
+ * nom's `map_parser`.
548
+ *
549
+ * @since 0.1.0
550
+ * @category combinator
551
+ */
552
+ export const mapParser = <A extends Input, E, R, I extends Input, B, E2, R2>(
553
+ parser: Parser<A, E, R, I>,
554
+ applied: Parser<B, E2, R2, A>
555
+ ): Parser<B, E | E2, R | R2, I> => P.mapParser(parser, applied)
556
+
557
+ /**
558
+ * nom's `flat_map`.
559
+ *
560
+ * @since 0.1.0
561
+ * @category combinator
562
+ */
563
+ export const flatMap = <A, E, R, I extends Input, B, E2, R2, I2 extends Input>(
564
+ parser: Parser<A, E, R, I>,
565
+ f: (a: A) => Parser<B, E2, R2, I2>
566
+ ): Parser<B, E | E2, R | R2, I & I2> => P.flatMap(parser, f)
567
+
568
+ /**
569
+ * nom's `value` (note the value comes first).
570
+ *
571
+ * @since 0.1.0
572
+ * @category combinator
573
+ */
574
+ export const value = <B, A, E, R, I extends Input>(val: B, parser: Parser<A, E, R, I>): Parser<B, E, R, I> =>
575
+ P.as(parser, val)
576
+
577
+ /**
578
+ * nom's `verify`.
579
+ *
580
+ * @since 0.1.0
581
+ * @category combinator
582
+ */
583
+ export const verify = <A, E, R, I extends Input>(
584
+ parser: Parser<A, E, R, I>,
585
+ predicate: (a: A) => boolean
586
+ ): Parser<A, E, R, I> => P.filter(parser, predicate)
587
+
588
+ /**
589
+ * nom's `recognize`.
590
+ *
591
+ * @since 0.1.0
592
+ * @category combinator
593
+ */
594
+ export const recognize = P.taken
595
+
596
+ /**
597
+ * nom's `consumed`: returns `[consumed, output]`.
598
+ *
599
+ * @since 0.1.0
600
+ * @category combinator
601
+ */
602
+ export const consumed = <A, E, R, I extends Input>(parser: Parser<A, E, R, I>): Parser<[Slice<I>, A], E, R, I> =>
603
+ P.map(P.withTaken(parser), ([a, s]) => [s, a])
604
+
605
+ /** @since 0.1.0 @category combinator */
606
+ export const opt = P.opt
607
+ /** @since 0.1.0 @category combinator */
608
+ export const cond = P.cond
609
+ /** @since 0.1.0 @category combinator */
610
+ export const peek = P.peek
611
+ /** @since 0.1.0 @category combinator */
612
+ export const not = P.not
613
+ /** @since 0.1.0 @category combinator */
614
+ export const eof = P.eof
615
+ /** @since 0.1.0 @category combinator */
616
+ export const allConsuming = P.allConsuming
617
+ /** @since 0.1.0 @category combinator */
618
+ export const complete = P.complete
619
+ /** @since 0.1.0 @category combinator */
620
+ export const cut = P.cut
621
+ /** @since 0.1.0 @category combinator */
622
+ export const success = P.succeed
623
+ /**
624
+ * nom's `fail()`.
625
+ *
626
+ * @since 0.1.0
627
+ * @category combinator
628
+ */
629
+ export const fail = P.reject
630
+ /** @since 0.1.0 @category combinator */
631
+ export const rest = Token.rest
632
+ /** @since 0.1.0 @category combinator */
633
+ export const restLen = Token.restLen
634
+
635
+ /**
636
+ * nom's `context` (note the label comes first).
637
+ *
638
+ * @since 0.1.0
639
+ * @category error
640
+ */
641
+ export const context = <A, E, R, I extends Input>(label: string, parser: Parser<A, E, R, I>): Parser<A, E, R, I> =>
642
+ P.context(parser, label)