declare namespace spellu {
    type SourceFile = {
        fileName: string;
        path: string;
        text: string;
    };
    type Token = {
        type: string;
        file?: SourceFile;
        lineNo: number;
        columnNo: number;
        string: string;
        value?: string | Token[];
    };
}
declare namespace spellu {
    interface Failable {
        isFailure(): boolean;
    }
    interface Either<Left, Right> extends Failable {
        extract(): Left | Right;
        resolve<T>(left?: () => T, right?: () => T): T;
    }
    interface Maybe extends Failable {
    }
    interface Just extends Maybe {
    }
    interface Nothing extends Maybe {
    }
    interface Listable extends Failable {
    }
    interface List extends Listable {
    }
    interface Nil extends Listable {
    }
}
declare namespace spellu {
    type SourceStreamOption = {
        normalize?: boolean;
        inputLength?: number;
        inputOffset?: number;
        startingLineNo?: number;
        startingColumnNo?: number;
    };
    type Location = {
        lineNo: number;
        columnNo: number;
    };
    class SourceStream implements ParserSource {
        protected readonly _input: string;
        protected readonly inputLength: number;
        protected inputOffset: number;
        protected lineNo: number;
        protected columnNo: number;
        constructor(input: string, option?: SourceStreamOption);
        readonly input: string;
        protected normalizeSource(string: string): string;
        protected stripUtf8Bom(string: string): string;
        protected normalizeNewLine(string: string): string;
        protected addTrailNewLine(string: string): string;
        location(): Location;
        charCodeAt(offset?: number): number;
        substring(length: number): string;
        nowEol(): boolean;
        nowEos(): boolean;
        startsWith(pattern: string): boolean;
        test(pattern: string | RegExp): boolean;
        skip(pattern: string | RegExp): void;
        consume(pattern: string | RegExp): boolean;
        scan(type: string, pattern: string | RegExp, matchIndex?: number): Token | null;
        scanBlock(type: string, openString: string, closeString: string, option?: {
            allowRecursive?: boolean;
            allowMultiline?: boolean;
            innerPattern?: string;
        }): Token | null;
        read<T>(pattern: string | RegExp, converter: (result: RegExpExecArray) => T, defaultValue: T): T;
        match<T>(pattern: string | RegExp, converter: (result: RegExpExecArray) => T, defaultValue: T, option?: {
            locationUpdate?: boolean;
        }): T;
        protected regexp(stringOrPattern: string | RegExp): RegExp;
        protected matchBlock(openString: string, closeString: string, innerPattern: string): number;
        protected matchBlockRecursive(openString: string, closeString: string, innerPattern: string): number;
        protected escapeForReadAhead(string: string): string;
        token(type: string, location?: Location, string?: string, value?: string): Token;
        protected updateLocation(string: string): void;
    }
}
declare namespace spellu {
    class Tokenizer {
        readonly source: SourceStream;
        protected token: Token;
        constructor(source: Token | SourceStream);
        available(): boolean;
        setToken(token: Token): void;
        chain(): Chain;
        skip(pattern: RegExp): Chain;
        consume(pattern: RegExp): Chain;
        scan(type: string, pattern: string | RegExp, matchIndex?: number, innerTokenizer?: (source: SourceStream) => any): Chain;
        scanBlock(type: string, openPattern: string, closePattern: string, option?: {}, innerTokenizer?: (source: SourceStream) => any): Chain;
        expect(message: string): void;
        error(code: string, message: string): never;
        fail(): void;
        fatal(message: string): void;
        result(): Token;
    }
    class Chain {
        protected tokenizer: Tokenizer;
        protected source: SourceStream;
        protected result?: boolean;
        constructor(tokenizer: Tokenizer);
        call(closure: (chain: this) => void): this;
        skip(pattern: RegExp): this;
        consume(pattern: RegExp): this;
        scan(type: string, pattern: string | RegExp, matchIndex?: number, innerTokenizer?: (source: SourceStream) => any): this;
        scanBlock(type: string, openPattern: string, closePattern: string, option?: {}, innerTokenizer?: (source: SourceStream) => any): this;
        expect(message: string): this;
        error(): void;
        fail(message?: string): void;
        fatal(message?: string): void;
        ok(): boolean;
        ng(): boolean;
    }
}
declare namespace spellu {
    interface ParserInputString {
        nowEos(): boolean;
        location(): Location;
        scan(pattern: string): string | null;
        scan(pattern: RegExp, matchIndex?: number): string | null;
    }
    interface ParserInputToken {
        nowEos(): boolean;
        location(): Location;
        scan(type: string, pattern: string): Token | null;
        scan(type: string, pattern: RegExp, matchIndex?: number): Token | null;
        nextTokenIf(type: string): Token | null;
    }
    interface ParserSource {
        nowEos(): boolean;
        location(): Location;
        skip(pattern: RegExp): void;
        consume(pattern: RegExp): boolean;
        scan(type: string, pattern: string | RegExp, matchIndex?: number): Token | null;
    }
    interface Diagnostic {
        message: string;
        lineNo?: number;
        columnNo?: number;
    }
    type ParserResult<V> = ParserSuccess<V> | ParserFailure;
    type ParserSuccess<V> = Success<ParserSource, V>;
    type ParserFailure = Failure<ParserSource, Diagnostic>;
    interface ParsedValue<C, S, F> extends Either<F, S> {
        _: C;
        isSuccess(): boolean;
        isFailure(): boolean;
        success(callback: (value: S) => void): ParsedValue<C, S, F>;
        failure(callback: (diagnostics: F) => void): ParsedValue<C, S, F>;
        extract(): S | F;
        resolve<T>(left?: (diagnostics: F) => T, right?: (value: S) => T): T | null;
    }
    class Success<C, V> implements ParsedValue<C, V, never> {
        _: C;
        value: V;
        constructor(_: C, value: V);
        isSuccess(): boolean;
        isFailure(): boolean;
        success(callback: (value: V) => void): this;
        failure(callback: (diagnostics: never) => void): this;
        extract(): V;
        resolve<T>(left?: (diagnostics: never) => T, right?: (value: V) => T): T | null;
    }
    class Failure<C, D> implements ParsedValue<C, never, D[]> {
        _: C;
        diagnostics: D[];
        constructor(_: C, diagnostics?: D[]);
        isSuccess(): boolean;
        isFailure(): boolean;
        success(callback: (value: never) => void): this;
        failure(callback: (diagnostics: D[]) => void): this;
        extract(): D[];
        resolve<T>(left?: (diagnostics: D[]) => T, right?: (value: never) => T): T | null;
    }
    interface Parser<V> {
        (_: ParserSource): ParserResult<V>;
        many0: () => Parser<V[]>;
        many1: () => Parser<V[]>;
        optional: () => Parser<V | null>;
        or: <W>(parser: Parser<W>) => Parser<V | W>;
        times: (count: number) => Parser<V[]>;
        timesMany: (min: number) => Parser<V[]>;
        timesBetween: (min: number, max: number) => Parser<V[]>;
        expect(callback: (value: V) => boolean, message: string): Parser<V>;
        reduce<T>(callback: (value: V) => T): Parser<T>;
        inspect(callback: (result: ParserResult<V>) => void): Parser<V>;
    }
    interface Combinator<V> {
        (...args: any[]): Parser<V>;
    }
    function createParser<V>(evaluator: (_: ParserSource) => ParserResult<V>): Parser<V>;
    function success<V>(_: ParserSource, value: V): ParserSuccess<V>;
    function failure<V>(_: ParserSource, diagnostic: Diagnostic): ParserFailure;
    function failure<V>(_: ParserSource, diagnostics: Diagnostic[]): ParserFailure;
    function and<V>(): Parser<[never]>;
    function and<V1>(p1: Parser<V1>): Parser<[V1]>;
    function and<V1, V2>(p1: Parser<V1>, p2: Parser<V2>): Parser<[V1, V2]>;
    function and<V1, V2, V3>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>): Parser<[V1, V2, V3]>;
    function and<V1, V2, V3, V4>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>): Parser<[V1, V2, V3, V4]>;
    function and<V1, V2, V3, V4, V5>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>): Parser<[V1, V2, V3, V4, V5]>;
    function and<V1, V2, V3, V4, V5, V6>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>): Parser<[V1, V2, V3, V4, V5, V6]>;
    function and<V1, V2, V3, V4, V5, V6, V7>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>): Parser<[V1, V2, V3, V4, V5, V6, V7]>;
    function and<V1, V2, V3, V4, V5, V6, V7, V8>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>): Parser<[V1, V2, V3, V4, V5, V6, V7, V8]>;
    function and<V1, V2, V3, V4, V5, V6, V7, V8, V9>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>, p9: Parser<V9>): Parser<[V1, V2, V3, V4, V5, V6, V7, V8, V9]>;
    function and(...parsers: Parser<any>[]): Parser<any[]>;
    function or<V>(): Parser<[never]>;
    function or<V1>(p1: Parser<V1>): Parser<V1 | null>;
    function or<V1, V2>(p1: Parser<V1>, p2: Parser<V2>): Parser<V1 | V2 | null>;
    function or<V1, V2, V3>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>): Parser<V1 | V2 | V3 | null>;
    function or<V1, V2, V3, V4>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>): Parser<V1 | V2 | V3 | V4 | null>;
    function or<V1, V2, V3, V4, V5>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>): Parser<V1 | V2 | V3 | V4 | V5 | null>;
    function or<V1, V2, V3, V4, V5, V6>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>): Parser<V1 | V2 | V3 | V4 | V5 | V6 | null>;
    function or<V1, V2, V3, V4, V5, V6, V7>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>): Parser<V1 | V2 | V3 | V4 | V5 | V6 | V7 | null>;
    function or<V1, V2, V3, V4, V5, V6, V7, V8>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>): Parser<V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | null>;
    function or<V1, V2, V3, V4, V5, V6, V7, V8, V9>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>, p9: Parser<V9>): Parser<V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | null>;
    function or<V>(...parsers: Parser<V>[]): Parser<V>;
    function option<V>(parser: Parser<V>): Parser<V | null>;
    function many<V>(parser: Parser<V>, min: number, max?: number): Parser<V[]>;
    function $$<V1>(p1: Parser<V1>): Parser<[V1]>;
    function $$<V1, V2>(p1: Parser<V1>, p2: Parser<V2>): Parser<[V1, V2]>;
    function $$<V1, V2, V3>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>): Parser<[V1, V2, V3]>;
    function $$<V1, V2, V3, V4>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>): Parser<[V1, V2, V3, V4]>;
    function $$<V1, V2, V3, V4, V5>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>): Parser<[V1, V2, V3, V4, V5]>;
    function $$<V1, V2, V3, V4, V5, V6>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>): Parser<[V1, V2, V3, V4, V5, V6]>;
    function $$<V1, V2, V3, V4, V5, V6, V7>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>): Parser<[V1, V2, V3, V4, V5, V6, V7]>;
    function $$<V1, V2, V3, V4, V5, V6, V7, V8>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>): Parser<[V1, V2, V3, V4, V5, V6, V7, V8]>;
    function $$<V1, V2, V3, V4, V5, V6, V7, V8, V9>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>, p9: Parser<V9>): Parser<[V1, V2, V3, V4, V5, V6, V7, V8, V9]>;
    function $$(...parsers: (string | Parser<any>)[]): Parser<any>;
    function $0<V1>(p1: Parser<V1>): Parser<V1[]>;
    function $0<V1, V2>(p1: Parser<V1>, p2: Parser<V2>): Parser<[V1, V2][]>;
    function $0<V1, V2, V3>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>): Parser<[V1, V2, V3][]>;
    function $0<V1, V2, V3, V4>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>): Parser<[V1, V2, V3, V4][]>;
    function $0<V1, V2, V3, V4, V5>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>): Parser<[V1, V2, V3, V4, V5][]>;
    function $0<V1, V2, V3, V4, V5, V6>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>): Parser<[V1, V2, V3, V4, V5, V6][]>;
    function $0<V1, V2, V3, V4, V5, V6, V7>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>): Parser<[V1, V2, V3, V4, V5, V6, V7][]>;
    function $0<V1, V2, V3, V4, V5, V6, V7, V8>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>): Parser<[V1, V2, V3, V4, V5, V6, V7, V8][]>;
    function $0<V1, V2, V3, V4, V5, V6, V7, V8, V9>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>, p9: Parser<V9>): Parser<[V1, V2, V3, V4, V5, V6, V7, V8, V9][]>;
    function $0(parser: Parser<any>, ...parsers: (string | Parser<any>)[]): Parser<any[][]>;
    function $1<V1>(p1: Parser<V1>): Parser<V1[]>;
    function $1<V1, V2>(p1: Parser<V1>, p2: Parser<V2>): Parser<[V1, V2][]>;
    function $1<V1, V2, V3>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>): Parser<[V1, V2, V3][]>;
    function $1<V1, V2, V3, V4>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>): Parser<[V1, V2, V3, V4][]>;
    function $1<V1, V2, V3, V4, V5>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>): Parser<[V1, V2, V3, V4, V5][]>;
    function $1<V1, V2, V3, V4, V5, V6>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>): Parser<[V1, V2, V3, V4, V5, V6][]>;
    function $1<V1, V2, V3, V4, V5, V6, V7>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>): Parser<[V1, V2, V3, V4, V5, V6, V7][]>;
    function $1<V1, V2, V3, V4, V5, V6, V7, V8>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>): Parser<[V1, V2, V3, V4, V5, V6, V7, V8][]>;
    function $1<V1, V2, V3, V4, V5, V6, V7, V8, V9>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>, p9: Parser<V9>): Parser<[V1, V2, V3, V4, V5, V6, V7, V8, V9][]>;
    function $1(parser: Parser<any>, ...parsers: (string | Parser<any>)[]): Parser<any[][]>;
    function $_<V1>(p1: Parser<V1>): Parser<V1 | null>;
    function $_<V1, V2>(p1: Parser<V1>, p2: Parser<V2>): Parser<[V1, V2] | null>;
    function $_<V1, V2, V3>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>): Parser<[V1, V2, V3] | null>;
    function $_<V1, V2, V3, V4>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>): Parser<[V1, V2, V3, V4] | null>;
    function $_<V1, V2, V3, V4, V5>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>): Parser<[V1, V2, V3, V4, V5] | null>;
    function $_<V1, V2, V3, V4, V5, V6>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>): Parser<[V1, V2, V3, V4, V5, V6] | null>;
    function $_<V1, V2, V3, V4, V5, V6, V7>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>): Parser<[V1, V2, V3, V4, V5, V6, V7] | null>;
    function $_<V1, V2, V3, V4, V5, V6, V7, V8>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>): Parser<[V1, V2, V3, V4, V5, V6, V7, V8] | null>;
    function $_<V1, V2, V3, V4, V5, V6, V7, V8, V9>(p1: Parser<V1>, p2: Parser<V2>, p3: Parser<V3>, p4: Parser<V4>, p5: Parser<V5>, p6: Parser<V6>, p7: Parser<V7>, p8: Parser<V8>, p9: Parser<V9>): Parser<[V1, V2, V3, V4, V5, V6, V7, V8, V9] | null>;
    function $_(parser: Parser<any>, ...parsers: (string | Parser<any>)[]): Parser<any[] | null>;
    function delay<V>(combinator: Combinator<V>, ...args: any[]): Parser<V>;
    function always<T>(value?: T): Parser<T>;
    function never<T>(message?: string): Parser<T>;
    function parse<V>(parser: Parser<V>, input: string): ParserResult<V>;
}
declare namespace spellu {
    function p<V>(def: (source: ParserSource) => V | Diagnostic | Diagnostic[]): Parser<V>;
    const string: {
        eos: () => Parser<string>;
        string: (string: string) => Parser<string>;
        regex: (pattern: RegExp) => Parser<string>;
    };
}
declare namespace spellu {
    const token: {
        eos: (type: string) => Parser<Token>;
        string: (type: string, string?: string) => Parser<Token>;
        regex: (type: string, pattern: RegExp, matchIndex?: number) => Parser<Token>;
    };
}

export = spellu;
