使用 scala packrat 解析器解析一个简单的字符串

Parsing a simple string with a scala packrat parser

我正在尝试使用 scala 的解析器组合器解析字符串,如下所示:

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

}

我认为这应该会成功,因为 Packrat 解析器会回溯,所以 "water" 最终会匹配 "something here"。

但是,似乎 "water" 匹配的是 "something here end"。我原以为它不应该这样做。有办法解决吗?

为什么packrat解析器不回溯,请看这篇this SO question。也就是说,获得您想要的东西的一种方法如下:

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

主要思想是在指定单词之间的分隔符时使用not。只有当它不是 end 时,words 解析器才会成功。否则,program 解析器继续。