使用 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
解析器继续。
我正在尝试使用 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
解析器继续。