import P = require('parsimmon'); import { Parser, Mark, Result, Index, Reply, Language, TypedLanguage } from "parsimmon"; // -- -- -- -- -- -- -- -- -- -- -- -- -- class Foo { bar: Bar; } class Bar { foo: Foo; } // -- -- -- -- -- -- -- -- -- -- -- -- -- let str: string = null!; let strArr: string[]; let bool: boolean; let num: number = null!; let index: Index; let foo: Foo = null!; declare const bar: Bar; // -- -- -- -- -- -- -- -- -- -- -- -- -- let strPar: Parser; let numPar: Parser = null!; let voidPar: Parser; let anyPar: Parser; let nullPar: Parser; let emptyStrPar: Parser<''>; let indexPar: Parser; let fooPar: Parser = null!; let barPar: Parser = null!; let fooOrBarPar: Parser; // -- -- -- -- -- -- -- -- -- -- -- -- -- let strArrPar: Parser; let fooArrPar: Parser; // -- -- -- -- -- -- -- -- -- -- -- -- -- let fooMarkPar: Parser> = null!; const result = fooMarkPar.parse(str); if (result.status) { index = result.value.start; index = result.value.end; foo = result.value.value; } // -- -- -- -- -- -- -- -- -- -- -- -- -- let fooResult: Result = fooPar.parse(""); // https://github.com/Microsoft/TypeScript/issues/12882 if (fooResult.status === true) { foo = fooResult.value; } else { strArr = fooResult.expected; index = fooResult.index; } // -- -- -- -- -- -- -- -- -- -- -- -- -- let fooReply: Reply; fooReply = P.makeSuccess(0, foo); fooReply = P.makeFailure(0, ''); fooReply = P.makeFailure(0, ['', '']); fooPar = P((input: string, i: number) => P.makeSuccess(0, foo)); fooPar = P.Parser((input: string, i: number) => P.makeSuccess(0, foo)); // -- -- -- -- -- -- -- -- -- -- -- -- -- fooResult = fooPar.parse(str); foo = fooPar.tryParse(str); fooPar = fooPar.or(fooPar); fooOrBarPar = fooPar.or(barPar); barPar = fooPar.chain((f) => { foo = f; return barPar; }); barPar = fooPar.then((f) => { foo = f; return barPar; }); barPar = fooPar.then(barPar); barPar = fooPar.map((f) => { foo = f; return bar; }); strPar = P.string(str); strPar = strPar.contramap((f) => { f; // $ExpectType string return f.toUpperCase(); }); barPar = strPar.promap((f) => { f; // $ExpectType string return 3; }, (f) => { f; // $ExpectType number return bar; }); // -- -- -- -- -- -- -- -- -- -- -- -- -- fooPar = fooPar.skip(barPar); fooPar = fooPar.wrap(barPar, strPar); barPar = barPar = fooPar.result(bar); fooOrBarPar = fooPar.fallback(bar); // -- -- -- -- -- -- -- -- -- -- -- -- -- fooArrPar = fooPar.many(); fooArrPar = fooPar.times(num); fooArrPar = fooPar.times(num, num); fooArrPar = fooPar.atMost(num); fooArrPar = fooPar.atLeast(num); fooMarkPar = fooPar.mark(); fooPar = fooPar.desc(str); fooPar = fooPar.desc([str, str]); // -- -- -- -- -- -- -- -- -- -- -- -- -- strPar = P.string(str); strPar = P.regex(/rgx/); fooPar = P.succeed(foo); fooArrPar = P.seq(fooPar, fooPar); const par: Parser<[Bar, Foo, number]> = P.seq(barPar, fooPar, numPar); const par2: Parser = P.seq(barPar, fooPar, numPar).map(([a, b, c]: [Bar, Foo, number]) => 42); interface SeqObj { first: number; second: string; third: Foo; } const seqObjPar: Parser = P.seqObj( ['first', numPar], barPar, fooArrPar, ['third', fooPar], ['second', strPar]); fooPar = P.custom((success, failure) => (stream, i) => { str = stream; num = i; return success(num, foo); }); fooPar = P.custom((success, failure) => (stream, i) => failure(num, str)); fooPar = P.alt(fooPar, fooPar); anyPar = P.alt(barPar, fooPar, numPar); fooPar = P.lazy(() => { return fooPar; }); voidPar = P.fail(str); fooPar = P.fail(str); fooPar = P.empty(); // $ExpectType Parser // -- -- -- -- -- -- -- -- -- -- -- -- -- const bytePar: Parser = P.byte(3); const byteParMany: Parser = P.bitSeq([1, 2, 5, 1]); interface ByteSeqObj { first: number; second: number; third: number; } const byteParObj: Parser = P.bitSeqObj([ ['first', 3], 6, ['second', 8], 7, ['third', 9], ]); const byteParObjErr: Parser = P.bitSeqObj([ // $ExpectError ['first', 3], 6, ['second', 8], 7, /* missing 'third' key */ ]); // -- -- -- -- -- -- -- -- -- -- -- -- -- strPar = P.letter; strPar = P.letters; strPar = P.digit; strPar = P.digits; strPar = P.whitespace; strPar = P.optWhitespace; strPar = P.cr; strPar = P.lf; strPar = P.crlf; strPar = P.newline; const voidOrStrPar: Parser = P.end; strPar = P.any; strPar = P.all; voidPar = P.eof; indexPar = P.index; // -- -- -- -- -- -- -- -- -- -- -- -- -- bool = P.isParser(numPar); bool = P.isParser(null); bool = P.isParser(42); strPar = P.oneOf('a'); strPar = P.noneOf('a'); strPar = P.range('a', 'z'); strPar = P.regex(/foo/); strPar = P.regex(/foo/, 3); strPar = P.regexp(/bar/); strPar = P.regexp(/bar/, 3); nullPar = P.notFollowedBy(fooPar); emptyStrPar = P.lookahead(str); emptyStrPar = P.lookahead(/foo/); emptyStrPar = P.lookahead(fooPar); strPar = strPar.tie(); strPar = strPar.tieWith(""); fooPar = P.of(foo); str = P.formatError('foo', strPar.parse('bar')); strPar = P.seqMap(P.digit, (a: string) => 'foo'); numPar = P.seqMap(P.digit, P.digits, (a: string, b: string) => 42); strPar = P.seqMap(P.digit, P.digits, P.letter, (a: string, b: string, c: string) => 'foo'); strPar = P.seqMap(P.digit, P.digits, P.letter, P.letters.map(Number), (a: string, b: string, c: string, d: number) => 'foo'); strArrPar = P.sepBy(P.string('foo'), P.string('bar')); strArrPar = P.sepBy1(P.string('foo'), P.string('bar')); strPar = P.test((a: string) => false); strPar = P.takeWhile((a: string) => true); // Slightly modified from the documentation example for 'parser.thru(wrapper)'. function makeNode(name: Name) { return (parser: P.Parser): P.Parser> => { return P.seqMap( P.index, parser, P.index, (start, value, end) => { return { name, start, value, end, }; }, ); }; } let node: P.Parser> = P.letters.node('identifier'); node = P.letters.thru(makeNode('identifier')); // -- -- -- -- -- -- -- -- -- -- -- -- -- // Fantasy Land support fooPar = fooPar.empty(); // $ExpectType Parser // example taken from the documentation for the #ap method numPar = P.digit .ap(P.digit .map(s => (t: string) => Number(s) + Number(t))); fooArrPar = fooPar.sepBy(barPar); fooArrPar = fooPar.sepBy1(barPar); fooPar = barPar.of(foo); // -- -- -- -- -- -- -- -- -- -- -- -- -- let language: Language; language = P.createLanguage({ SomeRule: r => P.alt(P.string(""), r.AnotherRule), AnotherRule: () => P.string(""), }); // $ExpectType Parser language.SomeRule; // $ExpectType Parser language.AnotherRule; // $ExpectType Parser language.UndefinedRule; interface MyLanguageSpec { FooRule: Foo; BarRule: Bar; StringRule: string; } let myLanguage: TypedLanguage; myLanguage = P.createLanguage({ FooRule: r => { fooPar = r.FooRule; barPar = r.BarRule; strPar = r.StringRule; return fooPar; }, BarRule: r => barPar, StringRule: () => strPar, }); // $ExpectType Parser myLanguage.FooRule; // $ExpectType Parser myLanguage.BarRule; // $ExpectType Parser myLanguage.StringRule; const noRules = P.createLanguage<{}>({}); // $ExpectError P.createLanguage<{MissingRule: string}>({}); P.createLanguage<{SomeRule: string}>({ SomeRule: r => strPar, AnotherRule: (r: any) => strPar // $ExpectError });