在JavaTokenParsers中将空格设置为分隔符



扩展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 ~) ~ BAZ)

我如何使用空格作为delimiter,即上述不会解析成功,因为GETBAZ不匹配actionGETSET ?

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解决方案,但这在很大程度上是一个品味和偏好的问题。

重写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

最新更新