Comparing version
@@ -15,2 +15,7 @@ # Changelog | ||
# 0.3.0 | ||
- **Breaking Change** | ||
- upgrade to latest `fp-ts` (0.5.1) (@gcanti) | ||
# 0.2.1 | ||
@@ -17,0 +22,0 @@ |
@@ -22,12 +22,7 @@ import { Monoid } from 'fp-ts/lib/Monoid'; | ||
export declare class Parser<A> implements FantasyMonad<URI, A>, FantasyAlternative<URI, A> { | ||
readonly value: (s: string) => ParseResult<A>; | ||
static of: typeof of; | ||
static zero: typeof zero; | ||
readonly run: (s: string) => ParseResult<A>; | ||
readonly _A: A; | ||
readonly _URI: URI; | ||
constructor(value: (s: string) => ParseResult<A>); | ||
/** Run a parser against an input, either getting an error or a value */ | ||
run(s: string): ParseResult<A>; | ||
constructor(run: (s: string) => ParseResult<A>); | ||
map<B>(f: (a: A) => B): Parser<B>; | ||
of<B>(b: B): Parser<B>; | ||
ap<B>(fab: Parser<(a: A) => B>): Parser<B>; | ||
@@ -38,18 +33,18 @@ chain<B>(f: (a: A) => Parser<B>): Parser<B>; | ||
} | ||
export declare function map<A, B>(f: (a: A) => B, fa: Parser<A>): Parser<B>; | ||
export declare function of<A>(a: A): Parser<A>; | ||
export declare function ap<A, B>(fab: Parser<(a: A) => B>, fa: Parser<A>): Parser<B>; | ||
export declare function chain<A, B>(f: (a: A) => Parser<B>, fa: Parser<A>): Parser<B>; | ||
export declare function alt<A>(fx: Parser<A>, fy: Parser<A>): Parser<A>; | ||
export declare function zero<A>(): Parser<A>; | ||
export declare const map: <A, B>(f: (a: A) => B, fa: Parser<A>) => Parser<B>; | ||
export declare const of: <A>(a: A) => Parser<A>; | ||
export declare const ap: <A, B>(fab: Parser<(a: A) => B>, fa: Parser<A>) => Parser<B>; | ||
export declare const chain: <A, B>(f: (a: A) => Parser<B>, fa: Parser<A>) => Parser<B>; | ||
export declare const alt: <A>(fx: Parser<A>) => (fy: Parser<A>) => Parser<A>; | ||
export declare const zero: <A>() => Parser<A>; | ||
export declare const emptyString: Parser<string>; | ||
export declare function empty(): Parser<string>; | ||
export declare function concat(x: Parser<string>, y: Parser<string>): Parser<string>; | ||
export declare function createParseFailure<A>(remaining: string, message: string): ParseResult<A>; | ||
export declare function createParseSuccess<A>(a: A, s: string): ParseResult<A>; | ||
export declare function consumed<A>(result: ParseResult<A>): Either<ParseFailure, A>; | ||
export declare function remaining<A>(result: ParseResult<A>): string; | ||
export declare function getAndNext(s: string): Option<[string, string]>; | ||
export declare const empty: () => Parser<string>; | ||
export declare const concat: (x: Parser<string>) => (y: Parser<string>) => Parser<string>; | ||
export declare const createParseFailure: <A>(remaining: string, message: string) => Either<ParseFailure, [A, string]>; | ||
export declare const createParseSuccess: <A>(a: A, s: string) => Either<ParseFailure, [A, string]>; | ||
export declare const consumed: <A>(result: Either<ParseFailure, [A, string]>) => Either<ParseFailure, A>; | ||
export declare const remaining: <A>(result: Either<ParseFailure, [A, string]>) => string; | ||
export declare const getAndNext: (s: string) => Option<[string, string]>; | ||
/** Get the result of a parse, plus the unparsed input remainder */ | ||
export declare function unparser<A>(parser: Parser<A>, s: string): { | ||
export declare const unparser: <A>(parser: Parser<A>) => (s: string) => { | ||
consumed: Either<ParseFailure, A>; | ||
@@ -59,11 +54,13 @@ remaining: string; | ||
/** Returns a parser which will fail immediately with the provided message */ | ||
export declare function failWith<A>(message: string): Parser<A>; | ||
export declare const failWith: <A>(message: string) => Parser<A>; | ||
/** The `fail` parser will just fail immediately without consuming any input */ | ||
export declare const fail: Parser<any>; | ||
/** A parser combinator which returns the provided parser unchanged, except | ||
export declare const fail: Parser<never>; | ||
/** | ||
* A parser combinator which returns the provided parser unchanged, except | ||
* that if it fails, the provided error message will be returned in the | ||
* `ParseFailure`. | ||
*/ | ||
export declare function expected<A>(parser: Parser<A>, message: string): Parser<A>; | ||
/** The `succeed` parser constructor creates a parser which will simply | ||
export declare const expected: <A>(parser: Parser<A>, message: string) => Parser<A>; | ||
/** | ||
* The `succeed` parser constructor creates a parser which will simply | ||
* return the value provided as its argument, without consuming any input. | ||
@@ -73,3 +70,3 @@ * | ||
*/ | ||
export declare const succeed: typeof of; | ||
export declare const succeed: <A>(a: A) => Parser<A>; | ||
/** The `item` parser consumes a single value, regardless of what it is, | ||
@@ -79,3 +76,4 @@ * and returns it as its result. | ||
export declare const item: Parser<string>; | ||
/** The `seq` combinator takes a parser, and a function which will receive | ||
/** | ||
* 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 | ||
@@ -88,4 +86,5 @@ * parser, which will be run immediately after the initial parser. In this | ||
*/ | ||
export declare const seq: typeof chain; | ||
/** The `either` combinator takes two parsers, runs the first on the input | ||
export declare const seq: <A, B>(f: (a: A) => Parser<B>, fa: Parser<A>) => Parser<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 | ||
@@ -96,4 +95,5 @@ * parser on the same input. Basically, try parser 1, then try parser 2. | ||
*/ | ||
export declare const either: typeof alt; | ||
/** The `sat` parser constructor takes a predicate function, and will consume | ||
export declare const either: <A>(fx: Parser<A>) => (fy: Parser<A>) => Parser<A>; | ||
/** | ||
* The `sat` parser constructor takes a predicate function, and will consume | ||
* a single character if calling that predicate function with the character | ||
@@ -103,10 +103,12 @@ * as its argument returns `true`. If it returns `false`, the parser will | ||
*/ | ||
export declare function sat(predicate: Predicate<string>): Parser<string>; | ||
/** The `maybe` parser combinator creates a parser which will run the provided | ||
export declare const sat: (predicate: Predicate<string>) => Parser<string>; | ||
/** | ||
* 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 string (as | ||
* a result, without consuming any input. | ||
*/ | ||
export declare function maybe(parser: Parser<string>): Parser<string>; | ||
export declare function fold(ps: Array<Parser<string>>): Parser<string>; | ||
/** The `many` combinator takes a parser, and returns a new parser which will | ||
export declare const maybe: (parser: Parser<string>) => Parser<string>; | ||
export declare const fold: (ps: Parser<string>[]) => Parser<string>; | ||
/** | ||
* 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 | ||
@@ -119,18 +121,23 @@ * a list of the result values of each parse operation as its result, or the | ||
*/ | ||
export declare function many<A>(parser: Parser<A>): Parser<Array<A>>; | ||
/** The `many1` combinator is just like the `many` combinator, except it | ||
export declare const many: <A>(parser: Parser<A>) => Parser<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. | ||
*/ | ||
export declare function many1<A>(parser: Parser<A>): Parser<NonEmptyArray<A>>; | ||
/** Matches the provided parser `p` zero or more times, but requires the | ||
export declare const many1: <A>(parser: Parser<A>) => Parser<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`. | ||
*/ | ||
export declare function sepBy<A, B>(sep: Parser<A>, parser: Parser<B>): Parser<Array<B>>; | ||
/** Matches the provided parser `p` one or more times, but requires the | ||
export declare const sepBy: <A, B>(sep: Parser<A>, parser: Parser<B>) => Parser<B[]>; | ||
/** Matches both parsers and return the value of the second */ | ||
export declare const second: <A>(pa: Parser<A>) => <B>(pb: Parser<B>) => Parser<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`. | ||
*/ | ||
export declare function sepBy1<A, B>(sep: Parser<A>, parser: Parser<B>): Parser<NonEmptyArray<B>>; | ||
export declare const sepBy1: <A, B>(sep: Parser<A>, parser: Parser<B>) => Parser<NonEmptyArray<B>>; | ||
export declare const parser: Monad<URI> & Alternative<URI> & Monoid<Parser<string>>; |
233
lib/index.js
@@ -5,2 +5,3 @@ "use strict"; | ||
var Either_1 = require("fp-ts/lib/Either"); | ||
var function_1 = require("fp-ts/lib/function"); | ||
var NonEmptyArray_1 = require("fp-ts/lib/NonEmptyArray"); | ||
@@ -10,10 +11,6 @@ var Option_1 = require("fp-ts/lib/Option"); | ||
exports.URI = 'Parser'; | ||
var Parser = (function () { | ||
function Parser(value) { | ||
this.value = value; | ||
var Parser = /** @class */ (function () { | ||
function Parser(run) { | ||
this.run = run; | ||
} | ||
/** Run a parser against an input, either getting an error or a value */ | ||
Parser.prototype.run = function (s) { | ||
return this.value(s); | ||
}; | ||
Parser.prototype.map = function (f) { | ||
@@ -26,5 +23,2 @@ var _this = this; | ||
}; | ||
Parser.prototype.of = function (b) { | ||
return of(b); | ||
}; | ||
Parser.prototype.ap = function (fab) { | ||
@@ -42,3 +36,3 @@ var _this = this; | ||
Parser.prototype.zero = function () { | ||
return zero(); | ||
return exports.zero(); | ||
}; | ||
@@ -52,78 +46,39 @@ Parser.prototype.alt = function (fa) { | ||
}; | ||
Parser.of = of; | ||
Parser.zero = zero; | ||
return Parser; | ||
}()); | ||
exports.Parser = Parser; | ||
function map(f, fa) { | ||
return fa.map(f); | ||
} | ||
exports.map = map; | ||
function of(a) { | ||
return new Parser(function (s) { return createParseSuccess(a, s); }); | ||
} | ||
exports.of = of; | ||
function ap(fab, fa) { | ||
return fa.ap(fab); | ||
} | ||
exports.ap = ap; | ||
function chain(f, fa) { | ||
return fa.chain(f); | ||
} | ||
exports.chain = chain; | ||
function alt(fx, fy) { | ||
return fx.alt(fy); | ||
} | ||
exports.alt = alt; | ||
function zero() { | ||
return exports.fail; | ||
} | ||
exports.zero = zero; | ||
exports.emptyString = of(''); | ||
function empty() { | ||
return exports.emptyString; | ||
} | ||
exports.empty = empty; | ||
function concat(x, y) { | ||
exports.map = function (f, fa) { return fa.map(f); }; | ||
exports.of = function (a) { return new Parser(function (s) { return exports.createParseSuccess(a, s); }); }; | ||
exports.ap = function (fab, fa) { return fa.ap(fab); }; | ||
exports.chain = function (f, fa) { return fa.chain(f); }; | ||
exports.alt = function (fx) { return function (fy) { return fx.alt(fy); }; }; | ||
exports.zero = function () { return exports.fail; }; | ||
exports.emptyString = exports.of(''); | ||
exports.empty = function () { return exports.emptyString; }; | ||
exports.concat = function (x) { return function (y) { | ||
return y.ap(x.map(function (a) { return function (b) { return a + b; }; })); | ||
} | ||
exports.concat = concat; | ||
}; }; | ||
// | ||
// helpers | ||
// | ||
function createParseFailure(remaining, message) { | ||
exports.createParseFailure = function (remaining, message) { | ||
return Either_1.left({ remaining: remaining, message: message }); | ||
} | ||
exports.createParseFailure = createParseFailure; | ||
function createParseSuccess(a, s) { | ||
return Either_1.right([a, s]); | ||
} | ||
exports.createParseSuccess = createParseSuccess; | ||
function consumed(result) { | ||
return result.map(function (_a) { | ||
var a = _a[0], _ = _a[1]; | ||
return a; | ||
}); | ||
} | ||
exports.consumed = consumed; | ||
function remaining(result) { | ||
return result.fold(function (pe) { return pe.remaining; }, function (_a) { | ||
var _ = _a[0], s = _a[1]; | ||
return s; | ||
}); | ||
} | ||
exports.remaining = remaining; | ||
function getAndNext(s) { | ||
if (s.length > 0) { | ||
return Option_1.some([s.substring(0, 1), s.substring(1)]); | ||
} | ||
return Option_1.none; | ||
} | ||
exports.getAndNext = getAndNext; | ||
}; | ||
exports.createParseSuccess = function (a, s) { return Either_1.right([a, s]); }; | ||
exports.consumed = function (result) { return result.map(function (_a) { | ||
var a = _a[0], _ = _a[1]; | ||
return a; | ||
}); }; | ||
exports.remaining = function (result) { return result.fold(function (pe) { return pe.remaining; }, function (_a) { | ||
var _ = _a[0], s = _a[1]; | ||
return s; | ||
}); }; | ||
exports.getAndNext = function (s) { | ||
return s.length > 0 ? Option_1.some(function_1.tuple(s.substring(0, 1), s.substring(1))) : Option_1.none; | ||
}; | ||
/** Get the result of a parse, plus the unparsed input remainder */ | ||
function unparser(parser, s) { | ||
exports.unparser = function (parser) { return function (s) { | ||
var e = parser.run(s); | ||
return { consumed: consumed(e), remaining: remaining(e) }; | ||
} | ||
exports.unparser = unparser; | ||
return { consumed: exports.consumed(e), remaining: exports.remaining(e) }; | ||
}; }; | ||
// | ||
@@ -133,13 +88,11 @@ // combinators | ||
/** Returns a parser which will fail immediately with the provided message */ | ||
function failWith(message) { | ||
return new Parser(function (s) { return createParseFailure(s, message); }); | ||
} | ||
exports.failWith = failWith; | ||
exports.failWith = function (message) { return new Parser(function (s) { return exports.createParseFailure(s, message); }); }; | ||
/** The `fail` parser will just fail immediately without consuming any input */ | ||
exports.fail = failWith('Parse failed on `fail`'); | ||
/** A parser combinator which returns the provided parser unchanged, except | ||
exports.fail = exports.failWith('Parse failed on `fail`'); | ||
/** | ||
* A parser combinator which returns the provided parser unchanged, except | ||
* that if it fails, the provided error message will be returned in the | ||
* `ParseFailure`. | ||
*/ | ||
function expected(parser, message) { | ||
exports.expected = function (parser, message) { | ||
return new Parser(function (s) { return parser.run(s).mapLeft(function (_a) { | ||
@@ -149,5 +102,5 @@ var remaining = _a.remaining; | ||
}); }); | ||
} | ||
exports.expected = expected; | ||
/** The `succeed` parser constructor creates a parser which will simply | ||
}; | ||
/** | ||
* The `succeed` parser constructor creates a parser which will simply | ||
* return the value provided as its argument, without consuming any input. | ||
@@ -157,3 +110,3 @@ * | ||
*/ | ||
exports.succeed = of; | ||
exports.succeed = exports.of; | ||
/** The `item` parser consumes a single value, regardless of what it is, | ||
@@ -163,8 +116,9 @@ * and returns it as its result. | ||
exports.item = new Parser(function (s) { | ||
return getAndNext(s).fold(function () { return createParseFailure(s, 'Parse failed on item'); }, function (_a) { | ||
return exports.getAndNext(s).fold(function () { return exports.createParseFailure(s, 'Parse failed on item'); }, function (_a) { | ||
var c = _a[0], s = _a[1]; | ||
return createParseSuccess(c, s); | ||
return exports.createParseSuccess(c, s); | ||
}); | ||
}); | ||
/** The `seq` combinator takes a parser, and a function which will receive | ||
/** | ||
* 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 | ||
@@ -177,4 +131,5 @@ * parser, which will be run immediately after the initial parser. In this | ||
*/ | ||
exports.seq = chain; | ||
/** The `either` combinator takes two parsers, runs the first on the input | ||
exports.seq = exports.chain; | ||
/** | ||
* The `either` combinator takes two parsers, runs the first on the input | ||
* stream, and if that fails, it will backtrack and attempt the second | ||
@@ -185,4 +140,5 @@ * parser on the same input. Basically, try parser 1, then try parser 2. | ||
*/ | ||
exports.either = alt; | ||
/** The `sat` parser constructor takes a predicate function, and will consume | ||
exports.either = exports.alt; | ||
/** | ||
* The `sat` parser constructor takes a predicate function, and will consume | ||
* a single character if calling that predicate function with the character | ||
@@ -192,26 +148,21 @@ * as its argument returns `true`. If it returns `false`, the parser will | ||
*/ | ||
function sat(predicate) { | ||
exports.sat = function (predicate) { | ||
return new Parser(function (s) { | ||
return getAndNext(s) | ||
return exports.getAndNext(s) | ||
.chain(function (x) { return (predicate(x[0]) ? Option_1.some(x) : Option_1.none); }) | ||
.fold(function () { return createParseFailure(s, 'Parse failed on sat'); }, function (_a) { | ||
.fold(function () { return exports.createParseFailure(s, 'Parse failed on sat'); }, function (_a) { | ||
var c = _a[0], s = _a[1]; | ||
return createParseSuccess(c, s); | ||
return exports.createParseSuccess(c, s); | ||
}); | ||
}); | ||
} | ||
exports.sat = sat; | ||
/** The `maybe` parser combinator creates a parser which will run the provided | ||
}; | ||
/** | ||
* 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 string (as | ||
* a result, without consuming any input. | ||
*/ | ||
function maybe(parser) { | ||
return parser.alt(empty()); | ||
} | ||
exports.maybe = maybe; | ||
function fold(ps) { | ||
return Monoid_1.fold({ empty: empty, concat: concat }, ps); | ||
} | ||
exports.fold = fold; | ||
/** The `many` combinator takes a parser, and returns a new parser which will | ||
exports.maybe = function (parser) { return parser.alt(exports.empty()); }; | ||
exports.fold = function (ps) { return Monoid_1.fold(exports.parser)(ps); }; | ||
/** | ||
* 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 | ||
@@ -224,46 +175,42 @@ * a list of the result values of each parse operation as its result, or the | ||
*/ | ||
function many(parser) { | ||
return alt(many1(parser).map(function (a) { return a.toArray(); }), of([])); | ||
} | ||
exports.many = many; | ||
/** The `many1` combinator is just like the `many` combinator, except it | ||
exports.many = function (parser) { return exports.alt(exports.many1(parser).map(function (a) { return a.toArray(); }))(exports.of([])); }; | ||
/** | ||
* 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. | ||
*/ | ||
function many1(parser) { | ||
return parser.chain(function (head) { return many(parser).chain(function (tail) { return of(new NonEmptyArray_1.NonEmptyArray(head, tail)); }); }); | ||
} | ||
exports.many1 = many1; | ||
/** Matches the provided parser `p` zero or more times, but requires the | ||
exports.many1 = function (parser) { | ||
return parser.chain(function (head) { return exports.many(parser).chain(function (tail) { return exports.of(new NonEmptyArray_1.NonEmptyArray(head, tail)); }); }); | ||
}; | ||
/** | ||
* 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`. | ||
*/ | ||
function sepBy(sep, parser) { | ||
return alt(sepBy1(sep, parser).map(function (a) { return a.toArray(); }), alt(parser.map(function (a) { return [a]; }), of([]))); | ||
} | ||
exports.sepBy = sepBy; | ||
/** Matches both parsers and return the value of the second | ||
*/ | ||
function second(pa, pb) { | ||
return new Parser(function (s) { return Apply_1.applySecond({ URI: exports.URI, map: map, ap: ap })(pa, pb).run(s); }); | ||
} | ||
/** Matches the provided parser `p` one or more times, but requires the | ||
exports.sepBy = function (sep, parser) { | ||
return exports.alt(exports.sepBy1(sep, parser).map(function (a) { return a.toArray(); }))(exports.alt(parser.map(function (a) { return [a]; }))(exports.of([]))); | ||
}; | ||
/** Matches both parsers and return the value of the second */ | ||
exports.second = function (pa) { return function (pb) { | ||
return new Parser(function (s) { return Apply_1.applySecond(exports.parser)(pa)(pb).run(s); }); | ||
}; }; | ||
/** | ||
* 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`. | ||
*/ | ||
function sepBy1(sep, parser) { | ||
return parser.chain(function (head) { return alt(many(second(sep, parser)), of([])).chain(function (tail) { return of(new NonEmptyArray_1.NonEmptyArray(head, tail)); }); }); | ||
} | ||
exports.sepBy1 = sepBy1; | ||
exports.sepBy1 = function (sep, parser) { | ||
return parser.chain(function (head) { return exports.alt(exports.many(exports.second(sep)(parser)))(exports.of([])).chain(function (tail) { return exports.of(new NonEmptyArray_1.NonEmptyArray(head, tail)); }); }); | ||
}; | ||
exports.parser = { | ||
URI: exports.URI, | ||
map: map, | ||
of: of, | ||
ap: ap, | ||
chain: chain, | ||
zero: zero, | ||
alt: alt, | ||
empty: empty, | ||
concat: concat | ||
map: exports.map, | ||
of: exports.of, | ||
ap: exports.ap, | ||
chain: exports.chain, | ||
zero: exports.zero, | ||
alt: exports.alt, | ||
empty: exports.empty, | ||
concat: exports.concat | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -71,4 +71,4 @@ "use strict"; | ||
exports.doubleQuotedString = exports.doubleQuote | ||
.chain(function () { return many(p.either(string('\\"'), c.notChar('"'))); }) | ||
.chain(function () { return many(p.either(string('\\"'))(c.notChar('"'))); }) | ||
.chain(function (s) { return exports.doubleQuote.chain(function () { return p.of(s); }); }); | ||
//# sourceMappingURL=string.js.map |
{ | ||
"name": "parser-ts", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"description": "String parser combinators for TypeScript", | ||
@@ -28,3 +28,3 @@ "files": ["lib"], | ||
"dependencies": { | ||
"fp-ts": "^0.4.1" | ||
"fp-ts": "^0.5.1" | ||
}, | ||
@@ -39,3 +39,3 @@ "devDependencies": { | ||
"tslint-config-standard": "4.0.0", | ||
"typescript": "2.4.2", | ||
"typescript": "^2.5.2", | ||
"typings-checker": "1.1.2" | ||
@@ -42,0 +42,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
42466
-0.4%578
-7.37%+ Added
- Removed
Updated