Skip to content

Instantly share code, notes, and snippets.

@etluchs
Created April 6, 2012 21:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save etluchs/2322986 to your computer and use it in GitHub Desktop.
Save etluchs/2322986 to your computer and use it in GitHub Desktop.
Completing Parser Trait
import util.parsing.combinator.RegexParsers
/**
* A trait to make parsers for string literals return a nice list of possible completions if
* we're at the end of the input.
*
* @author Marcus Schulte
*/
trait CompletingParser extends RegexParsers {
/**
* A `Failure` which is curable by adding one of several possible completions.
*
* @param completions what would make the parser succeed if added to `in`.
* @param next the input about to be read
*/
case class MissingCompletionOrFailure( val completions: List[String],
override val msg: String,
override val next: Input )
extends Failure( msg, next ) {
override def append[U](a: => ParseResult[U]) = a match {
case MissingCompletionOrFailure( newCompletions, _, _ )
=> val comps = completions ++ newCompletions;
new MissingCompletionOrFailure( comps,
if (comps.isEmpty) msg else "expected one of " + comps,
next )
case ns: NoSuccess => this
case s: Success[U] => s
}
}
override implicit def literal( s: String ) : Parser[String] =new Parser[String] {
def apply(in: Input) = {
val source = in.source
val offset = in.offset
val start = handleWhiteSpace(source, offset)
var i = 0
var j = start
while (i < s.length && j < source.length && s.charAt(i) == source.charAt(j)) {
i += 1
j += 1
}
if (i == s.length)
Success(source.subSequence(start, j).toString, in.drop(j - offset))
else if (j == source.length()) {
val missing = s.substring(i)
MissingCompletionOrFailure( List(missing), "expected one of "+missing, in.drop(start - offset) )
} else {
MissingCompletionOrFailure( List(), "`"+s+"' expected but "+source.charAt(j)+" found", in.drop(start - offset))
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment