Defines grammar and encapsulates parsing logic. A ParseObject
takes as input a
String
source and parses it when the ParseObject.apply
method is called.
A structure ParseResult
is returned.
Static methods
staticall():ParseObject<String>
A ParseObject
that consumes and yields the entire remainder of the stream.
staticalt<A>(parsers:Array<ParseObject<A>>):ParseObject<A>
Accepts an array of parsers Array<ParseObject>
, yielding the value of the first
one that succeeds, backtracking in between. This means that the order of
parsers matters. If two parsers match the same prefix, the longer of the two
must come first.
Parser.alt([
Parser.string('ab'),
Parser.string('a')
]).apply('ab');
// => {status: true, value: 'ab'}
Parser.alt([
Parser.string('a'),
Parser.string('ab')
]).apply('ab');
// => {status: false, ...}
In the second case, Parser.alt
matches on the first parser, then
there are extra characters left over ('b'
), so ParseObject
returns a failure.
staticany():ParseObject<String>
A ParseObject
that consumes and yields the next character of the stream.
staticas<A>(parser:ParseObject<A>, expected:String):ParseObject<A>
Returns a new ParseObject
whose failure message is expected parameter. For example,
string('x').as('the letter x')
will indicate that 'the letter x' was
expected.
staticatLeast<A>(parser:ParseObject<A>, n:Int):ParseObject<Array<A>>
Expects ParseObject
at least n
times. Yields an array of the results.
staticinlineatMost<A>(parser:ParseObject<A>, n:Int):ParseObject<Array<A>>
Expects ParseObject
at most n
times. Yields an array of the results.
staticchar(character:String):ParseObject<String>
Returns a ParseObject
that looks for exactly one character from String
and
yields that exact value. This combinator is faster than Parser.string
in case of matching single character.
staticeof<A>():ParseObject<A>
A ParseObject
that expects to be at the end of the stream (zero characters left).
staticfail<A>(expected:String):ParseObject<A>
Returns a failing ParseObject
with the given expected
message.
staticflatMap<A, B>(parser:ParseObject<A>, fun:A‑>ParseObject<B>):ParseObject<B>
Returns a new ParseObject
which tries parser
, and on success calls the function
fun : A -> ParseObject<B>
with the result of the parse, which is expected to
return another parser, which will be tried next. This allows you to
dynamically decide how to continue the parse, which is impossible with the
other combinators.
var CustomString =
Parser.string('%')
.then(Parser.any())
.flatMap(function(start) {
var end = [
'[' => ']',
'(' => ')',
'{' => '}',
'<'=> '>'
][start];
end = end != null ? end : start;
return Parser.takeWhile(function(c) {
return c != end;
}).skip(Parser.string(end));
});
CustomString.apply('%:a string:'); // => {status: true, value: 'a string'}
CustomString.apply('%[a string]'); // => {status: true, value: 'a string'}
CustomString.apply('%{a string}'); // => {status: true, value: 'a string'}
CustomString.apply('%(a string)'); // => {status: true, value: 'a string'}
CustomString.apply('%<a string>'); // => {status: true, value: 'a string'}
staticlazy<A>(fun:Void‑>ParseObject<A>):ParseObject<A>
Accepts a function that returns a ParseObject
, which is evaluated the first
time the parser is used. This is useful for referencing parsers that haven't
yet been defined, and for implementing recursive parsers.
static var Value = Parser.lazy(function() {
return Parser.alt([
Parser.string('x'),
Parser.string('(')
.then(Value)
.skip(Parser.string(')'))
]);
});
// ...
Value.apply('X'); // => {status: true, value: 'X'}
Value.apply('(X)'); // => {status: true, value: 'X'}
Value.apply('((X))'); // => {status: true, value: 'X'}
staticmany<A>(parser:ParseObject<A>):ParseObject<Array<A>>
Expects ParseObject
zero or more times, and yields an array of the results.
staticinlinemany1<A>(parser:ParseObject<A>):ParseObject<Array<A>>
Expects ParseObject
one or more times, and yields an array of the results.
staticmap<A, B>(parser:ParseObject<A>, fun:A‑>B):ParseObject<B>
Transforms the output of parser
with the given function fun : A -> B
.
var pNum = Parser.regexp(~/[0-9]+/).map(Std.applyInt);
pNum.apply('9'); // => {status: true, value: 9}
pNum.apply('123'); // => {status: true, value: 123}
pNum.apply('3.1'); // => {status: true, value: 3.1}
staticnoneOf(string:String):ParseObject<String>
Returns a ParseObject
that looks for exactly one character NOT from String
,
and yields that character.
staticoneOf(string:String):ParseObject<String>
Returns a ParseObject
that looks for exactly one character from String
, and
yields that character.
staticor<A>(parser:ParseObject<A>, alternative:ParseObject<A>):ParseObject<A>
Returns a new ParseObject
which tries parser
, and if it fails uses
alternative
. Example:
var numberPrefix =
Parser.string('+')
.or(Parser.of('-'))
.or(Parser.of(''));
numberPrefix.apply('+'); // => {status: true, value: '+'}
numberPrefix.apply('-'); // => {status: true, value: '-'}
numberPrefix.apply(''); // => {status: true, value: ''}
staticregexp(re:EReg, group:Int = 0):ParseObject<String>
Returns a ParseObject
that looks for a match to the EReg
and yields the given
match group (defaulting to the entire match). The EReg
will always match
starting at the current parse location. The regexp may only use the
following flags: imu. Any other flag will result in some weird behaviour.
staticresult<A, B>(parser:ParseObject<A>, value:B):ParseObject<B>
Returns a new ParseObject
with the same behavior, but which yields value
.
Equivalent to Parser.map(parser, function(x) return x)
.
staticinlinesepBy<A, B>(parser:ParseObject<A>, separator:ParseObject<B>):ParseObject<Array<A>>
Accepts two ParseObject
s, and expects zero or more matches for content,
separated by separator
, yielding an array.
Parser.sepBy(
Parser.oneOf('abc'),
Parser.string('|')
).apply('a|b|c|c|c|a');
// => {status: true, value: ['a', 'b', 'c', 'c', 'c', 'a']}
Parser.sepBy(
Parser.oneOf('XYZ'),
Parser.string('-')
).apply('');
// => {status: true, value: []}
staticsepBy1<A, B>(parser:ParseObject<A>, separator:ParseObject<B>):ParseObject<Array<A>>
This is the same as ParseObject.sepBy
, but matches the content parser at least
once.
staticseq<A>(parsers:Array<ParseObject<A>>):ParseObject<Array<A>>
Accepts an array of parsers Array<ParseObject>
and returns a new
ParseObject<Array>
that expects them to match in order, yielding an array of
all their results.
staticskip<A, B>(parser:ParseObject<A>, next:ParseObject<B>):ParseObject<A>
Expects next
after parser
, but yields the value of parser
.
var parserA = p1.skip(p2); // is equivalent to...
var parserB = Parser.seq([p1, p2]).map(function(results) return results[0]);
staticstring(string:String):ParseObject<String>
Returns a ParseObject
that looks for String
and yields that exact value.
staticsucceed<A>(value:A):ParseObject<A>
Returns a ParseObject
that doesn't consume any of the string, and yields
value
.
statictakeWhile(predicate:String‑>Bool):ParseObject<String>
Returns a ParseObject
yielding a string containing all the next characters that
pass the predicate : String -> Bool
.
var CustomString =
Parser.string('%')
.then(Parser.any())
.flatMap(function(start) {
var end = [
'[' => ']',
'(' => ')',
'{' => '}',
'<'=> '>'
][start];
end = end != null ? end : start;
return Parser.takeWhile(function(c) {
return c != end;
}).skip(Parser.string(end));
});
CustomString.apply('%:a string:'); // => {status: true, value: 'a string'}
CustomString.apply('%[a string]'); // => {status: true, value: 'a string'}
CustomString.apply('%{a string}'); // => {status: true, value: 'a string'}
CustomString.apply('%(a string)'); // => {status: true, value: 'a string'}
CustomString.apply('%<a string>'); // => {status: true, value: 'a string'}
statictest(predicate:String‑>Bool):ParseObject<String>
Returns a ParseObject
that yield a single character if it passes the predicate
function String -> Bool
.
var SameUpperLower = Parser.test(function(c) {
return c.toUpperCase() == c.toLowerCase();
});
SameUpperLower.apply('a'); // => {status: false, ...}
SameUpperLower.apply('-'); // => {status: true, ...}
SameUpperLower.apply(':'); // => {status: true, ...}
staticthen<A, B>(parser:ParseObject<A>, next:ParseObject<B>):ParseObject<B>
Expects next
to follow parser
, and yields the result of next
.
var parserA = p1.then(p2); // is equivalent to...
var parserB = Parser.seq([p1, p2]).map(function(results) return results[1]);
statictimes<A>(parser:ParseObject<A>, min:Int, ?max:Int):ParseObject<Array<A>>
Expects ParseObject
between min
and max
times (or exactly min
times, when
max
is omitted), and yields an array of the results.