final class Parsley[+A] extends AnyVal
This is the class that encapsulates the act of parsing and running an object of this class with parse
will
parse the string given as input to parse
.
- Source
- Parsley.scala
- Version
4.0.0
- Note
In order to construct an object of this class you must use the combinators; the class itself is opaque.
- Grouped
- Alphabetic
- By Inheritance
- Parsley
- AnyVal
- Any
- Hide All
- Show All
- Public
- All
Value Members
-
final
def
!=(arg0: Any): Boolean
- Definition Classes
- Any
-
final
def
##(): Int
- Definition Classes
- Any
-
def
#>[B](x: B): Parsley[B]
This combinator, pronounced "as", replaces the result of this parser, ignoring the old result.
This combinator, pronounced "as", replaces the result of this parser, ignoring the old result.
Similar to
map
, except the old result of this parser is not required to compute the new result. This is useful when the result is a constant value (or function!). Functionally the same asthis *> pure(x)
orthis.map(_ => x)
.In Haskell, this combinator is known as
($>)
.- x
the new result of this parser.
- returns
a new parser that behaves the same as this parser, but always succeeds with
x
as the result.
scala> import parsley.character.string scala> (string("true") #> true).parse("true") val res0 = Success(true)
Example: -
def
*>[B](q: ⇒ Parsley[B]): Parsley[B]
This combinator, pronounced "then", first parses this parser then parses
q
: if both succeed then the result ofq
is returned.This combinator, pronounced "then", first parses this parser then parses
q
: if both succeed then the result ofq
is returned.First, this parser is ran, yielding
x
on success, thenq
is ran, yieldingy
on success. If both are successful theny
is returned andx
is ignored. If either fail then the entire combinator fails.Identical to
~>
:*>
is more common in Haskell, whereas~>
is more common in Scala.- q
the parser to run second, which returns the result of this combinator.
- returns
a parser that sequences this parser with
q
and returnsq
's result.
scala> import parsley.character.char scala> ('a' *> 'b').parse("ab") val res0 = Success('b')
Example: -
def
<*[B](q: ⇒ Parsley[B]): Parsley[A]
This combinator, pronounced "then discard", first parses this parser then parses
q
: if both succeed then the result of this parser is returned.This combinator, pronounced "then discard", first parses this parser then parses
q
: if both succeed then the result of this parser is returned.First, this parser is ran, yielding
x
on success, thenq
is ran, yieldingy
on success. If both are successful thenx
is returned andy
is ignored. If either fail then the entire combinator fails.Identical to
<~
:<*
is more common in Haskell, whereas<~
is more common in Scala.- q
the parser to run second, which returns the result of this combinator.
- returns
a parser that sequences this parser with
q
and returns this parser's result.
scala> import parsley.character.char scala> ('a' <* 'b').parse("ab") val res0 = Success('a')
Example: -
def
<**>[B](pf: ⇒ Parsley[(A) ⇒ B]): Parsley[B]
This combinator, pronounced "reverse ap", first parses this parser then parses
pf
: if both succeed then the value returned by this parser is applied to the function returned bypf
.This combinator, pronounced "reverse ap", first parses this parser then parses
pf
: if both succeed then the value returned by this parser is applied to the function returned bypf
.First, this parser is ran, yielding a value
x
on success, thenpf
is ran, yielding a functionf
on success. If both are successful, thenf(x)
is returned. If either fail then the entire combinator fails.Compared with
<*>
, this combinator is useful for left-factoring: when two branches of a parser share a common prefix, this can often be factored out; but the result of that factored prefix may be required to help generate the results of each branch. In this case, the branches can return functions that, when given the factored result, can produce the original results from before the factoring.- pf
the parser to run second, which returns a function this parser's result can be applied to.
- returns
a parser that sequences this parser with
pf
and combines their results with function application.
// this has a common prefix "term" and requires backtracking val expr1 = attempt(lift2(Add, term <* char('+'), expr2)) <|> term // common prefix factored out, and branches return a function to recombine val expr2 = term <**> (char('+') *> expr2.map(y => Add(_, y)) </> (identity[Expr] _))
- Note
equivalent to
lift2((x, f) => f(x), this, pf)
Example: -
def
<*>[B, C](px: ⇒ Parsley[B])(implicit ev: <:<[A, (B) ⇒ C]): Parsley[C]
This combinator, pronounced "ap", first parses this parser then parses
px
: if both succeed then the function returned by this parser is applied to the value returned bypx
.This combinator, pronounced "ap", first parses this parser then parses
px
: if both succeed then the function returned by this parser is applied to the value returned bypx
.The implicit (compiler-provided) evidence proves that this parser really has type
Parsley[B => C]
. First, this parser is ran, yielding a functionf
on success, thenpx
is ran, yielding a valuex
on success. If both are successful, thenf(x)
is returned. If either fail then the entire combinator fails.- px
the parser to run second, which returns a value applicable to this parser's result.
- ev
witnesses that the type of this parser,
A
, is actuallyB => C
.- returns
a parser that sequences this parser with
px
and combines their results with function application.
scala> import parsley.Parsley, parsley.character.char scala> val sign: Parsley[Int => Int] = char('+') #> (identity[Int] _) <|> char('-') #> (x => -x) scala> val nat: Parsley[Int] = .. scala> val int = sign <*> nat scala> int.parse("-7") val res0 = Success(-7) scala> int.parse("+42") val res1 = Success(42) scala> int.parse("2") val res2 = Failure(..) // `sign` failed: no + or - scala> int.parse("-a") val res3 = Failure(..) // `nat` failed
- Note
equivalent to
lift2((f, x) => f(x), this, px)
.
Example: -
def
<+:>[Aʹ >: A](ps: ⇒ Parsley[Seq[Aʹ]]): Parsley[Seq[Aʹ]]
This combinator, pronounced "prepend", first parses this parser then parses
ps
: if both succeed the result of this parser is prepended onto the result ofps
.This combinator, pronounced "prepend", first parses this parser then parses
ps
: if both succeed the result of this parser is prepended onto the result ofps
.First, this parser is ran, yielding
x
on success, thenps
is ran, yieldingxs
on success. If both are successful thenx +: xs
is returned. If either fail then the entire combinator fails.- Aʹ
the type of the elements in the result sequence, which must be a supertype of the result type of this parser: this allows for weakening of the result type.
- ps
the parser to run second, which returns a sequence.
- returns
a parser that sequences this parser with
ps
and prepends its result ontops
result.
def some[A](p: Parsley[A]): Parsley[List[A]] = { p <+:> many(p) // since List[A] <: Seq[A] }
- Note
equivalent to
lift2(_ +: _, this, ps)
Example: -
def
<+>[B](q: Parsley[B]): Parsley[Either[A, B]]
This combinator, pronounced "sum", wraps this parser's result in
Left
if it succeeds, and parsesq
if it failed without consuming input, wrapping the result inRight
.This combinator, pronounced "sum", wraps this parser's result in
Left
if it succeeds, and parsesq
if it failed without consuming input, wrapping the result inRight
.If this parser is successful, then its result is wrapped up using
Left(_)
and no further action is taken. Otherwise, if this parser fails without consuming input, thenq
is parsed instead and its result is wrapped up usingRight(_)
. If this parser fails having consumed input, this combinator fails. This is functionally equivalent tothis.map(Left(_)) <|> q.map(Right(_))
.The reason for this behaviour is that it prevents space leaks and improves error messages. If this behaviour is not desired, use
attempt(this)
to rollback any input consumed on failure.- q
the parser to run if this parser fails having not consumed input.
- returns
a parser which either parses this parser or parses
q
projecting their results into anEither[A, B]
.
scala> import parsley.character.char scala> val p = string("abc") <+> char("xyz") scala> p.parse("abc") val res0 = Success(Left("abc")) scala> p.parse("xyz") val res1 = Success(Right("xyz")) scala> p.parse("ab") val res2 = Failure(..) // first parser consumed an 'a'!
Example: -
def
</>[Aʹ >: A](x: Aʹ): Parsley[Aʹ]
This combinator, pronounced "or constant", returns
x
if this parser fails without consuming input.This combinator, pronounced "or constant", returns
x
if this parser fails without consuming input.If this parser is successful, then this combinator is successful and no further action is taken. Otherwise, if this parser fails without consuming input, then
x
is unconditionally returned. If this parser fails having consumed input, this combinator fails. Functionally the same asthis <|> pure(x)
.The reason for this behaviour is that it prevents space leaks and improves error messages. If this behaviour is not desired, use
attempt(this)
to rollback any input consumed on failure.- Aʹ
the type of
x
, which must be a supertype of the result type of this parser: this allows for weakening of the result type.- x
the value to return if this parser fails having not consumed input.
- returns
a parser which either parses this parser or returns
x
.
scala> import parsley.character.string scala> val p = string("aa") </> "b" scala> p.parse("aa") val res0 = Success("a") scala> p.parse("xyz") val res1 = Success("b") scala> p.parse("ab") val res2 = Failure(..) // first parser consumed an 'a'!
Example: -
def
<::>[Aʹ >: A](ps: ⇒ Parsley[List[Aʹ]]): Parsley[List[Aʹ]]
This combinator, pronounced "cons", first parses this parser then parses
ps
: if both succeed the result of this parser is prepended onto the result ofps
.This combinator, pronounced "cons", first parses this parser then parses
ps
: if both succeed the result of this parser is prepended onto the result ofps
.First, this parser is ran, yielding
x
on success, thenps
is ran, yieldingxs
on success. If both are successful thenx :: xs
is returned. If either fail then the entire combinator fails.- Aʹ
the type of the elements in the result list, which must be a supertype of the result type of this parser: this allows for weakening of the result type.
- ps
the parser to run second, which returns a list.
- returns
a parser that sequences this parser with
ps
and prepends its result ontops
result.
def some[A](p: Parsley[A]): Parsley[List[A]] = { p <::> many(p) }
- Note
equivalent to
lift2(_ :: _, this, ps)
Example: -
def
<|>[Aʹ >: A](q: Parsley[Aʹ]): Parsley[Aʹ]
This combinator, pronounced "or", parses
q
if this parser fails without consuming input.This combinator, pronounced "or", parses
q
if this parser fails without consuming input.If this parser is successful, then this combinator is successful and no further action is taken. Otherwise, if this parser fails without consuming input, then
q
is parsed instead. If this parser fails having consumed input, this combinator fails.The reason for this behaviour is that it prevents space leaks and improves error messages. If this behaviour is not desired, use
attempt(this)
to rollback any input consumed on failure.- Aʹ
the type returned by
q
, which must be a supertype of the result type of this parser: this allows for weakening of the result type.- q
the parser to run if this parser fails having not consumed input.
- returns
a parser which either parses this parser or parses
q
.
scala> import parsley.character.string scala> val p = string("a") <|> string("b") scala> p.parse("a") val res0 = Success("a") scala> p.parse("b") val res1 = Success("b") scala> val q = string("ab") <|> string("ac") scala> q.parse("ac") val res2 = Failure(..) // first parser consumed an 'a'!
Example: -
def
<~[B](q: ⇒ Parsley[B]): Parsley[A]
This combinator, pronounced "then discard", first parses this parser then parses
q
: if both succeed then the result of this parser is returned.This combinator, pronounced "then discard", first parses this parser then parses
q
: if both succeed then the result of this parser is returned.First, this parser is ran, yielding
x
on success, thenq
is ran, yieldingy
on success. If both are successful thenx
is returned andy
is ignored. If either fail then the entire combinator fails.Identical to
<*
:<*
is more common in Haskell, whereas<~
is more common in Scala.- q
the parser to run second, which returns the result of this combinator.
- returns
a parser that sequences this parser with
q
and returns this parser's result.
scala> import parsley.character.char scala> ('a' <~ 'b').parse("ab") val res0 = Success('a')
- Since
2.4.0
Example: -
def
<~>[B](q: ⇒ Parsley[B]): Parsley[(A, B)]
This combinator, pronounced "zip", first parses this parser then parses
q
: if both succeed the result of this parser is paired with the result ofq
.This combinator, pronounced "zip", first parses this parser then parses
q
: if both succeed the result of this parser is paired with the result ofq
.First, this parser is ran, yielding
x
on success, thenq
is ran, yieldingy
on success. If both are successful then(x, y)
is returned. If either fail then the entire combinator fails.- q
the parser to run second.
- returns
a parser that sequences this parser with
q
and pairs their results together.
scala> import parsley.character.char scala> val p = char('a') <~> char('b') scala> p.parse("ab") val res0 = Success(('a', 'b')) scala> p.parse("b") val res1 = Failure(..) scala> p.parse("a") val res2 = Failure(..)
- Note
equivalent to
lift2((_, _), this, q)
Example: -
final
def
==(arg0: Any): Boolean
- Definition Classes
- Any
-
def
>>=[B](f: (A) ⇒ Parsley[B]): Parsley[B]
This combinator, pronounced "bind", first performs this parser, then uses its result to generate and execute a new parser.
This combinator, pronounced "bind", first performs this parser, then uses its result to generate and execute a new parser.
First, this combinator runs this parser. If it succeeded, the result
x
is given to the functionf
to produce a new parserf(x)
. This new parser is then executed and its result returned. If either of this parser or the new parser fails, then the entire combinator fails.This is a very powerful combinator (Turing-powerful, in fact): it is only necessary (and not all the time) to use this for context-sensitive parsing. The idea is that it can make any form of decision based on the result of a parser, allowing it to perform a different parser for each possible output of another without exhaustively enumerating them all.
- f
the function that produces the next parser.
- returns
a new parser, which sequences this parser with the parser generated from its result.
// this is an inefficient implementation, but does work def filter(pred: A => Boolean): Parsley[A] = { this >>= { x => if (pred(x)) pure(x) else empty } }
- Note
there is significant overhead for using
>>=
: if possible try to avoid using it! This is because Parsley will need to generate, process, and compile each parser produced by the combinator during parse-time.
Example: -
final
def
asInstanceOf[T0]: T0
- Definition Classes
- Any
-
def
collect[B](pf: PartialFunction[A, B]): Parsley[B]
This combinator applies a partial function
pf
to the result of this parser if its result is defined forpf
, failing if it is not.This combinator applies a partial function
pf
to the result of this parser if its result is defined forpf
, failing if it is not.First, parse this parser. If it succeeds, test whether its result
x
is in the domain of the partial functionpf
. If it is defined forpf
, returnpf(x)
. If it is undefined, or this parser failed, then this combinator fails. Equivalent to afilter
followed by amap
.- pf
the partial function used to both filter the result of this parser and transform it.
- returns
a parser that returns the result of this parser applied to
pf
, if possible.
scala> val int: Parsley[Int] = .. scala> val safeDiv: Parsley[Int] = (int <~> char(' ') *> int).collect { case (x, y) if y != 0 => x / y } scala> safeDiv.parse("7 0") val res0 = Failure(..) // y cannot be 0! scala> safeDiv.parse("10 2") val res1 = Success(5)
- Since
2.0.0
- Note
when this combinator fails (and not this parser itself), it will generate errors rooted at the start of the parse (as if
amend
had been used) and the caret will span the entire successful parse of this parser.- See also
collectMsg(String, String*)
andcollectMsg(A => Seq[String])
for versions that can produce custom error messages on failure.
Example: -
def
filter(pred: (A) ⇒ Boolean): Parsley[A]
This combinator filters the result of this parser using a given predicate, succeeding only if the predicate returns
true
.This combinator filters the result of this parser using a given predicate, succeeding only if the predicate returns
true
.First, parse this parser. If it succeeds then take its result
x
and apply it to the predicatepred
. Ifpred(x)
is true, then returnx
. Otherwise, the combinator fails.- pred
the predicate that is tested against the parser result.
- returns
a parser that returns the result of this parser if it passes the predicate.
scala> import parsley.character.letter scala> val keywords = Set("if", "then", "else") scala> val identifier = some(letter).map(_.mkString) .filter(!keywords.contains(_)) scala> identifier.parse("hello") val res0 = Success("hello") scala> idenfitier.parse("if") val res1 = Failure(..)
- Note
when this combinator fails (and not this parser itself), it will generate errors rooted at the start of the parse (as if
amend
had been used) and the caret will span the entire successful parse of this parser.- See also
filterOut
for a version which can produce custom reasons on failure.guardAgainst
for a version which can produce custom error messages on failure.
Example: -
def
filterNot(pred: (A) ⇒ Boolean): Parsley[A]
This combinator filters the result of this parser using a given predicate, succeeding only if the predicate returns
false
.This combinator filters the result of this parser using a given predicate, succeeding only if the predicate returns
false
.First, parse this parser. If it succeeds then take its result
x
and apply it to the predicatepred
. Ifpred(x) is false, then return
x. Otherwise, the combinator fails.
- pred
the predicate that is tested against the parser result.
- returns
a parser that returns the result of this parser if it fails the predicate.
scala> import parsley.character.letter scala> val keywords = Set("if", "then", "else") scala> val identifier = some(letter).map(_.mkString) .filterNot(keywords.contains(_)) scala> identifier.parse("hello") val res0 = Success("hello") scala> idenfitier.parse("if") val res1 = Failure(..)
- Note
when this combinator fails (and not this parser itself), it will generate errors rooted at the start of the parse (as if
amend
had been used) and the caret will span the entire successful parse of this parser.- See also
filterOut
for a version that can produce custom reasons on failure.guardAgainst
for a version that can produce custom error messages on failure.
Example: -
def
flatMap[B](f: (A) ⇒ Parsley[B]): Parsley[B]
This combinator first performs this parser, then uses its result to generate and execute a new parser.
This combinator first performs this parser, then uses its result to generate and execute a new parser.
First, this combinator runs this parser. If it succeeded, the result
x
is given to the functionf
to produce a new parserf(x)
. This new parser is then executed and its result returned. If either of this parser or the new parser fails, then the entire combinator fails.This is a very powerful combinator (Turing-powerful, in fact): it is only necessary (and not all the time) to use this for context-sensitive parsing. The idea is that it can make any form of decision based on the result of a parser, allowing it to perform a different parser for each possible output of another without exhaustively enumerating them all.
In Haskell, this combinator is known as
(>>=)
(pronounced "bind").- f
the function that produces the next parser.
- returns
a new parser, which sequences this parser with the parser generated from its result.
// this is an inefficient implementation, but does work def filter(pred: A => Boolean): Parsley[A] = { this.flatMap { x => if (pred(x)) pure(x) else empty } }
- Note
there is significant overhead for using
flatMap
: if possible try to avoid using it! This is because Parsley will need to generate, process, and compile each parser produced by the combinator during parse-time.
Example: -
def
flatten[B](implicit ev: <:<[A, Parsley[B]]): Parsley[B]
This combinator collapses two layers of parsing structure into one.
This combinator collapses two layers of parsing structure into one.
The implicit (compiler-provided) evidence proves that this parser really has type
Parsley[Parsley[B]]
. First, this parser is executed, which, if successful, will produce a new parserp
. The parserp
is then executed, and its result is returned. If either this parser orp
fail, then the entire combinator fails.This is a very powerful combinator (Turing-powerful, in fact): it is only necessary (and not all the time) to use this for context-sensitive parsing. The idea is that it can allow a parser to return any other parser as its result: this allows for an implementation of a later parser to be picked by an earlier one.
In Haskell, this combinator is known as
join
.- ev
witnesses that the result type of this parser,
A
, is reallyParsley[B]
.- returns
a new parser, which sequences this parser with its result parser.
imagine a parser for RegEx that first reads the description of the regular expression, then runs that against the remaining input string. It is possible to implement the parser for the regular expression itself as a
Parsley[Parsley[Unit]]
, which returns a parser that matches the regular expression. This can then be used to parse the remaining input by usingflatten
to incorporate it into the parser again:scala> val regexDesc: Parsley[Parsley[Unit]] = .. // let's suppose "#" is the delimeter between expression and input scala> val regex: Parsley[Unit] = (regexDesc <* char('#')).flatten scala> regex.parse("a.(c*)#abccc") val res0 = Success(()) scala> regex.parse("a.(c*)#a") val res1 = Failure(..)
- Note
there is significant overhead for using
flatten
: if possible try to avoid using it! This is because Parsley will need to generate, process, and compile each parser produced by the combinator during parse-time.
Example: -
def
foldLeft[B](k: B)(f: (B, A) ⇒ B): Parsley[B]
This combinator will parse this parser zero or more times combining the results with the function
f
and base valuek
from the left.This combinator will parse this parser zero or more times combining the results with the function
f
and base valuek
from the left.This parser will continue to be parsed until it fails having not consumed input. All of the results generated by the successful parses are then combined in a left-to-right fashion using the function
f
: the accumulation is initialised with the valuek
. If this parser does fail at any point having consumed input, this combinator will fail.- k
initial accumulation value.
- f
function to apply to each iteration's accumulator.
- returns
a parser which parses this parser many times and folds the results together with
f
andk
left-associatively.
// this is not an efficient implementation of stringOfMany def stringOfMany(pc: Parsley[Char]): Parsley[String] = { pc.foldLeft("")(_ + _) }
Example: -
def
foldLeft1[B](k: B)(f: (B, A) ⇒ B): Parsley[B]
This combinator will parse this parser one or more times combining the results with the function
f
and base valuek
from the left.This combinator will parse this parser one or more times combining the results with the function
f
and base valuek
from the left.This parser will continue to be parsed until it fails having not consumed input. All of the results generated by the successful parses are then combined in a left-to-right fashion using the function
f
: the accumulation is initialised with the valuek
. If this parser does fail at any point having consumed input, this combinator will fail.- k
initial accumulation value.
- f
function to apply to each iteration's accumulator.
- returns
a parser which parses this parser some times and folds the results together with
f
andk
left-associatively.
val natural: Parsley[Int] = digit.foldLeft1(0)((x, d) => x * 10 + d.toInt)
- Since
2.1.0
Example: -
def
foldRight[B](k: B)(f: (A, B) ⇒ B): Parsley[B]
This combinator will parse this parser zero or more times combining the results with the function
f
and base valuek
from the right.This combinator will parse this parser zero or more times combining the results with the function
f
and base valuek
from the right.This parser will continue to be parsed until it fails having not consumed input. All of the results generated by the successful parses are then combined in a right-to-left fashion using the function
f
: the right-most value provided tof
is the valuek
. If this parser does fail at any point having consumed input, this combinator will fail.- k
value to use when this parser no longer succeeds.
- f
function to apply to each value produced by this parser, starting at the right.
- returns
a parser which parses this parser many times and folds the results together with
f
andk
right-associatively.
// in reality, many is implemented more efficiently def many[A](p: Parsley[A]) = { p.foldRight(List.empty[A])(_ :: _) }
Example: -
def
foldRight1[B](k: B)(f: (A, B) ⇒ B): Parsley[B]
This combinator will parse this parser one or more times combining the results with the function
f
and base valuek
from the right.This combinator will parse this parser one or more times combining the results with the function
f
and base valuek
from the right.This parser will continue to be parsed until it fails having not consumed input. All of the results generated by the successful parses are then combined in a right-to-left fashion using the function
f
: the right-most value provided tof
is the valuek
. If this parser does fail at any point having consumed input, this combinator will fail.- k
value to use when this parser no longer succeeds.
- f
function to apply to each value produced by this parser, starting at the right.
- returns
a parser which parses this parser some times and folds the results together with
f
andk
right-associatively.
// in reality, some is implemented more efficiently def some[A](p: Parsley[A]) = { p.foldRight1(List.empty[A])(_ :: _) }
- Since
2.1.0
Example: -
def
force(): Unit
Forces the compilation of a parser as opposed to the regular lazy evaluation.
-
def
getClass(): Class[_ <: AnyVal]
- Definition Classes
- AnyVal → Any
-
def
getOrElse[Aʹ >: A](x: Aʹ): Parsley[Aʹ]
This combinator returns
x
if this parser fails without consuming input.This combinator returns
x
if this parser fails without consuming input.If this parser is successful, then this combinator is successful and no further action is taken. Otherwise, if this parser fails without consuming input, then
x
is unconditionally returned. If this parser fails having consumed input, this combinator fails. Functionally the same asthis <|> pure(x)
.The reason for this behaviour is that it prevents space leaks and improves error messages. If this behaviour is not desired, use
attempt(this)
to rollback any input consumed on failure.scala> import parsley.character.string scala> val p = string("aa").getOrElse("b") scala> p.parse("aa") val res0 = Success("a") scala> p.parse("xyz") val res1 = Success("b") scala> p.parse("ab") val res2 = Failure(..) // first parser consumed an 'a'!
- Note
just an alias for
</>
Example: -
final
def
isInstanceOf[T0]: Boolean
- Definition Classes
- Any
-
def
map[B](f: (A) ⇒ B): Parsley[B]
This combinator allows the result of this parser to be changed using a given function.
This combinator allows the result of this parser to be changed using a given function.
When this parser succeeds,
map(f)
will adjust its result using the functionf
, which can potentially change its type. This can be used to build more complex results from parsers, instead of just characters or strings.In Haskell, this combinator is known as
fmap
or(<$>)
.- f
the function to apply to the result of the parse
- returns
a new parser that behaves the same as this parser, but with the given function
f
applied to its result.
scala> import parsley.character.digit scala> digit.map(_.asDigit).parse("7") val res0 = Success(7)
- Note
This is subject to aggressive optimisations assuming purity; the compiler is permitted to optimise such that the application of
f
actually only happens once at compile time. In order to preserve the behaviour of impure functions, consider using theunsafe
method before map;p.unsafe.map(f)
.
Example: -
def
mapFilter[B](f: (A) ⇒ Option[B]): Parsley[B]
This combinator applies a function
f
to the result of this parser: if it returns aSome(y)
,y
is returned, otherwise the parser fails.This combinator applies a function
f
to the result of this parser: if it returns aSome(y)
,y
is returned, otherwise the parser fails.First, parse this parser. If it succeeds, apply the function
f
to the resultx
. Iff(x)
returnsSome(y)
, returny
. Iff(x)
returnsNone
, or this parser failed then this combinator fails. Is a more efficient way of performing afilter
andmap
at the same time.- f
the function used to both filter the result of this parser and transform it.
- returns
a parser that returns the result of this parser applied to
f
, if it yields a value.
scala> val int: Parsley[Int] = .. scala> val safeDiv: Parsley[Int] = (int <~> char(' ') *> int).collect { case (x, y) if y != 0 => Some(x / y) case _ => None } scala> safeDiv.parse("7 0") val res0 = Failure(..) // y cannot be 0! scala> safeDiv.parse("10 2") val res1 = Success(5)
- Since
4.0.0
- Note
when this combinator fails (and not this parser itself), it will generate errors rooted at the start of the parse (as if
amend
had been used) and the caret will span the entire successful parse of this parser.
Example: -
def
orElse[Aʹ >: A](q: Parsley[Aʹ]): Parsley[Aʹ]
This combinator parses
q
if this parser fails without consuming input.This combinator parses
q
if this parser fails without consuming input.If this parser is successful, then this combinator is successful and no further action is taken. Otherwise, if this parser fails without consuming input, then
q
is parsed instead. If this parser fails having consumed input, this combinator fails.The reason for this behaviour is that it prevents space leaks and improves error messages. If this behaviour is not desired, use
attempt(this)
to rollback any input consumed on failure.- Aʹ
the type returned by
q
, which must be a supertype of the result type of this parser: this allows for weakening of the result type.- q
the parser to run if this parser fails having not consumed input.
- returns
a parser which either parses this parser or parses
q
.
scala> import parsley.character.string scala> val p = string("a").orElse(string("b")) scala> p.parse("a") val res0 = Success("a") scala> p.parse("b") val res1 = Success("b") scala> val q = string("ab").orElse(string("ac")) scala> q.parse("ac") val res2 = Failure(..) // first parser consumed an 'a'!
- Since
4.0.0
- Note
just an alias for
<|>
.
Example: -
def
overflows(): Unit
Provides an indicator that this parser will likely stack-overflow and so a stack-safe construction should be used when "compiling" this parser.
-
def
parse[Err](input: String)(implicit arg0: ErrorBuilder[Err]): Result[Err, A]
This method is responsible for actually executing parsers.
This method is responsible for actually executing parsers. Given an input array, will parse the string with the parser. The result is either a
Success
or aFailure
.- input
The input to run against
- returns
Either a success with a value of type
A
or a failure with error message
- Since
3.0.0
-
def
reduceLeft[B >: A](op: (B, A) ⇒ B): Parsley[B]
This combinator will parse this parser one or more times combining the results left-associatively with the function
op
.This combinator will parse this parser one or more times combining the results left-associatively with the function
op
.This parser will continue to be parsed until it fails having not consumed input. All of the results generated by the successful parses are then combined in a left-to-right fashion using the function
op
. If this parser does fail at any point having consumed input, this combinator will fail.- op
function to apply to each value produced by this parser, starting from the left.
- returns
a parser which parses this parser some times and folds the results together with
op
left-associatively.
stmt.reduceLeft(Seq(_, _))
- Since
2.3.0
Example: -
def
reduceLeftOption[B >: A](op: (B, A) ⇒ B): Parsley[Option[B]]
This combinator will parse this parser zero or more times combining the results left-associatively with the function
op
.This combinator will parse this parser zero or more times combining the results left-associatively with the function
op
.This parser will continue to be parsed until it fails having not consumed input. If this parser succeeded at least once, all of the results generated by the successful parses are then combined in a left-to-right fashion using the function
op
and returned in aSome
. If no successful parses occurred, thenNone
is returned. If this parser does fail at any point having consumed input, this combinator will fail.- op
function to apply to each value produced by this parser, starting from the left.
- returns
a parser which parses this parser many times and folds the results together with
op
left-associatively or returns None if no parses occured.
arg.reduceLeftOption(Sep(_, _))
- Since
2.3.0
Example: -
def
reduceRight[B >: A](op: (A, B) ⇒ B): Parsley[B]
This combinator will parse this parser one or more times combining the results right-associatively with the function
op
.This combinator will parse this parser one or more times combining the results right-associatively with the function
op
.This parser will continue to be parsed until it fails having not consumed input. All of the results generated by the successful parses are then combined in a right-to-left fashion using the function
op
. If this parser does fail at any point having consumed input, this combinator will fail.- op
function to apply to each value produced by this parser, starting from the right.
- returns
a parser which parses this parser some times and folds the results together with
op
right-associatively.
stmt.reduceRight(Seq(_, _))
- Since
2.3.0
Example: -
def
reduceRightOption[B >: A](op: (A, B) ⇒ B): Parsley[Option[B]]
This combinator will parse this parser zero or more times combining the results right-associatively with the function
op
.This combinator will parse this parser zero or more times combining the results right-associatively with the function
op
.This parser will continue to be parsed until it fails having not consumed input. If this parser succeeded at least once, all of the results generated by the successful parses are then combined in a right-to-left fashion using the function
op
and returned in aSome
. If no successful parses occurred, thenNone
is returned. If this parser does fail at any point having consumed input, this combinator will fail.- op
function to apply to each value produced by this parser, starting from the right.
- returns
a parser which parses this parser many times and folds the results together with
op
right-associatively or returns None if no parses occured.
arg.reduceRightOption(Sep(_, _))
- Since
2.3.0
Example: -
def
toString(): String
- Definition Classes
- Any
-
def
unsafe(): Parsley[A]
Using this method signifies that the parser it is invoked on is impure and any optimisations which assume purity are disabled.
-
def
void: Parsley[Unit]
Replaces the result of this parser with
()
.Replaces the result of this parser with
()
.This combinator is useful when the result of this parser is not required, and the type must be
Parsley[Unit]
. Functionally the same asthis #> ()
.- returns
a new parser that behaves the same as this parser, but always returns
()
on success.
-
def
withFilter(pred: (A) ⇒ Boolean): Parsley[A]
This is an alias for
p.filter(pred)
.This is an alias for
p.filter(pred)
. It is needed to support for-comprehension syntax withif
s.- Since
4.0.0
- See also
filter
for more information.
-
def
zip[B](q: ⇒ Parsley[B]): Parsley[(A, B)]
This combinator first parses this parser then parses
q
: if both succeed the result of this parser is paired with the result ofq
.This combinator first parses this parser then parses
q
: if both succeed the result of this parser is paired with the result ofq
.First, this parser is ran, yielding
x
on success, thenq
is ran, yieldingy
on success. If both are successful then(x, y)
is returned. If either fail then the entire combinator fails.- q
the parser to run second.
- returns
a parser that sequences this parser with
q
and pairs their results together.
scala> import parsley.character.char scala> val p = char('a').zip(char('b')) scala> p.parse("ab") val res0 = Success(('a', 'b')) scala> p.parse("b") val res1 = Failure(..) scala> p.parse("a") val res2 = Failure(..)
- Since
2.3.0
- Note
alias for
<~>
.
Example: -
def
|[Aʹ >: A](q: Parsley[Aʹ]): Parsley[Aʹ]
This combinator, pronounced "or", parses
q
if this parser fails without consuming input.This combinator, pronounced "or", parses
q
if this parser fails without consuming input.If this parser is successful, then this combinator is successful and no further action is taken. Otherwise, if this parser fails without consuming input, then
q
is parsed instead. If this parser fails having consumed input, this combinator fails.The reason for this behaviour is that it prevents space leaks and improves error messages. If this behaviour is not desired, use
attempt(this)
to rollback any input consumed on failure.- Aʹ
the type returned by
q
, which must be a supertype of the result type of this parser: this allows for weakening of the result type.- q
the parser to run if this parser fails having not consumed input.
- returns
a parser which either parses this parser or parses
q
.
scala> import parsley.character.string scala> val p = string("a") | string("b") scala> p.parse("a") val res0 = Success("a") scala> p.parse("b") val res1 = Success("b") scala> val q = string("ab") | string("ac") scala> q.parse("ac") val res2 = Failure(..) // first parser consumed an 'a'!
- Since
4.0.0
- Note
just an alias for
<|>
.
Example: -
def
~>[B](q: ⇒ Parsley[B]): Parsley[B]
This combinator, pronounced "then", first parses this parser then parses
q
: if both succeed then the result ofq
is returned.This combinator, pronounced "then", first parses this parser then parses
q
: if both succeed then the result ofq
is returned.First, this parser is ran, yielding
x
on success, thenq
is ran, yieldingy
on success. If both are successful theny
is returned andx
is ignored. If either fail then the entire combinator fails.Identical to
*>
:*>
is more common in Haskell, whereas~>
is more common in Scala.- q
the parser to run second, which returns the result of this combinator.
- returns
a parser that sequences this parser with
q
and returnsq
's result.
scala> import parsley.character.char scala> ('a' ~> 'b').parse("ab") val res0 = Success('b')
- Since
2.4.0
Example:
Running Parsers
These methods allow for a parser to be executed.
Result Changing Combinators
These combinators change the result of the parser they are called on into a value of a different type. This new result value may or may not be derived from the previous result.
Branching Combinators
These combinators allow for parsing one alternative or another. All of these combinators are left-biased, which means that the left-hand side of the combinator is tried first: the right-hand side of the combinator will only be tried when the left-hand one failed (and did not consume input in the process).
Sequencing Combinators
These combinators all combine two parsers in sequence. The receiver of the combinator will be executed first, then the argument second. The results of both parsers are combined in some way (depending on the individual combinator). If one of the parsers fails, the combinator as a whole fails.
Filtering Combinators
These combinators perform filtering on the results of a parser. This means that, given the result of a parser, they will perform some function on that result, and the success of that function effects whether or not the parser fails.
Folding Combinators
These combinators repeatedly execute a parser (at least zero or one times depending on
the specific combinator) until it fails. The results of the successes are then combined
together using a folding function. An initial value for the accumulation may be given
(for the fold
s), or the first successful result is the initial accumulator (for the
reduce
s). These are implemented efficiently and do not need to construct any intermediate
list with which to store the results.
Expensive Sequencing Combinators
These combinators can sequence two parsers, where the first parser's result influences the structure of the second one. This may be because the second parser is generated from the result of the first, or that the first parser returns the second parser. Either way, the second parser cannot be known until runtime, when the first parser has been executed: this means that Parsley is forced to compile the second parser during parse-time, which is very expensive to do repeatedly. These combinators are only needed in exceptional circumstances, and should be avoided otherwise.
Special Methods
These are methods that should be rarely needed.
This is the documentation for Parsley.
Package structure
The parsley package contains the
Parsley
class, as well as theResult
,Success
, andFailure
types. In addition to these, it also contains the following packages and "modules" (a module is defined as being an object which mocks a package):parsley.Parsley
contains the bulk of the core "function-style" combinators.parsley.combinator
contains many helpful combinators that simplify some common parser patterns.parsley.character
contains the combinators needed to read characters and strings, as well as combinators to match specific sub-sets of characters.parsley.debug
contains debugging combinators, helpful for identifying faults in parsers.parsley.extension
contains syntactic sugar combinators exposed as implicit classes.parsley.io
contains extension methods to run parsers with input sourced from IO sources.parsley.expr
contains the following sub modules:parsley.expr.chain
contains combinators used in expression parsingparsley.expr.precedence
is a builder for expression parsers built on a precedence table.parsley.expr.infix
contains combinators used in expression parsing, but with more permissive types than their equivalents inchain
.parsley.expr.mixed
contains combinators that can be used for expression parsing, but where different fixities may be mixed on the same level: this is rare in practice.parsley.implicits
contains several implicits to add syntactic sugar to the combinators. These are sub-categorised into the following sub modules:parsley.implicits.character
contains implicits to allow you to use character and string literals as parsers.parsley.implicits.combinator
contains implicits related to combinators, such as the ability to make any parser into aParsley[Unit]
automatically.parsley.implicits.lift
enables postfix application of the lift combinator onto a function (or value).parsley.implicits.zipped
enables boths a reversed form of lift where the function appears on the right and is applied on a tuple (useful when type inference has failed) as well as a.zipped
method for building tuples out of several combinators.parsley.errors
contains modules to deal with error messages, their refinement and generation.parsley.errors.combinator
provides combinators that can be used to either produce more detailed errors as well as refine existing errors.parsley.errors.tokenextractors
provides mixins for common token extraction strategies during error message generation: these can be used to avoid implementingunexpectedToken
in theErrorBuilder
.parsley.lift
contains functions which lift functions that work on regular types to those which now combine the results of parsers returning those same types. these are ubiquitous.parsley.ap
contains functions which allow for the application of a parser returning a function to several parsers returning each of the argument types.parsley.registers
contains combinators that interact with the context-sensitive functionality in the form of registers.parsley.token
contains theLexer
class that provides a host of helpful lexing combinators when provided with the description of a language.parsley.genericbridges
contains some basic implementations of the Parser Bridge pattern (see Design Patterns for Parser Combinators in Scala, or the parsley wiki): these can be used before more specialised generic bridge traits can be constructed.