在JavaTokenParsers中将Whitespace设置为分隔符

时间:2014-07-14 21:16:14

标签: scala parsing

扩展JavaTokenParsers,我有以下内容:

class Foo extends JavaTokenParsers { 
  lazy val check = id ~ action ~ obj

  lazy val id     = "FOO" | "BAR"
  lazy val action = "GET" | "SET"
  lazy val obj = "BAZ" | "BIZ"
}

我曾假设空格会作为分隔符。换句话说,当check成功解析以下表达式时,我感到困惑:FOO GETBAZ

val result = parseAll(check, "FOO GETBAZ")
println(result.get)

结果

  

((FOO〜GET)〜BAZ)

如何将空格用作delimiter,即上述不会成功解析,因为GETBAZaction&{39} {{1}不匹配}或GET

2 个答案:

答案 0 :(得分:1)

JavaTokenParserRegexParsers添加了一些方法,但它不会改变literal的行为,它会匹配其参数而不用担心它周围的内容。

skipWhitespace设置也不会对您有所帮助,因为它只指定是否忽略空格 - 而不是是否需要空格。

你有几个选择。一种方法是使用带有字边界的正则表达式:

class Foo extends JavaTokenParsers {
  def word(s: String): Parser[String] = regex(s"\\b$s\\b".r)

  lazy val check = id ~ action ~ obj    

  val id     = word("FOO") | word("BAR")
  val action = word("GET") | word("SET")
  val obj    = word("BAZ") | word("BIZ")
}

ident

class Foo extends JavaTokenParsers {
  def word(s: String): Parser[String] = ident.filter(_ == s)

  lazy val check = id ~ action ~ obj    

  val id     = word("FOO") | word("BAR")
  val action = word("GET") | word("SET")
  val obj    = word("BAZ") | word("BIZ")
}

或者您可以在每个项目之间手动添加空白解析器。

我可能会选择\b解决方案,但这主要取决于品味和偏好。

答案 1 :(得分:0)

覆盖def skipWhitespace方法:

object Foo extends JavaTokenParsers { 
  lazy val check = id ~ action ~ obj
  lazy val id     = "FOO" | "BAR"
  lazy val action = "GET" | "SET"
  lazy val obj =  "BAZ" | "BIZ"
  override def skipWhitespace() = false
}

请参阅:

scala> Foo.parseAll(Foo.check, "FOOGETBAZ").isEmpty
res0: Boolean = false

scala> Foo.parseAll(Foo.check, "FOOGET BAZ").isEmpty
res1: Boolean = true