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

Grouped members

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.

Value parameters

input

The input to run against

Attributes

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

Value parameters

x

the new result of this parser.

Attributes

Returns

a new parser that behaves the same as this parser, but always succeeds with x as the result.

Note

just an alias for as.

Example

scala> import parsley.character.string
scala> (string("true") #> true).parse("true")
val res0 = Success(true)
Source
Parsley.scala
def as[B](x: B): Parsley[B]

This combinator replaces the result of this parser, ignoring the old result.

This combinator 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 ($>).

Value parameters

x

the new result of this parser.

Attributes

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").as(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 (<$>).

Value parameters

f

the function to apply to the result of the parse

Attributes

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

This combinator ignores the result of this parser and instead returns the input parsed by it.

This combinator ignores the result of this parser and instead returns the input parsed by it.

This combinator executes this parser: if it fails, this combinator fails. Otherwise, if this parser succeeded, its result is discarded and the input it consumed in the process of parsing is returned directly. This can be used to efficiently obtain the underlying string of some parser without having to reconstruct it. One potential application is to suppress complex results of things within the Lexer without having to re-implement its functionality. However, it should be used judiciously.

Attributes

Returns

a parser which returns the parsed input directly.

Since

4.4.0

Source
Parsley.scala
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 as this.as(()).

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.

Value parameters

q

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

Attributes

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.

Value parameters

q

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

Attributes

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.

Value parameters

pf

the parser to run second, which returns a function this parser's result can be applied to.

Attributes

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 = atomic(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.

Value parameters

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.

Attributes

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('+').as(identity[Int] _) <|> char('-').as(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ʹ >: 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 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.

Type parameters

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.

Value parameters

ps

the parser to run second, which returns a sequence.

Attributes

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ʹ >: 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 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.

Type parameters

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.

Value parameters

ps

the parser to run second, which returns a list.

Attributes

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.

Value parameters

q

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

Attributes

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.

Value parameters

q

the parser to run second.

Attributes

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.

Value parameters

q

the parser to run second.

Attributes

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.

Value parameters

q

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

Attributes

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 atomic(this) to rollback any input consumed on failure.

Value parameters

q

the parser to run if this parser fails having not consumed input.

Attributes

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ʹ >: 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 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 atomic(this) to rollback any input consumed on failure.

Type parameters

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.

Value parameters

x

the value to return if this parser fails having not consumed input.

Attributes

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ʹ >: 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 atomic(this) to rollback any input consumed on failure.

Type parameters

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.

Value parameters

q

the parser to run if this parser fails having not consumed input.

Attributes

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 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 atomic(this) to rollback any input consumed on failure.

Type parameters

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.

Value parameters

q

the parser to run if this parser fails having not consumed input.

Attributes

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ʹ >: 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 atomic(this) to rollback any input consumed on failure.

Type parameters

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.

Value parameters

q

the parser to run if this parser fails having not consumed input.

Attributes

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.

Value parameters

f

function to apply to each iteration's accumulator.

k

initial accumulation value.

Attributes

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.

Value parameters

f

function to apply to each iteration's accumulator.

k

initial accumulation value.

Attributes

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.

Value parameters

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.

Attributes

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.

Value parameters

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.

Attributes

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.

Value parameters

op

function to apply to each value produced by this parser, starting from the left.

Attributes

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.

Value parameters

op

function to apply to each value produced by this parser, starting from the left.

Attributes

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.

Value parameters

op

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

Attributes

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.

Value parameters

op

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

Attributes

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.

Value parameters

pf

the partial function used to both filter the result of this parser and transform it.

Attributes

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.

Value parameters

pred

the predicate that is tested against the parser result.

Attributes

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.

Value parameters

pred

the predicate that is tested against the parser result.

Attributes

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.

Value parameters

f

the function used to both filter the result of this parser and transform it.

Attributes

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

Value parameters

f

the function that produces the next parser.

Attributes

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.

Value parameters

ev

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

Attributes

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
def impure: Parsley[A]

This combinator signifies that the parser it is invoked on is impure and any optimisations which assume purity are disabled.

This combinator signifies that the parser it is invoked on is impure and any optimisations which assume purity are disabled.

Attributes

Example

Any parsers that make use of mutable state may need to use this combinator to control parsley's aggressive optimisations that remove results that are not needed: in this case, the optimiser cannot see that the result of a parser is mutating some value, and may remove it.

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

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

Value members

Concrete methods

def parseFile[Err : ErrorBuilder](file: File)(implicit evidence$1: ErrorBuilder[Err], codec: Codec): Try[Result[Err, A]]
Implicitly added by ParseFromIO

This method executes a parser, but collects the input to the parser from the given file.

This method executes a parser, but collects the input to the parser from the given file.

The file name is used to annotate any error messages. The result of this method handles exceptions and ensures the file has been properly closed.

Value parameters

codec

the encoding of the file.

file

the file to load and run against.

Attributes

Returns

a Try containing a result of either a success with a value of type A or a failure with error message on success, and a failure if an IOException occured.

Since

4.5.0

Source
PlatformSpecific.scala
def unary_~: Parsley[A]
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 sequence combinator, for instance: p <::> sequence(q, .., r) will ensure that the sequence 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 = (atomic(term) <* '+', ~expr).zipped(_ + _) <|> term
// in this case, however, the following would fix the problem more elegantly:
lazy val expr = (atomic(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