UNPKG

23.6 kBTypeScriptView Raw
1/**
2 * **NOTE:** You probably will never need to use this function. Most parsing
3 * can be accomplished using `Parsimmon.regexp` and combination with
4 * `Parsimmon.seq` and `Parsimmon.alt`.
5 *
6 * You can add a primitive parser (similar to the included ones) by using
7 * `Parsimmon(fn)`. This is an example of how to create a parser that matches
8 * any character except the one provided:
9 *
10 * ```javascript
11 * function notChar(char) {
12 * return Parsimmon(function(input, i) {
13 * if (input.charAt(i) !== char) {
14 * return Parsimmon.makeSuccess(i + 1, input.charAt(i));
15 * }
16 * return Parsimmon.makeFailure(i, 'anything different than "' + char + '"');
17 * });
18 * }
19 * ```
20 *
21 * This parser can then be used and composed the same way all the existing
22 * ones are used and composed, for example:
23 *
24 * ```javascript
25 * var parser =
26 * Parsimmon.seq(
27 * Parsimmon.string('a'),
28 * notChar('b').times(5)
29 * );
30 * parser.parse('accccc');
31 * //=> {status: true, value: ['a', ['c', 'c', 'c', 'c', 'c']]}
32 * ```
33 */
34declare function Parsimmon<T>(fn: (input: string, i: number) => Parsimmon.Reply<T>): Parsimmon.Parser<T>;
35
36declare namespace Parsimmon {
37 type StreamType = string;
38
39 interface Index {
40 /** zero-based character offset */
41 offset: number;
42 /** one-based line offset */
43 line: number;
44 /** one-based column offset */
45 column: number;
46 }
47
48 interface Mark<T> {
49 start: Index;
50 end: Index;
51 value: T;
52 }
53
54 interface Node<Name extends string, T> extends Mark<T> {
55 name: Name;
56 }
57
58 type Result<T> = Success<T> | Failure;
59
60 interface Success<T> {
61 status: true;
62 value: T;
63 }
64
65 interface Failure {
66 status: false;
67 expected: string[];
68 index: Index;
69 }
70
71 interface Rule {
72 [key: string]: (r: Language) => Parser<any>;
73 }
74
75 interface Language {
76 [key: string]: Parser<any>;
77 }
78
79 type TypedRule<TLanguageSpec> = {
80 [P in keyof TLanguageSpec]: (r: TypedLanguage<TLanguageSpec>) => Parser<TLanguageSpec[P]>;
81 };
82
83 type TypedLanguage<TLanguageSpec> = {
84 [P in keyof TLanguageSpec]: Parser<TLanguageSpec[P]>;
85 };
86
87 interface Parser<T> {
88 /**
89 * parse the string
90 */
91 parse(input: string): Result<T>;
92 /**
93 * Like parser.parse(input) but either returns the parsed value or throws
94 * an error on failure. The error object contains additional properties
95 * about the error.
96 */
97 tryParse(input: string): T;
98 /**
99 * Passes the result of `parser` to the function `condition`,
100 * which returns a boolean. If the the condition is false, returns
101 * a failed parse with the given `message`. Else it returns the
102 * original result of `parser`.
103 */
104 assert(condition: (result: T) => boolean, message: string): Parser<T>;
105 /**
106 * returns a new parser which tries parser, and if it fails uses otherParser.
107 */
108 or<U>(otherParser: Parser<U>): Parser<T | U>;
109 /**
110 * returns a new parser which tries parser, and on success calls the given function
111 * with the result of the parse, which is expected to return another parser, which
112 * will be tried next
113 */
114 chain<U>(next: (result: T) => Parser<U>): Parser<U>;
115 /**
116 * returns a new parser which tries parser, and on success calls the given function
117 * with the result of the parse, which is expected to return another parser.
118 */
119 then<U>(call: (result: T) => Parser<U>): Parser<U>;
120 /**
121 * expects anotherParser to follow parser, and yields the result of anotherParser.
122 * NB: the result of parser here is ignored.
123 */
124 then<U>(anotherParser: Parser<U>): Parser<U>;
125 /**
126 * Transforms the input of parser with the given function.
127 */
128 contramap<U>(fn: (input: T) => U): Parser<U>;
129 /**
130 * Transforms the input and output of parser with the given function.
131 */
132 promap<U, V>(inputFn: (input: T) => U, outputFn: (output: U) => V): Parser<V>;
133 /**
134 * returns wrapper(this) from the parser. Useful for custom functions used
135 * to wrap your parsers, while keeping with Parsimmon chaining style.
136 */
137 thru<U>(call: (wrapper: Parser<T>) => Parser<U>): Parser<U>;
138 /**
139 * expects anotherParser before and after parser, yielding the result of parser
140 */
141 trim<U>(anotherParser: Parser<U>): Parser<T>;
142 /**
143 * transforms the output of parser with the given function.
144 */
145 map<U>(call: (result: T) => U): Parser<U>;
146 /**
147 * returns a new parser with the same behavior, but which yields aResult.
148 */
149 result<U>(aResult: U): Parser<U>;
150 /**
151 * returns a new parser that returns the fallback value if the first parser failed.
152 */
153 fallback<U>(fallbackValue: U): Parser<T | U>;
154 /**
155 * expects otherParser after parser, but preserves the yield value of parser.
156 */
157 skip<U>(otherParser: Parser<U>): Parser<T>;
158 /**
159 * Expects the parser before before parser and after after parser.
160 */
161 wrap(before: Parser<any>, after: Parser<any>): Parser<T>;
162 /**
163 * Returns a parser that looks for anything but whatever anotherParser wants to
164 * parse, and does not consume it. Yields the same result as parser. Equivalent to
165 * parser.skip(Parsimmon.notFollowedBy(anotherParser)).
166 */
167 notFollowedBy(anotherParser: Parser<any>): Parser<T>;
168 /**
169 * Returns a parser that looks for whatever arg wants to parse, but does not
170 * consume it. Yields the same result as parser. Equivalent to
171 * parser.skip(Parsimmon.lookahead(anotherParser)).
172 */
173 lookahead(arg: Parser<any> | string | RegExp): Parser<T>;
174 /**
175 * Equivalent to parser.tieWith("").
176 *
177 * Note: parser.tie() is usually used after Parsimmon.seq(...parsers) or parser.many().
178 */
179 tie(): Parser<string>;
180 /**
181 * When called on a parser yielding an array of strings, yields all their strings
182 * concatenated with the separator. Asserts that its input is actually an array of strings.
183 */
184 tieWith(join: string): Parser<string>;
185 /**
186 * expects parser zero or more times, and yields an array of the results.
187 */
188 many(): Parser<T[]>;
189 /**
190 * expects parser exactly n times, and yields an array of the results.
191 */
192 times(n: number): Parser<T[]>;
193 /**
194 * expects parser between min and max times, and yields an array of the results.
195 */
196 // tslint:disable-next-line:unified-signatures
197 times(min: number, max: number): Parser<T[]>;
198 /**
199 * expects parser at most n times. Yields an array of the results.
200 */
201 atMost(n: number): Parser<T[]>;
202 /**
203 * expects parser at least n times. Yields an array of the results.
204 */
205 atLeast(n: number): Parser<T[]>;
206 /**
207 * Yields an object with `start`, `value`, and `end` keys, where `value` is the original
208 * value yielded by the parser, and `start` and `end` indicate the `Index` objects representing
209 * the range of the parse result.
210 */
211 mark(): Parser<Mark<T>>;
212 /**
213 * Like `mark()`, but yields an object with an additional `name` key to use as an AST.
214 */
215 node<Name extends string>(name: Name): Parser<Node<Name, T>>;
216 /**
217 * Returns a new parser whose failure message is description.
218 * For example, string('x').desc('the letter x') will indicate that 'the letter x' was expected.
219 */
220 desc(description: string | string[]): Parser<T>;
221
222 // Fantasy land support
223
224 /**
225 * Returns Parsimmon.fail("fantasy-land/empty").
226 */
227 empty(): Parser<never>;
228 /**
229 * Takes parser which returns a function and applies it to the parsed value of otherParser.
230 */
231 ap<U>(otherParser: Parser<(t: T) => U>): Parser<U>;
232 /**
233 * Equivalent to Parsimmon.sepBy(parser, separator).
234 *
235 * Expects zero or more matches for parser, separated by the parser separator, yielding an array.
236 */
237 sepBy<U>(separator: Parser<U>): Parser<T[]>;
238 /**
239 * Equivalent to Parsimmon.sepBy(parser, separator).
240 *
241 * Expects one or more matches for parser, separated by the parser separator, yielding a non-empty array.
242 */
243 sepBy1<U>(separator: Parser<U>): Parser<[T, ...T[]]>;
244 /**
245 * Equivalent to Parsimmon.of(result).
246 */
247 of<U>(result: U): Parser<U>;
248 }
249
250 type UnParser<T> = T extends Parser<infer U> ? U : never;
251
252 /**
253 * Alias of `Parsimmon(fn)` for backwards compatibility.
254 */
255 function Parser<T>(fn: (input: string, i: number) => Parsimmon.Reply<T>): Parser<T>;
256
257 /**
258 * Starting point for building a language parser in Parsimmon.
259 *
260 * For having the resulting language rules return typed parsers, e.g. `Parser<Foo>` instead of
261 * `Parser<any>`, pass a language specification as type parameter to this function. The language
262 * specification should be of the following form:
263 *
264 * ```javascript
265 * {
266 * rule1: type;
267 * rule2: type;
268 * }
269 * ```
270 *
271 * For example:
272 *
273 * ```javascript
274 * const language = Parsimmon.createLanguage<{
275 * expr: Expr;
276 * numberLiteral: number;
277 * stringLiteral: string;
278 * }>({
279 * expr: r => (some expression that yields Parser<Expr>),
280 * numberLiteral: r => (some expression that yields Parser<number>),
281 * stringLiteral: r => (some expression that yields Parser<string>)
282 * });
283 * ```
284 *
285 * Now both `language` and the parameter `r` that is passed into every parser rule will be of the
286 * following type:
287 *
288 * ```javascript
289 * {
290 * expr: Parser<Expr>;
291 * numberLiteral: Parser<number>;
292 * stringLiteral: Parser<string>;
293 * }
294 * ```
295 *
296 * Another benefit is that both the `rules` parameter and the resulting `language` should match the
297 * properties defined in the language specification type, which means that the compiler checks that
298 * there are no missing or superfluous rules in the language definition, and that the rules you access
299 * on the resulting language do actually exist.
300 */
301 function createLanguage(rules: Rule): Language;
302 function createLanguage<TLanguageSpec>(rules: TypedRule<TLanguageSpec>): TypedLanguage<TLanguageSpec>;
303
304 /**
305 * To be used inside of Parsimmon(fn). Generates an object describing how
306 * far the successful parse went (index), and what value it created doing
307 * so. See documentation for Parsimmon(fn).
308 */
309 function makeSuccess<T>(index: number, value: T): SuccessReply<T>;
310
311 /**
312 * To be used inside of Parsimmon(fn). Generates an object describing how
313 * far the unsuccessful parse went (index), and what kind of syntax it
314 * expected to see (expectation). See documentation for Parsimmon(fn).
315 */
316 function makeFailure(furthest: number, expectation: string | string[]): FailureReply;
317
318 /**
319 * Returns true if obj is a Parsimmon parser, otherwise false.
320 */
321 function isParser(obj: any): obj is Parser<any>;
322
323 /**
324 * is a parser that expects to find "my-string", and will yield the same.
325 */
326 function string<T extends string>(string: T): Parser<T>;
327
328 /**
329 * Returns a parser that looks for exactly one character from string, and yields that character.
330 */
331 function oneOf(string: string): Parser<string>;
332
333 /**
334 * Returns a parser that looks for exactly one character NOT from string, and yields that character.
335 */
336 function noneOf(string: string): Parser<string>;
337
338 /**
339 * Parsers a single character in from begin to end, inclusive.
340 */
341 function range(begin: string, end: string): Parser<string>;
342
343 /**
344 * Returns a parser that looks for a match to the regexp and yields the given match group
345 * (defaulting to the entire match). The regexp will always match starting at the current
346 * parse location. The regexp may only use the following flags: imu. Any other flag will
347 * result in an error being thrown.
348 */
349 function regexp(myregex: RegExp, group?: number): Parser<string>;
350
351 /**
352 * This was the original name for Parsimmon.regexp, but now it is just an alias.
353 */
354 function regex(myregex: RegExp, group?: number): Parser<string>;
355
356 /**
357 * Parses using parser, but does not consume what it parses. Yields null if the parser
358 * does not match the input. Otherwise it fails.
359 */
360 function notFollowedBy(parser: Parser<any>): Parser<null>;
361
362 /**
363 * Parses using arg, but does not consume what it parses. Yields an empty string.
364 */
365 function lookahead(arg: Parser<any> | string | RegExp): Parser<"">;
366
367 /**
368 * Returns a parser that doesn't consume any of the string, and yields result.
369 */
370 function succeed<U>(result: U): Parser<U>;
371
372 /**
373 * This is an alias for Parsimmon.succeed(result).
374 */
375 function of<U>(result: U): Parser<U>;
376
377 /**
378 * accepts a variable number of parsers that it expects to find in order, yielding an array of the results.
379 */
380 function seq<T>(p1: Parser<T>): Parser<[T]>;
381 function seq<T, U>(p1: Parser<T>, p2: Parser<U>): Parser<[T, U]>;
382 function seq<T, U, V>(p1: Parser<T>, p2: Parser<U>, p3: Parser<V>): Parser<[T, U, V]>;
383 function seq<T, U, V, W>(p1: Parser<T>, p2: Parser<U>, p3: Parser<V>, p4: Parser<W>): Parser<[T, U, V, W]>;
384 function seq<T, U, V, W, X>(
385 p1: Parser<T>,
386 p2: Parser<U>,
387 p3: Parser<V>,
388 p4: Parser<W>,
389 p5: Parser<X>,
390 ): Parser<[T, U, V, W, X]>;
391 function seq<T, U, V, W, X, Y>(
392 p1: Parser<T>,
393 p2: Parser<U>,
394 p3: Parser<V>,
395 p4: Parser<W>,
396 p5: Parser<X>,
397 p6: Parser<Y>,
398 ): Parser<[T, U, V, W, X, Y]>;
399 function seq<T, U, V, W, X, Y, Z>(
400 p1: Parser<T>,
401 p2: Parser<U>,
402 p3: Parser<V>,
403 p4: Parser<W>,
404 p5: Parser<X>,
405 p6: Parser<Y>,
406 p7: Parser<Z>,
407 ): Parser<[T, U, V, W, X, Y, Z]>;
408 function seq<T>(...parsers: Array<Parser<T>>): Parser<T[]>;
409 function seq<T extends any[]>(...parsers: T): Parser<UnParser<T>>;
410
411 /**
412 * Takes the string passed to parser.parse(string) and the error returned from
413 * parser.parse(string) and turns it into a human readable error message string.
414 * Note that there are certainly better ways to format errors, so feel free to write your own.
415 */
416 function formatError<T>(string: string, error: Result<T>): string;
417
418 /**
419 * Matches all parsers sequentially, and passes their results as the arguments to a function.
420 * Similar to calling Parsimmon.seq and then .map, but the values are not put in an array.
421 */
422 function seqMap<T, U>(p1: Parser<T>, cb: (a1: T) => U): Parser<U>;
423 function seqMap<T, U, V>(p1: Parser<T>, p2: Parser<U>, cb: (a1: T, a2: U) => V): Parser<V>;
424 function seqMap<T, U, V, W>(p1: Parser<T>, p2: Parser<U>, p3: Parser<V>, cb: (a1: T, a2: U, a3: V) => W): Parser<W>;
425 function seqMap<T, U, V, W, X>(
426 p1: Parser<T>,
427 p2: Parser<U>,
428 p3: Parser<V>,
429 p4: Parser<W>,
430 cb: (a1: T, a2: U, a3: V, a4: W) => X,
431 ): Parser<X>;
432 function seqMap<T, U, V, W, X, Y>(
433 p1: Parser<T>,
434 p2: Parser<U>,
435 p3: Parser<V>,
436 p4: Parser<W>,
437 p5: Parser<X>,
438 cb: (a1: T, a2: U, a3: V, a4: W, a5: X) => Y,
439 ): Parser<Y>;
440 function seqMap<T, U, V, W, X, Y, Z>(
441 p1: Parser<T>,
442 p2: Parser<U>,
443 p3: Parser<V>,
444 p4: Parser<W>,
445 p5: Parser<X>,
446 p6: Parser<Y>,
447 cb: (a1: T, a2: U, a3: V, a4: W, a5: X, a6: Y) => Z,
448 ): Parser<Z>;
449 function seqMap<T, U, V, W, X, Y, Z, A>(
450 p1: Parser<T>,
451 p2: Parser<U>,
452 p3: Parser<V>,
453 p4: Parser<W>,
454 p5: Parser<X>,
455 p6: Parser<Y>,
456 p7: Parser<Z>,
457 cb: (a1: T, a2: U, a3: V, a4: W, a5: X, a6: Y, a7: Z) => A,
458 ): Parser<A>;
459 function seqMap<T, U, V, W, X, Y, Z, A, B>(
460 p1: Parser<T>,
461 p2: Parser<U>,
462 p3: Parser<V>,
463 p4: Parser<W>,
464 p5: Parser<X>,
465 p6: Parser<Y>,
466 p7: Parser<Z>,
467 p8: Parser<A>,
468 cb: (a1: T, a2: U, a3: V, a4: W, a5: X, a6: Y, a7: Z, a8: A) => B,
469 ): Parser<B>;
470 function seqMap<T, U, V, W, X, Y, Z, A, B, C>(
471 p1: Parser<T>,
472 p2: Parser<U>,
473 p3: Parser<V>,
474 p4: Parser<W>,
475 p5: Parser<X>,
476 p6: Parser<Y>,
477 p7: Parser<Z>,
478 p8: Parser<A>,
479 p9: Parser<B>,
480 cb: (a1: T, a2: U, a3: V, a4: W, a5: X, a6: Y, a7: Z, a8: A, a9: B) => C,
481 ): Parser<C>;
482 function seqMap<T, U, V, W, X, Y, Z, A, B, C, D>(
483 p1: Parser<T>,
484 p2: Parser<U>,
485 p3: Parser<V>,
486 p4: Parser<W>,
487 p5: Parser<X>,
488 p6: Parser<Y>,
489 p7: Parser<Z>,
490 p8: Parser<A>,
491 p9: Parser<B>,
492 p10: Parser<C>,
493 cb: (a1: T, a2: U, a3: V, a4: W, a5: X, a6: Y, a7: Z, a8: A, a9: B, a10: C) => D,
494 ): Parser<D>;
495
496 function seqObj<T, Key extends keyof T = keyof T>(
497 ...args: Array<[Key, Parser<T[Key]>] | Parser<any>>
498 ): Parser<{ [K in Key]: T[K] }>;
499
500 interface SuccessReply<T> {
501 status: true;
502 index: number;
503 value: T;
504 furthest: -1;
505 expected: string[];
506 }
507
508 interface FailureReply {
509 status: false;
510 index: -1;
511 value: null;
512 furthest: number;
513 expected: string[];
514 }
515
516 type Reply<T> = SuccessReply<T> | FailureReply;
517
518 type SuccessFunctionType<U> = (index: number, result: U) => Reply<U>;
519 type FailureFunctionType<U> = (index: number, msg: string) => Reply<U>;
520 type ParseFunctionType<U> = (stream: StreamType, index: number) => Reply<U>;
521 /**
522 * allows to add custom primitive parsers.
523 */
524 function custom<U>(
525 parsingFunction: (success: SuccessFunctionType<U>, failure: FailureFunctionType<U>) => ParseFunctionType<U>,
526 ): Parser<U>;
527
528 /**
529 * accepts a variable number of parsers, and yields the value of the first one that succeeds,
530 * backtracking in between.
531 */
532 function alt<U>(...parsers: Array<Parser<U>>): Parser<U>;
533 function alt(...parsers: Array<Parser<any>>): Parser<any>;
534
535 /**
536 * Accepts two parsers, and expects zero or more matches for content, separated by separator, yielding an array.
537 */
538 function sepBy<T, U>(content: Parser<T>, separator: Parser<U>): Parser<T[]>;
539
540 /**
541 * This is the same as Parsimmon.sepBy, but matches the content parser at least once.
542 */
543 function sepBy1<T, U>(content: Parser<T>, separator: Parser<U>): Parser<[T, ...T[]]>;
544
545 /**
546 * accepts a function that returns a parser, which is evaluated the first time the parser is used.
547 * This is useful for referencing parsers that haven't yet been defined.
548 */
549 function lazy<U>(f: () => Parser<U>): Parser<U>;
550 function lazy<U>(description: string, f: () => Parser<U>): Parser<U>;
551
552 /**
553 * fail paring with a message
554 */
555 function fail(message: string): Parser<never>;
556
557 /**
558 * Returns Parsimmon.fail("fantasy-land/empty").
559 */
560 function empty(): Parser<never>;
561
562 /**
563 * is equivalent to Parsimmon.regex(/[a-z]/i)
564 */
565 const letter: Parser<string>;
566 /**
567 * is equivalent to Parsimmon.regex(/[a-z]*`/i)
568 */
569 const letters: Parser<string>;
570 /**
571 * is equivalent to Parsimmon.regex(/[0-9]/)
572 */
573 const digit: Parser<string>;
574 /**
575 * is equivalent to Parsimmon.regex(/[0-9]*`/)
576 */
577 const digits: Parser<string>;
578 /**
579 * is equivalent to Parsimmon.regex(/\s+/)
580 */
581 const whitespace: Parser<string>;
582 /**
583 * is equivalent to Parsimmon.regex(/\s*`/)
584 */
585 const optWhitespace: Parser<string>;
586 /**
587 * Equivalent to Parsimmon.string("\r").
588 *
589 * This parser checks for the "carriage return" character, which is used as the
590 * line terminator for classic Mac OS 9 text files.
591 */
592 const cr: Parser<string>;
593 /**
594 * Equivalent to Parsimmon.string("\n").
595 *
596 * This parser checks for the "line feed" character, which is used as the line
597 * terminator for Linux and macOS text files.
598 */
599 const lf: Parser<string>;
600 /**
601 * Equivalent to Parsimmon.string("\r\n").
602 *
603 * This parser checks for the "carriage return" character followed by the "line
604 * feed" character, which is used as the line terminator for Windows text files
605 * and HTTP headers.
606 */
607 const crlf: Parser<string>;
608 /**
609 * This flexible parser will match any kind of text file line ending.
610 */
611 const newline: Parser<string>;
612 /**
613 * Equivalent to Parsimmon.alt(Parsimmon.newline, Parsimmon.eof).
614 *
615 * This is the most general purpose "end of line" parser. It allows the "end of file"
616 * in addition to all three text file line endings from Parsimmon.newline. This is
617 * important because text files frequently do not have line terminators at the
618 * end ("trailing newline").
619 */
620 const end: Parser<undefined | string>;
621 /**
622 * consumes and yields the next character of the stream.
623 */
624 const any: Parser<string>;
625 /**
626 * consumes and yields the entire remainder of the stream.
627 */
628 const all: Parser<string>;
629 /**
630 * expects the end of the stream.
631 */
632 const eof: Parser<undefined>;
633 /**
634 * is a parser that yields the current index of the parse.
635 */
636 const index: Parser<Index>;
637 /**
638 * Returns a parser that yield a single character if it passes the predicate
639 */
640 function test(predicate: (char: string) => boolean): Parser<string>;
641 /**
642 * Returns a parser yield a string containing all the next characters that pass the predicate
643 */
644 function takeWhile(predicate: (char: string) => boolean): Parser<string>;
645 /**
646 * Returns a parser that yields a byte (as a number) that matches the given input;
647 * similar to Parsimmon.digit and Parsimmon.letter.
648 */
649 function byte(int: number): Parser<number>;
650 /**
651 * Returns a parser that yields a byte (as a number) that matches the given input;
652 * similar to Parsimmon.digit and Parsimmon.letter.
653 */
654 function bitSeq(alignments: number[]): Parser<number[]>;
655 /**
656 * Works like Parsimmon.bitSeq except each item in the array is either a number of
657 * bits or pair (array with length = 2) of name and bits. The bits are parsed in order
658 * and put into an object based on the name supplied. If there's no name for the bits,
659 * it will be parsed but discarded from the returned value.
660 */
661 function bitSeqObj<Key extends string>(
662 namedAlignments: Array<[Key, number] | number>,
663 ): Parser<{ [K in Key]: number }>;
664}
665
666export = Parsimmon;