parser-ts
Version:
String parser combinators for TypeScript
473 lines (472 loc) • 14.5 kB
TypeScript
/**
* @since 0.6.0
*/
import { Alt2 } from 'fp-ts/es6/Alt'
import { Alternative2 } from 'fp-ts/es6/Alternative'
import { Applicative2 } from 'fp-ts/es6/Applicative'
import { ChainRec2 } from 'fp-ts/es6/ChainRec'
import { Lazy } from 'fp-ts/es6/function'
import { Functor2 } from 'fp-ts/es6/Functor'
import { Monad2 } from 'fp-ts/es6/Monad'
import { Monoid } from 'fp-ts/es6/Monoid'
import * as NEA from 'fp-ts/es6/NonEmptyArray'
import * as O from 'fp-ts/es6/Option'
import { Predicate } from 'fp-ts/es6/Predicate'
import * as RNEA from 'fp-ts/es6/ReadonlyNonEmptyArray'
import { Refinement } from 'fp-ts/es6/Refinement'
import { Semigroup } from 'fp-ts/es6/Semigroup'
import { ParseResult } from './ParseResult'
import { Stream } from './Stream'
/**
* @category model
* @since 0.6.0
*/
export interface Parser<I, A> {
(i: Stream<I>): ParseResult<I, A>
}
/**
* The `succeed` parser constructor creates a parser which will simply
* return the value provided as its argument, without consuming any input.
*
* This is equivalent to the monadic `of`.
*
* @category constructors
* @since 0.6.0
*/
export declare const succeed: <I, A>(a: A) => Parser<I, A>
/**
* The `fail` parser will just fail immediately without consuming any input
*
* @category constructors
* @since 0.6.0
*/
export declare const fail: <I, A = never>() => Parser<I, A>
/**
* The `failAt` parser will fail immediately without consuming any input,
* but will report the failure at the provided input position.
*
* @category constructors
* @since 0.6.0
*/
export declare const failAt: <I, A = never>(i: Stream<I>) => Parser<I, A>
/**
* The `sat` parser constructor takes a predicate function, and will consume
* a single character if calling that predicate function with the character
* as its argument returns `true`. If it returns `false`, the parser will
* fail.
*
* @category constructors
* @since 0.6.0
*/
export declare const sat: <I>(predicate: Predicate<I>) => Parser<I, I>
/**
* A parser combinator which returns the provided parser unchanged, except
* that if it fails, the provided error message will be returned in the
* ParseError`.
*
* @category combinators
* @since 0.6.0
*/
export declare const expected: <I, A>(p: Parser<I, A>, message: string) => Parser<I, A>
/**
* The `item` parser consumes a single value, regardless of what it is,
* and returns it as its result.
*
* @category combinators
* @since 0.6.0
*/
export declare const item: <I>() => Parser<I, I>
/**
* The `cut` parser combinator takes a parser and produces a new parser for
* which all errors are fatal, causing either to stop trying further
* parsers and return immediately with a fatal error.
*
* @category combinators
* @since 0.6.0
*/
export declare const cut: <I, A>(p: Parser<I, A>) => Parser<I, A>
/**
* Takes two parsers `p1` and `p2`, returning a parser which will match
* `p1` first, discard the result, then either match `p2` or produce a fatal
* error.
*
* @category combinators
* @since 0.6.0
*/
export declare const cutWith: <I, A, B>(p1: Parser<I, A>, p2: Parser<I, B>) => Parser<I, B>
/**
* The `seq` combinator takes a parser, and a function which will receive
* the result of that parser if it succeeds, and which should return another
* parser, which will be run immediately after the initial parser. In this
* way, you can join parsers together in a sequence, producing more complex
* parsers.
*
* This is equivalent to the monadic `chain` operation.
*
* @category combinators
* @since 0.6.0
*/
export declare const seq: <I, A, B>(fa: Parser<I, A>, f: (a: A) => Parser<I, B>) => Parser<I, B>
/**
* The `either` combinator takes two parsers, runs the first on the input
* stream, and if that fails, it will backtrack and attempt the second
* parser on the same input. Basically, try parser 1, then try parser 2.
*
* If the first parser fails with an error flagged as fatal (see `cut`),
* the second parser will not be attempted.
*
* This is equivalent to the `alt` operation.
*
* @category combinators
* @since 0.6.0
*/
export declare const either: <I, A>(p: Parser<I, A>, f: () => Parser<I, A>) => Parser<I, A>
/**
* Converts a parser into one which will return the point in the stream where
* it started parsing in addition to its parsed value.
*
* Useful if you want to keep track of where in the input stream a parsed
* token came from.
*
* @category combinators
* @since 0.6.0
*/
export declare const withStart: <I, A>(p: Parser<I, A>) => Parser<I, [A, Stream<I>]>
/**
* The `maybe` parser combinator creates a parser which will run the provided
* parser on the input, and if it fails, it will returns the empty value (as
* defined by `empty`) as a result, without consuming any input.
*
* @category combinators
* @since 0.6.0
*/
export declare const maybe: <A>(M: Monoid<A>) => <I>(p: Parser<I, A>) => Parser<I, A>
/**
* Matches the end of the stream.
*
* @category combinators
* @since 0.6.0
*/
export declare const eof: <I>() => Parser<I, void>
/**
* The `many` combinator takes a parser, and returns a new parser which will
* run the parser repeatedly on the input stream until it fails, returning
* a list of the result values of each parse operation as its result, or the
* empty list if the parser never succeeded.
*
* Read that as "match this parser zero or more times and give me a list of
* the results."
*
* @category combinators
* @since 0.6.0
*/
export declare const many: <I, A>(p: Parser<I, A>) => Parser<I, A[]>
/**
* The `many1` combinator is just like the `many` combinator, except it
* requires its wrapped parser to match at least once. The resulting list is
* thus guaranteed to contain at least one value.
*
* @category combinators
* @since 0.6.0
*/
export declare const many1: <I, A>(parser: Parser<I, A>) => Parser<I, NEA.NonEmptyArray<A>>
/**
* Matches the provided parser `p` zero or more times, but requires the
* parser `sep` to match once in between each match of `p`. In other words,
* use `sep` to match separator characters in between matches of `p`.
*
* @category combinators
* @since 0.6.0
*/
export declare const sepBy: <I, A, B>(sep: Parser<I, A>, p: Parser<I, B>) => Parser<I, B[]>
/**
* Matches the provided parser `p` one or more times, but requires the
* parser `sep` to match once in between each match of `p`. In other words,
* use `sep` to match separator characters in between matches of `p`.
*
* @category combinators
* @since 0.6.0
*/
export declare const sepBy1: <I, A, B>(sep: Parser<I, A>, p: Parser<I, B>) => Parser<I, NEA.NonEmptyArray<B>>
/**
* Like `sepBy1`, but cut on the separator, so that matching a `sep` not
* followed by a `p` will cause a fatal error.
*
* @category combinators
* @since 0.6.0
*/
export declare const sepByCut: <I, A, B>(sep: Parser<I, A>, p: Parser<I, B>) => Parser<I, NEA.NonEmptyArray<B>>
/**
* Filters the result of a parser based upon a `Refinement` or a `Predicate`.
*
* @example
* import { pipe } from 'fp-ts/function'
* import { run } from 'parser-ts/code-frame'
* import * as C from 'parser-ts/char'
* import * as P from 'parser-ts/Parser'
*
* const parser = P.expected(
* pipe(
* P.item<C.Char>(),
* P.filter((c) => c !== 'a')
* ),
* 'anything except "a"'
* )
*
* run(parser, 'a')
* // { _tag: 'Left', left: '> 1 | a\n | ^ Expected: anything except "a"' }
*
* run(parser, 'b')
* // { _tag: 'Right', right: 'b' }
*
* @category combinators
* @since 0.6.10
*/
export declare const filter: {
<A, B extends A>(refinement: Refinement<A, B>): <I>(p: Parser<I, A>) => Parser<I, B>
<A>(predicate: Predicate<A>): <I>(p: Parser<I, A>) => Parser<I, A>
}
/**
* Matches the provided parser `p` that occurs between the provided `left` and `right` parsers.
*
* `p` is polymorphic in its return type, because in general bounds and actual parser could return different types.
*
* @category combinators
* @since 0.6.4
*/
export declare const between: <I, A>(left: Parser<I, A>, right: Parser<I, A>) => <B>(p: Parser<I, B>) => Parser<I, B>
/**
* Matches the provided parser `p` that is surrounded by the `bound` parser. Shortcut for `between(bound, bound)`.
*
* @category combinators
* @since 0.6.4
*/
export declare const surroundedBy: <I, A>(bound: Parser<I, A>) => <B>(p: Parser<I, B>) => Parser<I, B>
/**
* Takes a `Parser` and tries to match it without consuming any input.
*
* @example
* import { run } from 'parser-ts/code-frame'
* import * as P from 'parser-ts/Parser'
* import * as S from 'parser-ts/string'
*
* const parser = S.fold([
* S.string('hello '),
* P.lookAhead(S.string('world')),
* S.string('wor')
* ])
*
* run(parser, 'hello world')
* // { _tag: 'Right', right: 'hello worldwor' }
*
* @category combinators
* @since 0.6.6
*/
export declare const lookAhead: <I, A>(p: Parser<I, A>) => Parser<I, A>
/**
* Takes a `Predicate` and continues parsing until the given `Predicate` is satisfied.
*
* @example
* import * as C from 'parser-ts/char'
* import { run } from 'parser-ts/code-frame'
* import * as P from 'parser-ts/Parser'
*
* const parser = P.takeUntil((c: C.Char) => c === 'w')
*
* run(parser, 'hello world')
* // { _tag: 'Right', right: [ 'h', 'e', 'l', 'l', 'o', ' ' ] }
*
* @category combinators
* @since 0.6.6
*/
export declare const takeUntil: <I>(predicate: Predicate<I>) => Parser<I, Array<I>>
/**
* Returns `Some<A>` if the specified parser succeeds, otherwise returns `None`.
*
* @example
* import * as C from 'parser-ts/char'
* import { run } from 'parser-ts/code-frame'
* import * as P from 'parser-ts/Parser'
*
* const a = P.sat((c: C.Char) => c === 'a')
* const parser = P.optional(a)
*
* run(parser, 'a')
* // { _tag: 'Right', right: { _tag: 'Some', value: 'a' } }
*
* run(parser, 'b')
* // { _tag: 'Left', left: { _tag: 'None' } }
*
* @category combinators
* @since 0.6.10
*/
export declare const optional: <I, A>(parser: Parser<I, A>) => Parser<I, O.Option<A>>
/**
* The `manyTill` combinator takes a value `parser` and a `terminator` parser, and
* returns a new parser that will run the value `parser` repeatedly on the input
* stream, returning a list of the result values of each parse operation as its
* result, or the empty list if the parser never succeeded.
*
* @example
* import * as C from 'parser-ts/char'
* import { run } from 'parser-ts/code-frame'
* import * as P from 'parser-ts/Parser'
*
* const parser = P.manyTill(C.letter, C.char('-'))
*
* run(parser, 'abc-')
* // { _tag: 'Right', right: [ 'a', 'b', 'c' ] }
*
* run(parser, '-')
* // { _tag: 'Right', right: [] }
*
* @category combinators
* @since 0.6.11
*/
export declare const manyTill: <I, A, B>(parser: Parser<I, A>, terminator: Parser<I, B>) => Parser<I, readonly A[]>
/**
* The `many1Till` combinator is just like the `manyTill` combinator, except it
* requires the value `parser` to match at least once before the `terminator`
* parser. The resulting list is thus guaranteed to contain at least one value.
*
* @example
* import * as C from 'parser-ts/char'
* import { run } from 'parser-ts/code-frame'
* import * as P from 'parser-ts/Parser'
*
* const parser = P.many1Till(C.letter, C.char('-'))
*
* run(parser, 'abc-')
* // { _tag: 'Right', right: [ 'a', 'b', 'c' ] }
*
* run(parser, '-')
* // { _tag: 'Left', left: '> 1 | -\n | ^ Expected: a letter' }
*
* @category combinators
* @since 0.6.11
*/
export declare const many1Till: <I, A, B>(
parser: Parser<I, A>,
terminator: Parser<I, B>
) => Parser<I, RNEA.ReadonlyNonEmptyArray<A>>
/**
* @category Functor
* @since 0.6.7
*/
export declare const map: <A, B>(f: (a: A) => B) => <I>(fa: Parser<I, A>) => Parser<I, B>
/**
* @category Apply
* @since 0.6.7
*/
export declare const ap: <I, A>(fa: Parser<I, A>) => <B>(fab: Parser<I, (a: A) => B>) => Parser<I, B>
/**
* @category Apply
* @since 0.6.7
*/
export declare const apFirst: <I, B>(fb: Parser<I, B>) => <A>(fa: Parser<I, A>) => Parser<I, A>
/**
* @category Apply
* @since 0.6.7
*/
export declare const apSecond: <I, B>(fb: Parser<I, B>) => <A>(fa: Parser<I, A>) => Parser<I, B>
/**
* @category Applicative
* @since 0.6.7
*/
export declare const of: <I, A>(a: A) => Parser<I, A>
/**
* @category Monad
* @since 0.6.7
*/
export declare const chain: <I, A, B>(f: (a: A) => Parser<I, B>) => (ma: Parser<I, A>) => Parser<I, B>
/**
* @category Monad
* @since 0.6.7
*/
export declare const chainFirst: <I, A, B>(f: (a: A) => Parser<I, B>) => (ma: Parser<I, A>) => Parser<I, A>
/**
* @category Alt
* @since 0.6.7
*/
export declare const alt: <I, A>(that: Lazy<Parser<I, A>>) => (fa: Parser<I, A>) => Parser<I, A>
/**
* @category Monad
* @since 0.6.7
*/
export declare const flatten: <I, A>(mma: Parser<I, Parser<I, A>>) => Parser<I, A>
/**
* @category Alternative
* @since 0.6.7
*/
export declare const zero: <I, A>() => Parser<I, A>
/**
* @category instances
* @since 0.6.0
*/
export declare const URI = 'Parser'
/**
* @category instances
* @since 0.6.0
*/
export type URI = typeof URI
declare module 'fp-ts/es6/HKT' {
interface URItoKind2<E, A> {
Parser: Parser<E, A>
}
}
/**
* @category instances
* @since 0.6.7
*/
export declare const getSemigroup: <I, A>(S: Semigroup<A>) => Semigroup<Parser<I, A>>
/**
* @category instances
* @since 0.6.0
*/
export declare const getMonoid: <I, A>(M: Monoid<A>) => Monoid<Parser<I, A>>
/**
* @category instances
* @since 0.6.7
*/
export declare const Functor: Functor2<URI>
/**
* @category instances
* @since 0.6.7
*/
export declare const Applicative: Applicative2<URI>
/**
* @category instances
* @since 0.6.7
*/
export declare const Monad: Monad2<URI>
/**
* @category instances
* @since 0.6.11
*/
export declare const ChainRec: ChainRec2<URI>
/**
* @category instances
* @since 0.6.7
*/
export declare const Alt: Alt2<URI>
/**
* @category instances
* @since 0.6.7
*/
export declare const Alternative: Alternative2<URI>
/**
* @category instances
* @since 0.6.7
*/
export declare const parser: Monad2<URI> & Alternative2<URI>
/**
* @since 0.6.8
*/
export declare const bindTo: <N extends string>(name: N) => <I, A>(fa: Parser<I, A>) => Parser<I, { [K in N]: A }>
/**
* @since 0.6.8
*/
export declare const bind: <N extends string, I, A, B>(
name: Exclude<N, keyof A>,
f: (a: A) => Parser<I, B>
) => (fa: Parser<I, A>) => Parser<I, { [K in N | keyof A]: K extends keyof A ? A[K] : B }>