UNPKG

prsc

Version:

Tiny parser combinators library

549 lines (503 loc) 19.9 kB
/** * 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 { }