UNPKG

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