/**
 * Creates a Parser that skips the next code point if the given predicate returns true.
 *
 * This counts in unicode characters (code points), not UTF-16 code units.
 *
 * To match a sequence of code points, consider using `codepoints` instead.
 *
 * @public
 *
 * @param isMatch  - callback called with the next codepoint, should return whether that matches
 * @param expected - expected strings to return if the codepoint does not match
 */
export declare function codepoint(isMatch: (codepoint: number) => boolean, expected: string[]): Parser<void>;

/**
 * Creates a Parser that skips code points while the given predicate returns true.
 *
 * This counts in unicode characters (code points), not UTF-16 code units.
 *
 * This acts like `starConsumed(codepoint(isMatch, []))` if expected is not set, or as
 * `plusConsumed(codepoint(isMatch, expected))` if it is, but is much more efficient than either of
 * those combinations.
 *
 * @public
 *
 * @param isMatch  - callback called for each codepoint, should return whether that matches
 * @param expected - expected strings to return if the first codepoint does not match
 */
export declare function codepoints(isMatch: (codepoint: number) => boolean, expected?: string[]): Parser<void>;

/**
 * Helper to collect both the yielded values and the returned value from a generator.
 *
 * @public
 *
 * @param gen - Generator to collect from
 */
export declare function collect<T, R>(gen: Generator<T, R>): [T[], R];

/**
 * Creates a Parser that applies the given parser and only succeeds (returning the inner parser's
 * result) if parsing concludes at the end of the input string.
 *
 * @public
 *
 * @param parser - The parser to wrap
 */
export declare function complete<T>(parser: Parser<T>): Parser<T>;

/**
 * Creates a Parser that applies the given parser but discards the resulting value.
 *
 * @public
 *
 * @param parser - Parser to apply
 */
export declare function consume<T>(parser: Parser<T>): Parser<void>;

/**
 * Creates a Parser that turns errors returned by the inner parser into fatal errors. Parsers such
 * as `or` and `star` will not continue to attempt additional matches if a parser returns a fatal
 * error, and will usually return the error instead.
 *
 * @public
 *
 * @param parser - The parser to wrap
 */
export declare function cut<T>(parser: Parser<T>): Parser<T>;

/**
 * Creates a Parser that applies the given parsers in sequence, returning the result value of the
 * middle parser at the offset of the third if all are successful. If any parser fails, the error is
 * returned as-is.
 *
 * Optionally makes errors by the second and third parsers fatal if `cutAfterOpen` is `true`.
 *
 * @public
 *
 * @param open         - First parser to apply, value is discarded
 * @param inner        - Second parser to apply, value is kept
 * @param close        - Third parser to apply, value is discarded
 * @param cutAfterOpen - If `true`, errors returned by the second and third parsers are considered
 *                       fatal, causing parsers using this to stop trying other branches.
 */
export declare function delimited<TOpen, T, TClose>(open: Parser<TOpen>, inner: Parser<T>, close: Parser<TClose>, cutAfterOpen?: boolean): Parser<T>;

/**
 * Creates a parser that looks at a single codepoint to determine which parser to invoke. Can be
 * used as an alternative to large `or` parsers if looking ahead can narrow down the options.
 *
 * Can optionally look ahead further than the current codepoint, which is useful when nesting
 * several `dispatch` parsers.
 *
 * @public
 *
 * @param mapping     - Object mapping code points to parsers
 * @param otherwise   - Parser to use when the code point is not found in the mapping, or undefined
 *                      to reject in that situation.
 * @param extraOffset - How far ahead to look for the codepoint, defaults to 0
 * @param expected    - Expected values for parse errors generated when there is no codepoint or
 *                      when the codepoint is not in the mapping and there is no `otherwise` parser
 */
export declare function dispatch<T>(mapping: {
    [codepoint: number]: Parser<T>;
}, otherwise: Parser<T> | undefined, extraOffset?: number, expected?: string[]): Parser<T>;

/**
 * A parser that only succeeds if the end of the input string is reached.
 *
 * @public
 *
 * @param input  - The input to match in
 * @param offset - The offset in `input` at which to start matching
 */
export declare const end: Parser<void>;

/**
 * Creates an unsuccessful ParseResult (parse error) at the given offset.
 *
 * @public
 *
 * @param offset   - The offset in the input at which matching failed
 * @param expected - An array of strings indicating things that were expected at offset
 * @param fatal    - If true, no other branches should be tried as a result of this error
 */
export declare function error<T>(offset: number, expected: string[], fatal?: boolean): ParseResult<T>;

/**
 * Creates a Parser that matches only if the first Parser matches input at the starting position,
 * but the second Parser does not.
 *
 * @public
 *
 * @param match    - Parser that should match
 * @param except   - Parser that should not match
 * @param expected - Expected values for parse errors generated when the except parser succeeds
 */
export declare function except<T, U>(match: Parser<T>, except: Parser<U>, expected: string[]): Parser<T>;

/**
 * Creates a Parser that uses the given filter predicate to check values generated by the given
 * parser. Values that pass the predicate are passed through, those that don't return a parse error
 * instead.
 *
 * @public
 *
 * @param parser   - Parser to filter
 * @param filter   - Predicate function over the inner parser's values
 * @param expected - Expected values for parse errors generated when the filter rejects a value
 * @param fatal    - Whether the error returned when the filter rejects should be fatal
 */
export declare function filter<T>(parser: Parser<T>, filter: (v: T) => boolean, expected: string[], fatal?: boolean): Parser<T>;

/**
 * Creates a parser that discards undefined values from the array produced by the
 * given parser.
 *
 * Useful in combination with `star`, `or` and `consume`:
 *
 * ```
 * const a: Parser<string> = token('a');
 * const b: Parser<void> = consume(token('b'));
 * const abs: Parser<(string | void)[]> = star(or<string | void>([a, b]));
 * const as: Parser<string[]> = filterUndefined(abs);
 * ```
 *
 * @public
 *
 * @param parser - Parser to apply, should produce an array that may contain undefined entries.
 */
export declare function filterUndefined<T>(parser: Parser<(T | void)[]>): Parser<T[]>;

/**
 * Returns the first of the given two arguments. Useful as a `join` function for `then`. See also
 * `followed`.
 *
 * @public
 *
 * @param x - Argument to return
 * @param y - Argument to ignore
 */
export declare function first<T1, T2>(x: T1, y: T2): T1;

/**
 * Creates a Parser that applies the given two parsers in sequence, returning the result value of
 * the first at the offset of the second if both succeed. If either parser fails the error is
 * returned as-is.
 *
 * Equivalent to `then(parser, after, first)`.
 *
 * @public
 *
 * @param parser - First parser to apply, value is kept
 * @param before - Second parser to apply, value is discarded
 */
export declare function followed<T, TAfter>(parser: Parser<T>, after: Parser<TAfter>): Parser<T>;

/**
 * Creates a Parser that applies the given function to each value generated by the given parser.
 *
 * @public
 *
 * @param parser - Parser to map over
 * @param map    - Function to transform values generated by parser
 */
export declare function map<T, U>(parser: Parser<T>, map: (v: T) => U): Parser<U>;

/**
 * Creates a Parser that succeeds at the starting offset if the given parser fails and vice-versa.
 *
 * @public
 *
 * @param parser   - The parser to apply
 * @param expected - Expected values for parse errors generated when the inner parser succeeds
 */
export declare function not<T>(parser: Parser<T>, expected: string[]): Parser<void>;

/**
 * Creates a successful ParseResult with an undefined value. Use this to signal success in cases
 * where no value is required.
 *
 * @public
 *
 * @param offset - The offset in the input at which to continue parsing
 */
export declare function ok(offset: number): ParseResult<undefined>;

/**
 * Creates a successful ParseResult containing the given value.
 *
 * @public
 *
 * @param offset - The offset in the input at which to continue parsing
 * @param value  - The value resulting from applying the parser
 */
export declare function okWithValue<T>(offset: number, value: T): ParseResult<T>;

/**
 * Creates a Parser that tries to apply the given parser optionally. It returns the inner parser's
 * result if succesful, and otherwise indicates success at the starting offset with a `null` value.
 *
 * If the inner parser returns a fatal failure, the error is returned as-is.
 *
 * @public
 *
 * @param parser - Parser to attempt to apply
 */
export declare function optional<T>(parser: Parser<T>): Parser<T | null>;

/**
 * Creates a Parser that applies each of the given parsers in turn until one matches, then returns
 * that parser's result. If no parser matches, an error is returned reflecting the furthest offset
 * reached in the input string. If any parser returns a fatal error, no further branches are tried.
 *
 * @public
 *
 * @param parsers  - Parsers to attempt to apply
 * @param expected - Overrides the expected value used if none of the inner parsers match
 */
export declare function or<T>(parsers: Parser<T>[], expected?: string[]): Parser<T>;

/**
 * A parser is a function that tries to match whatever it expects at the given offset in the input
 * string. Returns a ParseResult.
 *
 * @public
 */
export declare type Parser<T> = (input: string, offset: number) => ParseResult<T>;

/**
 * The result of parsing - either success (with an offset at which to resume parsing the next thing)
 * or failure. If a failure is fatal, parsing should not continue to try alternative options.
 *
 * A ParseResult may contain a value that represents the parsed input.
 *
 * @public
 */
export declare type ParseResult<T> = {
    success: true;
    offset: number;
    value: T;
} | {
    success: false;
    offset: number;
    expected: string[];
    fatal: boolean;
};

/**
 * Creates a Parser that applies the given parser without consuming any input. That is, if the inner
 * parser is successful, success is returned (with the resulting value) at the starting offset,
 * effectively making the parser consume no input.
 *
 * Errors returned by the inner parser are returned as-is.
 *
 * @public
 *
 * @param parser - The parser to apply, value is discarded and any progress made in input is reset.
 */
export declare function peek<T>(parser: Parser<T>): Parser<T>;

/**
 * Creates a Parser that tries to apply the given parser one or more times in sequence. Values for
 * successful matches are collected in an array. Once the inner parser no longer matches, success is
 * returned at the offset reached with the accumulated values. The parser is required to match at
 * least once, so an initial failure is returned as-is.
 *
 * If the inner parser returns a fatal failure, the error is returned as-is.
 *
 * @public
 *
 * @param parser - The parser to apply repeatedly
 */
export declare function plus<T>(parser: Parser<T>): Parser<T[]>;

/**
 * Creates a Parser that tries to apply the given parser one or more times in sequence. Values for
 * successful matches are discarded. Once the inner parser no longer matches, success is returned at
 * the offset reached. The parser is required to match at least once, so an initial failure is
 * returned as-is.
 *
 * If the inner parser returns a fatal failure, the error is returned as-is.
 *
 * @public
 *
 * @param parser - The parser to apply repeatedly
 */
export declare function plusConsumed<T>(parser: Parser<T>): Parser<void>;

/**
 * Creates a Parser that applies the given two parsers in sequence, returning the result of the
 * second if the first succeeds.
 *
 * Equivalent to `then(before, parser, second)`.
 *
 * @public
 *
 * @param before - First parser to apply, value is discarded
 * @param parser - Second parser to apply, value is kept
 */
export declare function preceded<TBefore, T>(before: Parser<TBefore>, parser: Parser<T>): Parser<T>;

/**
 * Creates a Parser that matches a single character from a range of codepoints.
 *
 * Use `recognize` if you need the character that was matched.
 *
 * @public
 *
 * @param firstCodePoint - The first code point to accept
 * @param lastCodePoint  - The last code point to accept (inclusive)
 */
export declare function range(firstCodePoint: number, lastCodePoint: number, expected?: string[]): Parser<void>;

/**
 * Creates a Parser that applies the given parser. If successful, the inner parser's value is
 * discarded and the substring that was consumed from the input is returned as value instead. Errors
 * are returned as-is.
 *
 * When using this in combination with `star` or `plus`, consider using `starConsumed` or
 * `plusConsumed` instead for efficiency.
 *
 * @public
 *
 * @param parser - The parser to apply, value is discarded and replaced by the consumed input.
 */
export declare function recognize<T>(parser: Parser<T>): Parser<string>;

/**
 * Returns the second of the given two arguments. Useful as a `join` function for `then`. See also
 * `preceded`.
 *
 * @public
 *
 * @param x - Argument to ignore
 * @param y - Argument to return
 */
export declare function second<T1, T2>(x: T1, y: T2): T2;

/**
 * Creates a parser that applies the given parsers in sequence, returning a tuple of the
 * corresponding values if all of them accept.
 *
 * This can be slightly less efficient than nesting `then` and its variations, but may be a lot more
 * readable. If you don't care about any of the values produced, consider using `sequenceConsumed`
 * instead.
 *
 * @public
 *
 * @param parsers - Parsers to apply one after the other
 */
export declare function sequence<Ts extends unknown[]>(...parsers: {
    [key in keyof Ts]: Parser<Ts[key]>;
}): Parser<Ts>;

/**
 * Creates a parser that applies the given parsers in sequence, discarding all of the values
 * produced.
 *
 * @public
 *
 * @param parsers - Parsers to apply one after the other
 */
export declare function sequenceConsumed(...parsers: Parser<unknown>[]): Parser<void>;

/**
 * Creates a Parser that skips the given number of characters.
 *
 * This counts in unicode characters (code points), not UTF-16 code units.
 *
 * @public
 *
 * @param nCodepoints - number of characters to skip
 */
export declare function skipChars(nCodepoints: number): Parser<void>;

/**
 * Creates a Parser that tries to apply the given parser zero or more times in sequence. Values for
 * successful matches are collected in an array. Once the inner parser no longer matches, success is
 * returned at the offset reached with the accumulated values.
 *
 * If the inner parser returns a fatal failure, the error is returned as-is.
 *
 * @public
 *
 * @param parser - Parser to apply repeatedly
 */
export declare function star<T>(parser: Parser<T>): Parser<T[]>;

/**
 * Creates a Parser that tries to apply the given parser zero or more times in sequence. Values for
 * successful matches are discarded. Once the inner parser no longer matches, success is returned at
 * the offset reached.
 *
 * If the inner parser returns a fatal failure, the error is returned as-is.
 *
 * @public
 *
 * @param parser - Parser to apply repeatedly
 */
export declare function starConsumed<T>(parser: Parser<T>): Parser<void>;

/**
 * A parser that only succeeds at the start of the input string.
 *
 * @public
 *
 * @param input  - The input to match in
 * @param offset - The offset in `input` at which to start matching
 */
export declare const start: Parser<void>;

/**
 * Creates a StreamingParser which applies the given Parser and yields the value produced if it
 * matches.
 *
 * @public
 *
 * @param parser - The Parser to apply
 */
export declare function streaming<T>(parser: Parser<T>): StreamingParser<T>;

/**
 * Creates a StreamingParser that applies the given parser and directly yields values produced by
 * it, and then only succeeds if parsing concludes at the end of the input string.
 *
 * @public
 *
 * @param parser - StreamingParser to apply
 */
export declare function streamingComplete<T>(parser: StreamingParser<T>): StreamingParser<T>;

/**
 * Creates a StreamingParser which discards undefined values yielded by the given StreamingParser.
 *
 * @public
 *
 * @param parser - The StreamingParser to filter
 */
export declare function streamingFilterUndefined<T>(parser: StreamingParser<T | void>): StreamingParser<T>;

/**
 * Creates a StreamingParser that tries to apply the given parser optionally. It only yields the
 * values produced by the inner parser if it matches successfully, and does not yield anything
 * otherwise.
 *
 * @public
 *
 * @param parser - StreamingParser to attempt to apply
 */
export declare function streamingOptional<T>(parser: StreamingParser<T>): StreamingParser<T>;

/**
 * A StreamingParser is similar to a Parser, but instead of returning a value when parsing is
 * complete it can parse incrementally and yield values as they are produced. The generator returns
 * a ParseResult when iteration is done which indicates whether parsing was successful.
 *
 * @public
 */
export declare type StreamingParser<T> = (input: string, offset: number) => Generator<T, ParseResult<unknown>>;

/**
 * Creates a StreamingParser that tries to apply the given StreamingParser zero or more times in
 * sequence. Values produced during each iteration are only yielded whenever the inner parser
 * matches successfully.
 *
 * @public
 *
 * @param parser - StreamingParser to apply repeatedly
 */
export declare function streamingStar<T>(parser: StreamingParser<T>): StreamingParser<T>;

/**
 * Creates a StreamingParser which applies the given two StreamingParsers in sequence.
 *
 * Unlike `then`, this does not combine values using a function, but instead simply yields the
 * values produced by both parsers as they produce them.
 *
 * @public
 *
 * @param parser1 - First StreamingParser to apply
 * @param parser2 - StreamingParser to apply if the first one is successful
 */
export declare function streamingThen<T, U>(parser1: StreamingParser<T>, parser2: StreamingParser<U>): StreamingParser<T | U>;

/**
 * Creates a Parser that applies the given two parsers in sequence, returning success only if both
 * succeed. The given join function is used to combine the values from both parsers into the single
 * value to return. If either parser fails, the failure is returned as-is.
 *
 * @public
 *
 * @param parser1 - First parser to apply
 * @param parser2 - Parser to apply after the first one is successful
 * @param join    - Function used to combine the values of both parsers
 */
export declare function then<T1, T2, T>(parser1: Parser<T1>, parser2: Parser<T2>, join: (value1: T1, value2: T2) => T): Parser<T>;

/**
 * Creates a Parser that matches the given string.
 *
 * @public
 *
 * @param token - The expected string
 */
export declare function token(token: string): Parser<string>;

export { }
