@claudiu-ceia/combine 0.2.4

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 (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +389 -0
  3. package/esm/_dnt.shims.d.ts +2 -0
  4. package/esm/_dnt.shims.d.ts.map +1 -0
  5. package/esm/_dnt.shims.js +57 -0
  6. package/esm/mod.d.ts +6 -0
  7. package/esm/mod.d.ts.map +1 -0
  8. package/esm/mod.js +5 -0
  9. package/esm/package.json +3 -0
  10. package/esm/src/Parser.d.ts +85 -0
  11. package/esm/src/Parser.d.ts.map +1 -0
  12. package/esm/src/Parser.js +93 -0
  13. package/esm/src/Trie.d.ts +17 -0
  14. package/esm/src/Trie.d.ts.map +1 -0
  15. package/esm/src/Trie.js +75 -0
  16. package/esm/src/combinators.d.ts +199 -0
  17. package/esm/src/combinators.d.ts.map +1 -0
  18. package/esm/src/combinators.js +531 -0
  19. package/esm/src/internal_assert.d.ts +2 -0
  20. package/esm/src/internal_assert.d.ts.map +1 -0
  21. package/esm/src/internal_assert.js +5 -0
  22. package/esm/src/language.d.ts +12 -0
  23. package/esm/src/language.d.ts.map +1 -0
  24. package/esm/src/language.js +13 -0
  25. package/esm/src/parsers.d.ts +94 -0
  26. package/esm/src/parsers.d.ts.map +1 -0
  27. package/esm/src/parsers.js +256 -0
  28. package/esm/src/utility.d.ts +91 -0
  29. package/esm/src/utility.d.ts.map +1 -0
  30. package/esm/src/utility.js +178 -0
  31. package/package.json +21 -0
  32. package/script/_dnt.shims.d.ts +2 -0
  33. package/script/_dnt.shims.d.ts.map +1 -0
  34. package/script/_dnt.shims.js +60 -0
  35. package/script/mod.d.ts +6 -0
  36. package/script/mod.d.ts.map +1 -0
  37. package/script/mod.js +21 -0
  38. package/script/package.json +3 -0
  39. package/script/src/Parser.d.ts +85 -0
  40. package/script/src/Parser.d.ts.map +1 -0
  41. package/script/src/Parser.js +104 -0
  42. package/script/src/Trie.d.ts +17 -0
  43. package/script/src/Trie.d.ts.map +1 -0
  44. package/script/src/Trie.js +80 -0
  45. package/script/src/combinators.d.ts +199 -0
  46. package/script/src/combinators.d.ts.map +1 -0
  47. package/script/src/combinators.js +557 -0
  48. package/script/src/internal_assert.d.ts +2 -0
  49. package/script/src/internal_assert.d.ts.map +1 -0
  50. package/script/src/internal_assert.js +9 -0
  51. package/script/src/language.d.ts +12 -0
  52. package/script/src/language.d.ts.map +1 -0
  53. package/script/src/language.js +17 -0
  54. package/script/src/parsers.d.ts +94 -0
  55. package/script/src/parsers.d.ts.map +1 -0
  56. package/script/src/parsers.js +281 -0
  57. package/script/src/utility.d.ts +91 -0
  58. package/script/src/utility.d.ts.map +1 -0
  59. package/script/src/utility.js +214 -0
@@ -0,0 +1,531 @@
1
+ import { assert } from "./internal_assert.js";
2
+ import { failure, isFatal, success, } from "./Parser.js";
3
+ import { map } from "./utility.js";
4
+ /**
5
+ * Apply a variadic list of parsers sequentially. The return type maintains
6
+ * the order of the parsers such that you get a typed result back.
7
+ *
8
+ * // p is a Parser<[number, string, number, string]>
9
+ * const p = seq(number(), str("-"), number(), str("-"), number());
10
+ */
11
+ export const seq = (...parsers) => {
12
+ return (ctx) => {
13
+ if (parsers.length === 0) {
14
+ return failure(ctx, `A sequential parser needs to receive at least one parser.`);
15
+ }
16
+ const values = [];
17
+ let nextCtx = ctx;
18
+ for (const parser of parsers) {
19
+ const res = parser(nextCtx);
20
+ if (!res.success) {
21
+ return res;
22
+ }
23
+ values.push(res.value);
24
+ nextCtx = res.ctx;
25
+ }
26
+ return success(nextCtx, values);
27
+ };
28
+ };
29
+ /**
30
+ * Try both parsers in sequence, return the first one that's succesful.
31
+ * Fatal errors from either parser will be propagated immediately.
32
+ */
33
+ export const either = (a, b) => {
34
+ return (ctx) => {
35
+ return any(a, b)(ctx);
36
+ };
37
+ };
38
+ /**
39
+ * Try all parsers in order, return the first one that is succesful.
40
+ * If none match, return the failure result of the parser that
41
+ * consumed most of the input.
42
+ *
43
+ * Fatal errors are propagated immediately without trying remaining parsers.
44
+ */
45
+ export const any = (...parsers) => {
46
+ return (ctx) => {
47
+ let furthestRes;
48
+ for (const parser of parsers) {
49
+ const res = parser(ctx);
50
+ if (res.success) {
51
+ return res;
52
+ }
53
+ // Fatal errors propagate immediately - no backtracking
54
+ if (isFatal(res)) {
55
+ return res;
56
+ }
57
+ if (!furthestRes || furthestRes.ctx.index < res.ctx.index) {
58
+ furthestRes = res;
59
+ }
60
+ }
61
+ assert(furthestRes);
62
+ return furthestRes;
63
+ };
64
+ };
65
+ /**
66
+ * Try all parsers in order. If more than one match is found,
67
+ * it's a failure. If only one matches, return it's result.
68
+ * If none matches, return the failure result of the parser
69
+ * that consumed the most input.
70
+ *
71
+ * Fatal errors are propagated immediately.
72
+ */
73
+ export const oneOf = (...parsers) => {
74
+ return (ctx) => {
75
+ let match;
76
+ let furthestRes;
77
+ for (const parser of parsers) {
78
+ const res = parser(ctx);
79
+ // Fatal errors propagate immediately
80
+ if (!res.success && isFatal(res)) {
81
+ return res;
82
+ }
83
+ if (res.success) {
84
+ if (match) {
85
+ if (match.success) {
86
+ return failure(ctx, `expected single parser to match, already matched "${JSON.stringify(match.value)}", now matched ${JSON.stringify(res.value)}`);
87
+ }
88
+ else {
89
+ return failure(ctx, "expected single parser to match", [match]);
90
+ }
91
+ }
92
+ match = res;
93
+ }
94
+ if (!furthestRes || furthestRes.ctx.index < res.ctx.index) {
95
+ furthestRes = res;
96
+ }
97
+ }
98
+ if (match) {
99
+ return match;
100
+ }
101
+ assert(furthestRes);
102
+ return furthestRes;
103
+ };
104
+ };
105
+ /**
106
+ * Try all parsers in sequence and keep track of which one consumed
107
+ * the most input, then return it.
108
+ *
109
+ * Fatal errors are propagated immediately.
110
+ */
111
+ export const furthest = (...parsers) => {
112
+ return (ctx) => {
113
+ let furthestRes;
114
+ for (const parser of parsers) {
115
+ const res = parser(ctx);
116
+ // Fatal errors propagate immediately
117
+ if (!res.success && isFatal(res)) {
118
+ return res;
119
+ }
120
+ if (!furthestRes || furthestRes.ctx.index < res.ctx.index) {
121
+ furthestRes = res;
122
+ }
123
+ }
124
+ assert(furthestRes);
125
+ return furthestRes;
126
+ };
127
+ };
128
+ /**
129
+ * Try a parser. If it matches, return it, otherwise return a `null`
130
+ * result without consuming any input.
131
+ *
132
+ * Fatal errors are propagated - optional only catches non-fatal failures.
133
+ */
134
+ export const optional = (parser) => {
135
+ return (ctx) => {
136
+ const res = parser(ctx);
137
+ if (res.success) {
138
+ return res;
139
+ }
140
+ // Fatal errors propagate - don't swallow them
141
+ if (isFatal(res)) {
142
+ return res;
143
+ }
144
+ return success(ctx, null);
145
+ };
146
+ };
147
+ /**
148
+ * Match the same parser until it fails. This parser never fails, so even
149
+ * if it doesn't match it's a succes.
150
+ *
151
+ * Fatal errors are propagated immediately.
152
+ */
153
+ export const many = (parser) => {
154
+ return (ctx) => {
155
+ const values = [];
156
+ let nextCtx = ctx;
157
+ while (true) {
158
+ const res = parser(nextCtx);
159
+ if (!res.success) {
160
+ // Fatal errors propagate
161
+ if (isFatal(res)) {
162
+ return res;
163
+ }
164
+ break;
165
+ }
166
+ values.push(res.value);
167
+ nextCtx = res.ctx;
168
+ }
169
+ return success(nextCtx, values);
170
+ };
171
+ };
172
+ /**
173
+ * Match the same parser until it fails. Needs to match at least
174
+ * once to be a success.
175
+ *
176
+ * Fatal errors are propagated immediately.
177
+ */
178
+ export const many1 = (parser) => {
179
+ return (ctx) => {
180
+ const res = many(parser)(ctx);
181
+ // Propagate fatal errors
182
+ if (!res.success) {
183
+ return res;
184
+ }
185
+ if (ctx.index === res.ctx.index) {
186
+ return failure(res.ctx, "Expected at least one match");
187
+ }
188
+ return res;
189
+ };
190
+ };
191
+ /**
192
+ * Match parser until the second parser matches. The result is a tuple
193
+ * of results for the first parser, with the result of the second parser
194
+ * appended.
195
+ *
196
+ * Fatal errors from either parser are propagated immediately.
197
+ */
198
+ export const manyTill = (parser, end) => {
199
+ return (ctx) => {
200
+ const values = [];
201
+ let nextCtx = ctx;
202
+ // eslint-disable-next-line no-constant-condition
203
+ while (true) {
204
+ const maybeEnd = end(nextCtx);
205
+ if (maybeEnd.success) {
206
+ return success(maybeEnd.ctx, [...values, maybeEnd.value]);
207
+ }
208
+ // Fatal errors from end parser propagate
209
+ if (isFatal(maybeEnd)) {
210
+ return maybeEnd;
211
+ }
212
+ const res = parser(nextCtx);
213
+ if (!res.success) {
214
+ // Fatal errors from content parser propagate
215
+ if (isFatal(res)) {
216
+ return res;
217
+ }
218
+ const maybeEnd = end(nextCtx);
219
+ if (maybeEnd.success) {
220
+ return success(maybeEnd.ctx, [...values, maybeEnd.value]);
221
+ }
222
+ else {
223
+ return maybeEnd;
224
+ }
225
+ }
226
+ values.push(res.value);
227
+ nextCtx = res.ctx;
228
+ }
229
+ };
230
+ };
231
+ /**
232
+ * Repeatedly match a parser
233
+ *
234
+ * Fatal errors are propagated immediately.
235
+ */
236
+ export const repeat = (n, parser) => {
237
+ return (ctx) => {
238
+ const values = [];
239
+ let nextCtx = ctx;
240
+ let idx = 0;
241
+ while (idx < n) {
242
+ const res = parser(nextCtx);
243
+ if (!res.success) {
244
+ // Propagate fatal errors with their stack
245
+ if (isFatal(res)) {
246
+ return res;
247
+ }
248
+ return failure(ctx, res.expected, [], res.stack);
249
+ }
250
+ values.push(res.value);
251
+ nextCtx = res.ctx;
252
+ idx++;
253
+ }
254
+ return success(nextCtx, values);
255
+ };
256
+ };
257
+ /**
258
+ * Useful for parsing separated lists. Repeatedly match a sequence of both
259
+ * parsers while they both match. Doesn't support trailing separators.
260
+ *
261
+ * const p = sepBy(number(), str(","));
262
+ *
263
+ * const ok = p("1,2,3"); // success
264
+ * const fail = p("1,2,3,"); // failure, expecting one more number
265
+ *
266
+ * If no matches are found, it's a success.
267
+ *
268
+ * Fatal errors are propagated immediately.
269
+ */
270
+ export const sepBy = (parser, sep) => {
271
+ return (ctx) => {
272
+ const values = [];
273
+ let nextCtx = ctx;
274
+ // eslint-disable-next-line no-constant-condition
275
+ while (true) {
276
+ const res = parser(nextCtx);
277
+ // Fatal errors propagate
278
+ if (!res.success && isFatal(res)) {
279
+ return res;
280
+ }
281
+ if (res.success) {
282
+ const sepCtx = res.ctx;
283
+ values.push(res.value);
284
+ const sepRes = sep(sepCtx);
285
+ // Fatal errors from separator propagate
286
+ if (!sepRes.success && isFatal(sepRes)) {
287
+ return sepRes;
288
+ }
289
+ if (!sepRes.success) {
290
+ return success(sepCtx, values);
291
+ }
292
+ nextCtx = sepRes.ctx;
293
+ values.push(sepRes.value);
294
+ continue;
295
+ }
296
+ return success(nextCtx, values);
297
+ }
298
+ };
299
+ };
300
+ /**
301
+ * Same as `sepBy`, but at least one match is required.
302
+ *
303
+ * Fatal errors are propagated immediately.
304
+ */
305
+ export const sepBy1 = (parser, sep) => {
306
+ return (ctx) => {
307
+ const res = sepBy(parser, sep)(ctx);
308
+ // Propagate fatal errors
309
+ if (!res.success) {
310
+ return res;
311
+ }
312
+ if (res.ctx.index === ctx.index) {
313
+ const parserTest = parser(ctx);
314
+ if (parserTest.success) {
315
+ // This should never happen since `sepBy` didn't match - need to rewrite for statical guarantee
316
+ return failure(parserTest.ctx, "Unjustified error");
317
+ }
318
+ else {
319
+ return failure(res.ctx, "Expected at least one match", [parserTest]);
320
+ }
321
+ }
322
+ return res;
323
+ };
324
+ };
325
+ /**
326
+ * Skips matching parsers while consuming input.
327
+ *
328
+ * Fatal errors are propagated immediately.
329
+ */
330
+ export const skipMany = (parser) => {
331
+ return (ctx) => {
332
+ const res = many(parser)(ctx);
333
+ // Propagate fatal errors
334
+ if (!res.success) {
335
+ return res;
336
+ }
337
+ return success(res.ctx, null);
338
+ };
339
+ };
340
+ /**
341
+ * Skips matching parsers while consuming input. At least one match is required.
342
+ *
343
+ * Fatal errors are propagated immediately.
344
+ */
345
+ export const skipMany1 = (parser) => {
346
+ return (ctx) => {
347
+ const res = many1(parser)(ctx);
348
+ if (res.success) {
349
+ return success(res.ctx, null);
350
+ }
351
+ return res;
352
+ };
353
+ };
354
+ /**
355
+ * Match a parser, but don't consume any input.
356
+ */
357
+ export const peek = (parser) => {
358
+ return (ctx) => {
359
+ const res = parser(ctx);
360
+ if (res.success) {
361
+ return success(ctx, null);
362
+ }
363
+ return failure(ctx, `lookahead failed, ${res.expected}`, [], res.stack);
364
+ };
365
+ };
366
+ /**
367
+ * Skips matching a single parser while consuming input.
368
+ */
369
+ export const skip1 = (parser) => {
370
+ return (ctx) => {
371
+ const res = parser(ctx);
372
+ if (res.success) {
373
+ return success(res.ctx, null);
374
+ }
375
+ return res;
376
+ };
377
+ };
378
+ export const surrounded = (open, middle, close) => {
379
+ /* return (ctx) => {
380
+ const openRes = open(ctx);
381
+ if (openRes.success) {
382
+ let cursor = openRes.ctx;
383
+ let closeRes = close(cursor);
384
+ while (!closeRes.success) {
385
+ const res = middle(cursor);
386
+ if (res.success) {
387
+
388
+ }
389
+ }
390
+ }
391
+ } */
392
+ return map(seq(open, middle, close), ([_open, middle, _close]) => middle);
393
+ };
394
+ export const minus = (a, b) => {
395
+ return (ctx) => {
396
+ const excludedRes = b(ctx);
397
+ if (excludedRes.success) {
398
+ return failure(ctx, `Matched excluded "${JSON.stringify(excludedRes.value)}"`);
399
+ }
400
+ return a(ctx);
401
+ };
402
+ };
403
+ export const not = (a) => {
404
+ return (ctx) => {
405
+ const res = a(ctx);
406
+ if (res.success) {
407
+ return failure(ctx, `Matched "${JSON.stringify(res.value)}"`);
408
+ }
409
+ return success(ctx, null);
410
+ };
411
+ };
412
+ export const keepNonNull = (parser) => map(parser, (matches) => matches.filter((v) => v !== null));
413
+ export const seqNonNull = (...parsers) => keepNonNull(seq(...parsers));
414
+ /**
415
+ * Parse left-associative infix expressions.
416
+ * Parses: term (op term)* and folds left using the combine function.
417
+ *
418
+ * This is useful for parsing binary operators with the same precedence level.
419
+ *
420
+ * @param term - Parser for the operands
421
+ * @param op - Parser for the operator(s)
422
+ * @param combine - Function to combine left operand, operator, and right operand
423
+ * @returns A parser that produces the left-folded result
424
+ *
425
+ * @example
426
+ * ```ts
427
+ * // Parse addition/subtraction: 1 + 2 - 3 => ((1 + 2) - 3)
428
+ * const addSub = chainl1(
429
+ * numberParser,
430
+ * any(str("+"), str("-")),
431
+ * (left, op, right) => ({ type: "binary", op, left, right })
432
+ * );
433
+ * ```
434
+ *
435
+ * Fatal errors are propagated immediately.
436
+ */
437
+ export const chainl1 = (term, op, combine) => {
438
+ return (ctx) => {
439
+ const firstRes = term(ctx);
440
+ if (!firstRes.success) {
441
+ return firstRes;
442
+ }
443
+ let acc = firstRes.value;
444
+ let nextCtx = firstRes.ctx;
445
+ while (true) {
446
+ const opRes = op(nextCtx);
447
+ if (!opRes.success) {
448
+ // Fatal errors propagate
449
+ if (isFatal(opRes)) {
450
+ return opRes;
451
+ }
452
+ break;
453
+ }
454
+ const rightRes = term(opRes.ctx);
455
+ if (!rightRes.success) {
456
+ // Fatal errors propagate
457
+ if (isFatal(rightRes)) {
458
+ return rightRes;
459
+ }
460
+ // Operator matched but operand didn't - this is a failure
461
+ return rightRes;
462
+ }
463
+ acc = combine(acc, opRes.value, rightRes.value);
464
+ nextCtx = rightRes.ctx;
465
+ }
466
+ return success(nextCtx, acc);
467
+ };
468
+ };
469
+ /**
470
+ * Parse right-associative infix expressions.
471
+ * Parses: term (op term)* and folds right using the combine function.
472
+ *
473
+ * This is useful for operators like exponentiation: 2 ** 3 ** 4 => 2 ** (3 ** 4)
474
+ *
475
+ * @param term - Parser for the operands
476
+ * @param op - Parser for the operator(s)
477
+ * @param combine - Function to combine left operand, operator, and right operand
478
+ * @returns A parser that produces the right-folded result
479
+ *
480
+ * @example
481
+ * ```ts
482
+ * // Parse exponentiation: 2 ** 3 ** 4 => 2 ** (3 ** 4)
483
+ * const pow = chainr1(
484
+ * numberParser,
485
+ * str("**"),
486
+ * (left, op, right) => ({ type: "binary", op, left, right })
487
+ * );
488
+ * ```
489
+ *
490
+ * Fatal errors are propagated immediately.
491
+ */
492
+ export const chainr1 = (term, op, combine) => {
493
+ return (ctx) => {
494
+ const firstRes = term(ctx);
495
+ if (!firstRes.success) {
496
+ return firstRes;
497
+ }
498
+ // Collect all terms and operators
499
+ const terms = [firstRes.value];
500
+ const ops = [];
501
+ let nextCtx = firstRes.ctx;
502
+ while (true) {
503
+ const opRes = op(nextCtx);
504
+ if (!opRes.success) {
505
+ // Fatal errors propagate
506
+ if (isFatal(opRes)) {
507
+ return opRes;
508
+ }
509
+ break;
510
+ }
511
+ const rightRes = term(opRes.ctx);
512
+ if (!rightRes.success) {
513
+ // Fatal errors propagate
514
+ if (isFatal(rightRes)) {
515
+ return rightRes;
516
+ }
517
+ // Operator matched but operand didn't - this is a failure
518
+ return rightRes;
519
+ }
520
+ ops.push(opRes.value);
521
+ terms.push(rightRes.value);
522
+ nextCtx = rightRes.ctx;
523
+ }
524
+ // Fold right: a op b op c => a op (b op c)
525
+ let acc = terms[terms.length - 1];
526
+ for (let i = terms.length - 2; i >= 0; i--) {
527
+ acc = combine(terms[i], ops[i], acc);
528
+ }
529
+ return success(nextCtx, acc);
530
+ };
531
+ };
@@ -0,0 +1,2 @@
1
+ export declare const assert: (condition: unknown, message?: string) => asserts condition;
2
+ //# sourceMappingURL=internal_assert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal_assert.d.ts","sourceRoot":"","sources":["../../src/src/internal_assert.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,EAAE,CACnB,SAAS,EAAE,OAAO,EAClB,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,SAOZ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export const assert = (condition, message = "Assertion failed") => {
2
+ if (!condition) {
3
+ throw new Error(message);
4
+ }
5
+ };
@@ -0,0 +1,12 @@
1
+ import type { Parser } from "./Parser.js";
2
+ export type BoundDefinition<T extends UnboundDefinition<any>> = {
3
+ [Key in keyof T]: ReturnType<T[Key]>;
4
+ };
5
+ export type UnboundDefinition<T extends BoundDefinition<any>> = {
6
+ [Key in keyof T]: (self: T) => T[Key];
7
+ };
8
+ export type UntypedLanguage = {
9
+ [key: string]: Parser<unknown>;
10
+ };
11
+ export declare const createLanguage: <T extends BoundDefinition<any> = UntypedLanguage>(map: UnboundDefinition<T>) => BoundDefinition<UnboundDefinition<T>>;
12
+ //# sourceMappingURL=language.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../src/src/language.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,iBAAiB,CAAC,GAAG,CAAC,IAAI;KAC7D,GAAG,IAAI,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,eAAe,CAAC,GAAG,CAAC,IAAI;KAC7D,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,CAAC,SAAS,eAAe,CAAC,GAAG,CAAC,yBAEzB,iBAAiB,CAAC,CAAC,CAAC,KACxB,eAAe,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAetC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { lazy } from "./utility.js";
2
+ export const createLanguage = (map) => {
3
+ const LanguageDefinition = class LanguageDefinitionClass {
4
+ constructor() {
5
+ const bound = {};
6
+ for (const key of Object.keys(map)) {
7
+ bound[key] = lazy(() => map[key](this));
8
+ }
9
+ Object.assign(this, bound);
10
+ }
11
+ };
12
+ return new LanguageDefinition();
13
+ };
@@ -0,0 +1,94 @@
1
+ import { type Parser } from "./Parser.js";
2
+ /**
3
+ * Matches a given string.
4
+ */
5
+ export declare const str: (match: string) => Parser<string>;
6
+ /**
7
+ * Matches any of the given strings by using a trie.
8
+ * Use instead of `any(str("..."), ...) when you want
9
+ * to match against many possible strings.
10
+ */
11
+ export declare const trie: (matches: string[]) => Parser<string>;
12
+ /**
13
+ * Matches a given character by UTF-16 code.
14
+ */
15
+ export declare const char: (code: number) => Parser<string>;
16
+ /**
17
+ * Matches any single character.
18
+ */
19
+ export declare const anyChar: () => Parser<string>;
20
+ /**
21
+ * Matches any character not matching the given UTF-16 code.
22
+ */
23
+ export declare const notChar: (code: number) => Parser<string>;
24
+ /**
25
+ * Matches any character based on a predicate.
26
+ */
27
+ export declare const charWhere: (pred: (code: number) => boolean) => Parser<string>;
28
+ /**
29
+ * Skips matching any character not matching the given UTF-16 code.
30
+ */
31
+ export declare const skipCharWhere: (pred: (code: number) => boolean) => Parser<string | null>;
32
+ /**
33
+ * Matches any single decimal digit
34
+ */
35
+ export declare const digit: () => Parser<number>;
36
+ /**
37
+ * Matches any single letter (case insesitive A-Z)
38
+ */
39
+ export declare const letter: () => Parser<string>;
40
+ /**
41
+ * Matches any whitespace
42
+ */
43
+ export declare const space: () => Parser<string>;
44
+ /**
45
+ * Matches any `count` characters as long as there's enough input
46
+ * left to parse.
47
+ */
48
+ export declare const take: (count: number) => Parser<string>;
49
+ /**
50
+ * Matches the rest of the input.
51
+ */
52
+ export declare const takeText: () => Parser<string>;
53
+ /**
54
+ * Matches an end of line marker
55
+ */
56
+ export declare const eol: () => Parser<string>;
57
+ /**
58
+ * Matches if there's no input left to parse
59
+ */
60
+ export declare const eof: () => Parser<null>;
61
+ /**
62
+ * Matches horizontal space (spaces/tabs), if at least one space
63
+ * follows.
64
+ */
65
+ export declare const horizontalSpace: () => Parser<null>;
66
+ /**
67
+ * Matches a positive integer
68
+ */
69
+ export declare const int: () => Parser<number>;
70
+ /**
71
+ * Matches a dot-separated double
72
+ */
73
+ export declare const double: () => Parser<number>;
74
+ /**
75
+ * Matches a hexadecimal digit
76
+ */
77
+ export declare const hexDigit: () => Parser<string>;
78
+ /**
79
+ * Matches a hexadecimal number (`0x` lead not allowed)
80
+ */
81
+ export declare const hex: () => Parser<string>;
82
+ /**
83
+ * Matches a positive decimal number
84
+ */
85
+ export declare const number: () => Parser<number>;
86
+ /**
87
+ * Matches a signed decimal number (with explicit +/- sign)
88
+ */
89
+ export declare const signed: (nParser?: Parser<number>) => Parser<number>;
90
+ /**
91
+ * Matches input for given regex
92
+ */
93
+ export declare const regex: (re: RegExp, expected: string) => Parser<string>;
94
+ //# sourceMappingURL=parsers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parsers.d.ts","sourceRoot":"","sources":["../../src/src/parsers.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,MAAM,EAAW,MAAM,aAAa,CAAC;AAI5D;;GAEG;AACH,eAAO,MAAM,GAAG,UAAW,MAAM,KAAG,MAAM,CAAC,MAAM,CAShD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,IAAI,YAAa,MAAM,EAAE,KAAG,MAAM,CAAC,MAAM,CAwBrD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,IAAI,SAAU,MAAM,KAAG,MAAM,CAAC,MAAM,CAKhD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,QAAO,MAAM,CAAC,MAAM,CAWvC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,SAAU,MAAM,KAAG,MAAM,CAAC,MAAM,CAiBnD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,SAAS,SAAU,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,KAAG,MAAM,CAAC,MAAM,CAcxE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,SAClB,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,KAC9B,MAAM,CAAC,MAAM,GAAG,IAAI,CAStB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,KAAK,QAAO,MAAM,CAAC,MAAM,CAQrC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,MAAM,QAAO,MAAM,CAAC,MAAM,CAItC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,KAAK,QAAO,MAAM,CAAC,MAAM,CAIrC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,IAAI,UAAW,MAAM,KAAG,MAAM,CAAC,MAAM,CAYjD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,QAAQ,QAAO,MAAM,CAAC,MAAM,CAOxC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,GAAG,QAAO,MAAM,CAAC,MAAM,CAInC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,GAAG,QAAO,MAAM,CAAC,IAAI,CAQjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAO,MAAM,CAAC,IAAI,CAM7C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,GAAG,QAAO,MAAM,CAAC,MAAM,CAInC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,MAAM,QAAO,MAAM,CAAC,MAAM,CAkBtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,QAAQ,QAAO,MAAM,CAAC,MAAM,CAUxC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,GAAG,QAAO,MAAM,CAAC,MAAM,CASnC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,MAAM,QAAO,MAAM,CAAC,MAAM,CAEtC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,MAAM,aAAa,MAAM,CAAC,MAAM,CAAC,KAAc,MAAM,CAAC,MAAM,CAUxE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,KAAK,OAAQ,MAAM,YAAY,MAAM,KAAG,MAAM,CAAC,MAAM,CAgBjE,CAAC"}