Skip to content

Instantly share code, notes, and snippets.

@eamelink
Created January 29, 2013 10:28
Show Gist options
  • Save eamelink/4663332 to your computer and use it in GitHub Desktop.
Save eamelink/4663332 to your computer and use it in GitHub Desktop.
Scala 'rep' parser combinators that cascade 'Error's. The regular ones swallow any error that are not in the first repetition.
trait ErrorReps {
// Copied and adapted from Scala 2.10.0
def repErr[T](p: => Parser[T]): Parser[List[T]] = rep1Err(p) | success(List())
def rep1Err[T](p: => Parser[T]): Parser[List[T]] = rep1Err(p, p)
def rep1Err[T](first: => Parser[T], p0: => Parser[T]): Parser[List[T]] = Parser { in =>
lazy val p = p0 // lazy argument
val elems = new ListBuffer[T]
def continue(in: Input): ParseResult[List[T]] = {
val p0 = p // avoid repeatedly re-evaluating by-name parser
@tailrec def applyp(in0: Input): ParseResult[List[T]] = p0(in0) match {
case Success(x, rest) => elems += x ; applyp(rest)
case Failure(_, _) => Success(elems.toList, in0)
case Error(msg, _) => Error(msg, in0)
}
applyp(in)
}
first(in) match {
case Success(x, rest) => elems += x ; continue(rest)
case ns: NoSuccess => ns
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment