Class Parser<T>
- Direct Known Subclasses:
Parser.Lazy
Different from most parser combinators (such as Haskell Parsec), a common source of bug
(infinite loop or StackOverFlowError caused by accidental zero-consumption rule in the context of
many() or recursive grammar) is made impossible by requiring all parsers to consume at least one
character. Optional suffix is achieved through using the built-in combinators such as optionallyFollowedBy()
and postfix()
; or you can use the
zeroOrMore()
, zeroOrMoreDelimitedBy()
,
orElse()
and optional()
fluent chains.
For simplicity, or()
and anyOf()
will always backtrack upon failure.
But it's more efficient to factor out common left prefix. For example instead of
anyOf(expr.followedBy(";"), expr)
, use expr.optionallyFollowedBy(";"))
instead.
WARNING: do not use this class to parse user-provided input, or in performance critical hot paths. Parser combinators are not known for optimal performance and recursive grammars can be subject to stack overflow error on maliciously crafted input (think of 10K left parens).
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final class
A lazy parser, to be used for recursive grammars.final class
Facilitates a fluent chain for matching the current parser optionally.static class
Thrown if parsing failed. -
Method Summary
Modifier and TypeMethodDescriptionstatic <T> Parser
<T> Matches if any of the givenparsers
match.Returns a parser that applies this parser at least once, greedily.final <A,
R> Parser <R> atLeastOnce
(Collector<? super T, A, ? extends R> collector) Returns a parser that applies this parser at least once, greedily, and collects the return values usingcollector
.atLeastOnceDelimitedBy
(String delimiter) Returns a parser that matches the current parser at least once, delimited by the given delimiter.final <A,
R> Parser <R> atLeastOnceDelimitedBy
(String delimiter, Collector<? super T, A, ? extends R> collector) Returns a parser that matches the current parser at least once, delimited by the given delimiter.Returns a parser that matches the current parser immediately enclosed betweenopen
andclose
.Returns a parser that matches the current parser immediately enclosed betweenopen
andclose
, which are non-empty string delimiters.consecutive
(CharPredicate matcher, String name) Matches one or more consecutive characters as specified bymatcher
.Returns an equivalent parser that fails if the parser result doesn't satisfy the givenpredicate
.final <R> Parser
<R> If this parser matches, applies functionf
to get the next parser to match in sequence.followedBy
(Parser<?> suffix) If this parser matches, continue to matchsuffix
.followedBy
(Parser<X>.OrEmpty suffix) If this parser matches, continue to match the optionalsuffix
.followedBy
(String suffix) If this parser matches, continue to matchsuffix
.static <T> Parser
<T> Returns an equivalent parser that suppresses character skipping that's otherwise applied ifparseSkipping()
orparseToStreamSkipping()
are called.Specifies that the optional (or zero-or-more)rule
should be matched literally even ifparseSkipping()
orparseToStreamSkipping()
is called.final <R> Parser
<R> If this parser matches, returns the result of applying the given function to the match.notFollowedBy
(Parser<?> suffix, String name) A form of negative lookahead such that the match is rejected if followed bysuffix
.notFollowedBy
(String suffix) A form of negative lookahead such that the match is rejected if followed bysuffix
.optional()
Starts a fluent chain for matching the current parser optionally.optionallyFollowedBy
(Parser<? extends UnaryOperator<T>> suffix) Returns an equivalent parser except it will optionally apply the unary operator resulting fromsuffix
.optionallyFollowedBy
(String suffix) Returns an equivalent parser except it allowssuffix
if present.optionallyFollowedBy
(String suffix, Function<? super T, ? extends T> op) If this parser matches, optionally applies theop
function if the pattern is followed bysuffix
.or()
Returns a collector that results in a parser that matches if any of the inputparsers
match.Matches ifthis
orthat
matches.Starts a fluent chain for matching the current parser optionally.final T
Parses the entire input string and returns the result.final T
parseSkipping
(Parser<?> skip, String input) Parsesinput
while skipping patterns matched byskip
around atomic matches.final T
parseSkipping
(CharPredicate charsToSkip, String input) Parsesinput
whilecharsToSkip
around atomic matches.parseToStream
(String input) Parses the entire input string lazily by applying this parser repeatedly until the end of input.parseToStreamSkipping
(Parser<?> skip, String input) Parsesinput
to a lazy stream while skipping patterns matched byskip
around atomic matches.parseToStreamSkipping
(CharPredicate charsToSkip, String input) Parsesinput
to a lazy stream whilecharsToSkip
around atomic matches.postfix
(Parser<? extends UnaryOperator<T>> operator) Returns a parser that after this parser succeeds, applies theoperator
parser zero or more times and apply the result unary operator function iteratively.prefix
(Parser<? extends UnaryOperator<T>> operator) Returns a parser that applies theoperator
parser zero or more times beforethis
and applies the result unary operator functions iteratively.sequence
(Parser<A>.OrEmpty left, Parser<B>.OrEmpty right, BiFunction<? super A, ? super B, ? extends C> combiner) Sequentially matchesleft
thenright
, with both allowed to be optional, and then combines the results using thecombiner
function.static <A,
B, C> Parser <C> sequence
(Parser<A> left, Parser<B>.OrEmpty right, BiFunction<? super A, ? super B, ? extends C> combiner) Sequentially matchesleft
thenright
(which is allowed to be optional), and then combines the results using thecombiner
function.static <A,
B, C> Parser <C> sequence
(Parser<A> left, Parser<B> right, BiFunction<? super A, ? super B, ? extends C> combiner) Sequentially matchesleft
thenright
, and then combines the results using thecombiner
function.single
(CharPredicate matcher, String name) Matches a character as specified bymatcher
.Matches a literalstring
.final <R> Parser
<R> If this parser matches, applies the given parser on the remaining input.final <R> Parser
<R> If this parser matches, applies the given optional (or zero-or-more) parser on the remaining input.final <R> Parser
<R> thenReturn
(R result) If this parser matches, returns the given result.Starts a fluent chain for matching the current parser zero or more times.zeroOrMore
(CharPredicate charsToMatch, String name) Starts a fluent chain for matching consecutivecharsToMatch
zero or more times.zeroOrMore
(Collector<? super T, A, ? extends R> collector) Starts a fluent chain for matching the current parser zero or more times.zeroOrMoreDelimitedBy
(String delimiter) Starts a fluent chain for matching the current parser zero or more times, delimited bydelimiter
.zeroOrMoreDelimitedBy
(String delimiter, Collector<? super T, A, ? extends R> collector) Starts a fluent chain for matching the current parser zero or more times, delimited bydelimiter
.
-
Method Details
-
single
Matches a character as specified bymatcher
. -
consecutive
Matches one or more consecutive characters as specified bymatcher
. -
string
-
sequence
public static <A,B, Parser<C> sequenceC> (Parser<A> left, Parser<B> right, BiFunction<? super A, ? super B, ? extends C> combiner) Sequentially matchesleft
thenright
, and then combines the results using thecombiner
function. -
sequence
public static <A,B, Parser<C> sequenceC> (Parser<A> left, Parser<B>.OrEmpty right, BiFunction<? super A, ? super B, ? extends C> combiner) Sequentially matchesleft
thenright
(which is allowed to be optional), and then combines the results using thecombiner
function. Ifright
is empty, the default value is passed to thecombiner
function. -
sequence
public static <A,B, Parser<C>.OrEmpty sequenceC> (Parser<A>.OrEmpty left, Parser<B>.OrEmpty right, BiFunction<? super A, ? super B, ? extends C> combiner) Sequentially matchesleft
thenright
, with both allowed to be optional, and then combines the results using thecombiner
function. If either is empty, the corresponding default value is passed to thecombiner
function. -
anyOf
Matches if any of the givenparsers
match. -
or
-
or
-
atLeastOnce
-
atLeastOnce
-
atLeastOnceDelimitedBy
Returns a parser that matches the current parser at least once, delimited by the given delimiter.For example if you want to express the regex pattern
(a|b|c)
, you can use:Parser.anyOf(string("a"), string("b"), string("c")) .atLeastOnceDelimitedBy("|")
-
atLeastOnceDelimitedBy
public final <A,R> Parser<R> atLeastOnceDelimitedBy(String delimiter, Collector<? super T, A, ? extends R> collector) Returns a parser that matches the current parser at least once, delimited by the given delimiter.For example if you want to express the regex pattern
(a|b|c)
, you can use:Parser.anyOf(string("a"), string("b"), string("c")) .atLeastOnceDelimitedBy("|", RegexPattern.asAlternation())
-
zeroOrMore
Starts a fluent chain for matching consecutivecharsToMatch
zero or more times. If no such character is found, empty string is the result.For example if you need to parse a quoted literal that's allowed to be empty:
zeroOrMore(c -> c != '\'', "quoted").between("'", "'")
-
zeroOrMore
-
zeroOrMore
Starts a fluent chain for matching the current parser zero or more times.collector
is used to collect the parsed results and the empty collector result will be used if this parser matches zero times.For example if you want to parse a list of statements between a pair of curly braces, you can use:
statement.zeroOrMore(toBlock()).between("{", "}")
-
zeroOrMoreDelimitedBy
Starts a fluent chain for matching the current parser zero or more times, delimited bydelimiter
.For example if you want to parse a list of names
[a,b,c]
, you can use:consecutive(ALPHA, "item") .zeroOrMoreDelimitedBy(",") .between("[", "]")
-
zeroOrMoreDelimitedBy
public final <A,R> Parser<R>.OrEmpty zeroOrMoreDelimitedBy(String delimiter, Collector<? super T, A, ? extends R> collector) Starts a fluent chain for matching the current parser zero or more times, delimited bydelimiter
.collector
is used to collect the parsed results and the empty collector result will be used if this parser matches zero times.For example if you want to parse a set of names
[a,b,c]
, you can use:consecutive(ALPHA, "item") .zeroOrMoreDelimitedBy(",", toImmutableSet()) .between("[", "]")
-
prefix
Returns a parser that applies theoperator
parser zero or more times beforethis
and applies the result unary operator functions iteratively.For infix operator support, consider using
OperatorTable
. -
postfix
Returns a parser that after this parser succeeds, applies theoperator
parser zero or more times and apply the result unary operator function iteratively.This is useful to parse postfix operators such as in regex the quantifiers are usually postfix.
For infix operator support, consider using
OperatorTable
. -
between
-
between
-
map
-
flatMap
-
thenReturn
If this parser matches, returns the given result. -
then
-
then
-
followedBy
-
followedBy
-
followedBy
-
optionallyFollowedBy
-
optionallyFollowedBy
-
optionallyFollowedBy
Returns an equivalent parser except it will optionally apply the unary operator resulting fromsuffix
. -
notFollowedBy
-
notFollowedBy
-
orElse
Starts a fluent chain for matching the current parser optionally.defaultValue
will be the result in case the current parser doesn't match.For example if you want to parse an optional placeholder name enclosed by curly braces, you can use:
consecutive(ALPHA, "placeholder name") .orElse(EMPTY_PLACEHOLDER) .between("{", "}")
-
optional
Starts a fluent chain for matching the current parser optionally.Optional.empty()
will be the result in case the current parser doesn't match.For example if you want to parse an optional placeholder name enclosed by curly braces, you can use:
consecutive(ALPHA, "placeholder name") .optional() .between("{", "}")
-
expecting
Returns an equivalent parser that fails if the parser result doesn't satisfy the givenpredicate
. For example, you could use it to implement a parser for keywords:consecutive(ALPHA, "word").expecting(SUPPORTED_KEYWORDS::contains, "keyword")
-
literally
Returns an equivalent parser that suppresses character skipping that's otherwise applied ifparseSkipping()
orparseToStreamSkipping()
are called. For example quoted string literals should not skip whitespaces. -
literally
Specifies that the optional (or zero-or-more)rule
should be matched literally even ifparseSkipping()
orparseToStreamSkipping()
is called. -
parseSkipping
-
parseSkipping
Parsesinput
whilecharsToSkip
around atomic matches. -
parseToStreamSkipping
-
parseToStreamSkipping
Parsesinput
to a lazy stream whilecharsToSkip
around atomic matches. -
parse
Parses the entire input string and returns the result. Upon successful return, theinput
is fully consumed.- Throws:
Parser.ParseException
- if the input cannot be parsed.
-
parseToStream
-