Parsley

parsley.Parsley
See theParsley companion object
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.

Attributes

Version:

4.0.0

Note:

In order to construct an object of this class you must use the combinators; the class itself is opaque.

Companion:
object
Source:
Parsley.scala
Graph
Supertypes
class AnyVal
trait Matchable
class Any

Members list

Concise view

Running Parsers

These methods allow for a parser to be executed.

def parse[Err : ErrorBuilder](input: String): 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 a Failure.

Attributes

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

Source:
Parsley.scala

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.

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 as this *> pure(x) or this.map(_ => x).

In Haskell, this combinator is known as ($>).

Attributes

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.

Example:

scala> import parsley.character.string
scala> (string("true") #> true).parse("true")
val res0 = Success(true)
Source:
Parsley.scala
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 function f, 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 (<$>).

Attributes

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.

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 the unsafe method before map; p.unsafe.map(f).

Example:

scala> import parsley.character.digit
scala> digit.map(_.asDigit).parse("7")
val res0 = Success(7)
Source:
Parsley.scala

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 as this #> ().

Attributes

Returns:

a new parser that behaves the same as this parser, but always returns () on success.

Source:
Parsley.scala

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.

def *>[B](q: => Parsley[B]): Parsley[B]

This combinator, pronounced "then", first parses this parser then parses q: if both succeed then the result of q is returned.

This combinator, pronounced "then", first parses this parser then parses q: if both succeed then the result of q is returned.

First, this parser is ran, yielding x on success, then q is ran, yielding y on success. If both are successful then y is returned and x is ignored. If either fail then the entire combinator fails.

Identical to ~>: *> is more common in Haskell, whereas ~> is more common in Scala.

Attributes

q

the parser to run second, which returns the result of this combinator.

Returns:

a parser that sequences this parser with q and returns q's result.

Example:

scala> import parsley.character.char
scala> ('a' *> 'b').parse("ab")
val res0 = Success('b')
Source:
Parsley.scala
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, then q is ran, yielding y on success. If both are successful then x is returned and y is ignored. If either fail then the entire combinator fails.

Identical to <~: <* is more common in Haskell, whereas <~ is more common in Scala.

Attributes

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.

Example:

scala> import parsley.character.char
scala> ('a' <* 'b').parse("ab")
val res0 = Success('a')
Source:
Parsley.scala
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 by pf.

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 by pf.

First, this parser is ran, yielding a value x on success, then pf is ran, yielding a function f on success. If both are successful, then f(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.

Attributes

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.

Note:

equivalent to

lift2((x, f) => f(x), this, pf)
Example:

// 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] _))
Source:
Parsley.scala
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 by px.

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 by px.

The implicit (compiler-provided) evidence proves that this parser really has type Parsley[B => C]. First, this parser is ran, yielding a function f on success, then px is ran, yielding a value x on success. If both are successful, then f(x) is returned. If either fail then the entire combinator fails.

Attributes

ev

witnesses that the type of this parser, A, is actually B => C.

px

the parser to run second, which returns a value applicable to this parser's result.

Returns:

a parser that sequences this parser with px and combines their results with function application.

Note:

equivalent to lift2((f, x) => f(x), this, px).

Example:

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
Source:
Parsley.scala
def <+:>[ >: A](ps: => Parsley[Seq[]]): Parsley[Seq[]]

This combinator, pronounced "prepend", first parses this parser then parses ps: if both succeed the result of this parser is prepended onto the result of ps.

This combinator, pronounced "prepend", first parses this parser then parses ps: if both succeed the result of this parser is prepended onto the result of ps.

First, this parser is ran, yielding x on success, then ps is ran, yielding xs on success. If both are successful then x +: xs is returned. If either fail then the entire combinator fails.

Attributes

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 onto ps result.

Note:

equivalent to

lift2(_ +: _, this, ps)
Example:

def some[A](p: Parsley[A]): Parsley[List[A]] = {
   p <+:> many(p) // since List[A] <: Seq[A]
}
Source:
Parsley.scala
def <::>[ >: A](ps: => Parsley[List[]]): Parsley[List[]]

This combinator, pronounced "cons", first parses this parser then parses ps: if both succeed the result of this parser is prepended onto the result of ps.

This combinator, pronounced "cons", first parses this parser then parses ps: if both succeed the result of this parser is prepended onto the result of ps.

First, this parser is ran, yielding x on success, then ps is ran, yielding xs on success. If both are successful then x :: xs is returned. If either fail then the entire combinator fails.

Attributes

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 onto ps result.

Note:

equivalent to

lift2(_ :: _, this, ps)
Example:

def some[A](p: Parsley[A]): Parsley[List[A]] = {
   p <::> many(p)
}
Source:
Parsley.scala
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, then q is ran, yielding y on success. If both are successful then x is returned and y is ignored. If either fail then the entire combinator fails.

Identical to <*: <* is more common in Haskell, whereas <~ is more common in Scala.

Attributes

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.

Since:

2.4.0

Example:

scala> import parsley.character.char
scala> ('a' <~ 'b').parse("ab")
val res0 = Success('a')
Source:
Parsley.scala
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 of q.

This combinator, pronounced "zip", first parses this parser then parses q: if both succeed the result of this parser is paired with the result of q.

First, this parser is ran, yielding x on success, then q is ran, yielding y on success. If both are successful then (x, y) is returned. If either fail then the entire combinator fails.

Attributes

q

the parser to run second.

Returns:

a parser that sequences this parser with q and pairs their results together.

Note:

equivalent to

lift2((_, _), this, q)
Example:

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(..)
Source:
Parsley.scala
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 of q.

This combinator first parses this parser then parses q: if both succeed the result of this parser is paired with the result of q.

First, this parser is ran, yielding x on success, then q is ran, yielding y on success. If both are successful then (x, y) is returned. If either fail then the entire combinator fails.

Attributes

q

the parser to run second.

Returns:

a parser that sequences this parser with q and pairs their results together.

Since:

2.3.0

Note:

alias for <~>.

Example:

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(..)
Source:
Parsley.scala
def ~>[B](q: => Parsley[B]): Parsley[B]

This combinator, pronounced "then", first parses this parser then parses q: if both succeed then the result of q is returned.

This combinator, pronounced "then", first parses this parser then parses q: if both succeed then the result of q is returned.

First, this parser is ran, yielding x on success, then q is ran, yielding y on success. If both are successful then y is returned and x is ignored. If either fail then the entire combinator fails.

Identical to *>: *> is more common in Haskell, whereas ~> is more common in Scala.

Attributes

q

the parser to run second, which returns the result of this combinator.

Returns:

a parser that sequences this parser with q and returns q's result.

Since:

2.4.0

Example:

scala> import parsley.character.char
scala> ('a' ~> 'b').parse("ab")
val res0 = Success('b')
Source:
Parsley.scala

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).

def <+>[B](q: Parsley[B]): Parsley[Either[A, B]]

This combinator, pronounced "sum", wraps this parser's result in Left if it succeeds, and parses q if it failed without consuming input, wrapping the result in Right.

This combinator, pronounced "sum", wraps this parser's result in Left if it succeeds, and parses q if it failed without consuming input, wrapping the result in Right.

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, then q is parsed instead and its result is wrapped up using Right(_). If this parser fails having consumed input, this combinator fails. This is functionally equivalent to this.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.

Attributes

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 an Either[A, B].

Example:

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'!
Source:
Parsley.scala
def </>[ >: A](x: ): Parsley[]

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 as this <|> 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.

Attributes

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.

Example:

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'!
Source:
Parsley.scala
def <|>[ >: A](q: Parsley[]): Parsley[]

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.

Attributes

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.

Example:

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'!
Source:
Parsley.scala
def getOrElse[ >: A](x: ): Parsley[]

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 as this <|> 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.

Attributes

Note:

just an alias for </>

Example:

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'!
Source:
Parsley.scala
def orElse[ >: A](q: Parsley[]): Parsley[]

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.

Attributes

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.

Since:

4.0.0

Note:

just an alias for <|>.

Example:

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'!
Source:
Parsley.scala
def |[ >: A](q: Parsley[]): Parsley[]

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.

Attributes

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.

Since:

4.0.0

Note:

just an alias for <|>.

Example:

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'!
Source:
Parsley.scala

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 folds), or the first successful result is the initial accumulator (for the reduces). These are implemented efficiently and do not need to construct any intermediate list with which to store the results.

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 value k from the left.

This combinator will parse this parser zero or more times combining the results with the function f and base value k 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 value k. If this parser does fail at any point having consumed input, this combinator will fail.

Attributes

f

function to apply to each iteration's accumulator.

k

initial accumulation value.

Returns:

a parser which parses this parser many times and folds the results together with f and k left-associatively.

Example:

// this is not an efficient implementation of stringOfMany
def stringOfMany(pc: Parsley[Char]): Parsley[String] = {
   pc.foldLeft("")(_ + _)
}
Source:
Parsley.scala
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 value k from the left.

This combinator will parse this parser one or more times combining the results with the function f and base value k 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 value k. If this parser does fail at any point having consumed input, this combinator will fail.

Attributes

f

function to apply to each iteration's accumulator.

k

initial accumulation value.

Returns:

a parser which parses this parser some times and folds the results together with f and k left-associatively.

Since:

2.1.0

Example:

val natural: Parsley[Int] = digit.foldLeft1(0)((x, d) => x * 10 + d.toInt)
Source:
Parsley.scala
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 value k from the right.

This combinator will parse this parser zero or more times combining the results with the function f and base value k 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 to f is the value k. If this parser does fail at any point having consumed input, this combinator will fail.

Attributes

f

function to apply to each value produced by this parser, starting at the right.

k

value to use when this parser no longer succeeds.

Returns:

a parser which parses this parser many times and folds the results together with f and k right-associatively.

Example:

// in reality, many is implemented more efficiently
def many[A](p: Parsley[A]) = {
   p.foldRight(List.empty[A])(_ :: _)
}
Source:
Parsley.scala
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 value k from the right.

This combinator will parse this parser one or more times combining the results with the function f and base value k 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 to f is the value k. If this parser does fail at any point having consumed input, this combinator will fail.

Attributes

f

function to apply to each value produced by this parser, starting at the right.

k

value to use when this parser no longer succeeds.

Returns:

a parser which parses this parser some times and folds the results together with f and k right-associatively.

Since:

2.1.0

Example:

// in reality, some is implemented more efficiently
def some[A](p: Parsley[A]) = {
   p.foldRight1(List.empty[A])(_ :: _)
}
Source:
Parsley.scala
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.

Attributes

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.

Since:

2.3.0

Example:

stmt.reduceLeft(Seq(_, _))
Source:
Parsley.scala
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 a Some. If no successful parses occurred, then None is returned. If this parser does fail at any point having consumed input, this combinator will fail.

Attributes

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.

Since:

2.3.0

Example:

arg.reduceLeftOption(Sep(_, _))
Source:
Parsley.scala
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.

Attributes

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.

Since:

2.3.0

Example:

stmt.reduceRight(Seq(_, _))
Source:
Parsley.scala
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 a Some. If no successful parses occurred, then None is returned. If this parser does fail at any point having consumed input, this combinator will fail.

Attributes

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.

Since:

2.3.0

Example:

arg.reduceRightOption(Sep(_, _))
Source:
Parsley.scala

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.

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 for pf, failing if it is not.

This combinator applies a partial function pf to the result of this parser if its result is defined for pf, failing if it is not.

First, parse this parser. If it succeeds, test whether its result x is in the domain of the partial function pf. If it is defined for pf, return pf(x). If it is undefined, or this parser failed, then this combinator fails. Equivalent to a filter followed by a map.

Attributes

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.

See also:

collectMsg(String, String*) and collectMsg(A => Seq[String]) for versions that can produce custom error messages on failure.

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.

Example:

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)
Source:
Parsley.scala
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 predicate pred. If pred(x) is true, then return x. Otherwise, the combinator fails.

Attributes

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.

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.

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:

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(..)
Source:
Parsley.scala
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 predicate pred. If pred(x) is false, then return x. Otherwise, the combinator fails.

Attributes

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.

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.

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:

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(..)
Source:
Parsley.scala
def mapFilter[B](f: A => Option[B]): Parsley[B]

This combinator applies a function f to the result of this parser: if it returns a Some(y), y is returned, otherwise the parser fails.

This combinator applies a function f to the result of this parser: if it returns a Some(y), y is returned, otherwise the parser fails.

First, parse this parser. If it succeeds, apply the function f to the result x. If f(x) returns Some(y), return y. If f(x) returns None, or this parser failed then this combinator fails. Is a more efficient way of performing a filter and map at the same time.

Attributes

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.

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:

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)
Source:
Parsley.scala

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.

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 function f to produce a new parser f(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.

Attributes

f

the function that produces the next parser.

Returns:

a new parser, which sequences this parser with the parser generated from its result.

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:

// this is an inefficient implementation, but does work
def filter(pred: A => Boolean): Parsley[A] = {
   this >>= { x =>
       if (pred(x)) pure(x)
       else empty
   }
}
Source:
Parsley.scala
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 function f to produce a new parser f(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").

Attributes

f

the function that produces the next parser.

Returns:

a new parser, which sequences this parser with the parser generated from its result.

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:

// 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
   }
}
Source:
Parsley.scala
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 parser p. The parser p is then executed, and its result is returned. If either this parser or p 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.

Attributes

ev

witnesses that the result type of this parser, A, is really Parsley[B].

Returns:

a new parser, which sequences this parser with its result parser.

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:

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 using flatten 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(..)
Source:
Parsley.scala

Special Methods

These are methods that should be rarely needed.

def force(): Unit

Forces the compilation of a parser as opposed to the regular lazy evaluation.

Forces the compilation of a parser as opposed to the regular lazy evaluation.

Attributes

Source:
Parsley.scala

Provides an indicator that this parser will likely stack-overflow and so a stack-safe construction should be used when "compiling" this parser.

Provides an indicator that this parser will likely stack-overflow and so a stack-safe construction should be used when "compiling" this parser.

Attributes

Source:
Parsley.scala
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.

Using this method signifies that the parser it is invoked on is impure and any optimisations which assume purity are disabled.

Attributes

Source:
Parsley.scala

Value members

Concrete methods

Implicitly added by LazyParsley

This combinator makes a parser lazy.

This combinator makes a parser lazy.

There are some combinators that are, due to Scala limitations, strict in all their parameters. Usually, a combinator is strict in its "first position", which is to say the first part of the combinator to be executed; and lazy in all other "positions". The rationale behind this is that recursion appearing in a "first position" will result in infinite recursion at parse-time, it is left-recursive after all, and so it makes little sense to waste efficiency and complicate the API to support laziness there. Since method receivers are strict and only arguments can be lazy under regular conditions, this works well.

However, for combinators that are always strict, this poses a problem: a recursion point inside one of these strict fields will cause an infinite loop at runtime! This can be fixed by ensuring that this becomes part of a lazy argument. This is a solution described by the skip combinator, for instance: p *> skip(q, .., r) will ensure that the skip is in a lazy position in *> meaning that even if any of q to r must be lazy, they can go in the strict positions of skip because the p *> provides the required laziness. However, if this isn't possible (for instance, with the zipped combinators), then how can this problem be solved?

This is the job of the ~ combinator: very simply it wraps up a parser in a lazy box, so that even if the box is forced by a strict position, the parser will remain lazy. This means it serves as an adequate solution to this problem.

Attributes

Returns:

the parser p, but guaranteed to be lazy.

Example:

// this works fine, even though all of `zipped`'s parsers are strict
lazy val expr = (attempt(term) <* '+', ~expr).zipped(_ + _) <|> term
// in this case, however, the following would fix the problem more elegantly:
lazy val expr = (attempt(term), '+' *> expr).zipped(_ + _) <|> term
Source:
Parsley.scala
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 with ifs.

Attributes

See also:

filter for more information.

Since:

4.0.0

Source:
Parsley.scala