1

I'm trying to parse a string using scala's parser combinators like this:

import scala.util.parsing.combinator._
import scala.util.parsing.input.CharSequenceReader

object TestPackratParser extends RegexParsers with PackratParsers {

  lazy val program: PackratParser[Any] = "start" ~ water ~ "end" ^^ (_ => println("program"))

  lazy val water: PackratParser[Any] = (""".""".r).* ^^ (_ => println("water"))

  def main(args: Array[String]) {
    parseAll(phrase(program), new PackratReader(new CharSequenceReader("start something here end")))
  }

}

I think this should be successful because a packrat parser backtracks, so "water" will eventually match "something here".

However, it seems that "water" is matching "something here end" instead. I would have thought it shouldn't do this. Is there a way to fix it?

1 Answer 1

2

As for why the packrat parser does not backtrack, please see this this SO question. Said that, one way to get what you want would be the following:

object TestPackratParser extends RegexParsers with PackratParsers {

  override val skipWhitespace = false

  lazy val ws = """\s+""".r

  lazy val program: PackratParser[Any] = "start" ~ ws ~ water ~ ws ~ "end" ^^ (_ => println("program"))

  lazy val water: PackratParser[Any] =  words ^^ (_ => println("water"))

  val words = repsep("""\w+""".r,  ws ~ not("end") ^^ { case _ => ""})

  def main(args: Array[String]) {
    parseAll(phrase(program), new PackratReader(new CharSequenceReader("start something here end")))
  }
}

The main idea is to use not when specifying the separator between words. Only if it's not end the words parser succeeds. Otherwise, the program parser continues.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! I'm going to look at applying your type of solution to the bigger problem I had. For anyone checking back on this, I also found the GLL combinators linked to in the other SO question very useful and they were able to handle this problem too.
Your parsing code is great. Do you have any gists / github /etc so i can see some of your other work?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.