扩展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
不匹配action
的GET
或SET
?
JavaTokenParser
为RegexParsers
添加了一些方法,但它不改变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