您可以使用 “解析器。^?”运算符来检查一组解析元素是否有重复。
def tokens = tokenA | tokenB | tokenC
def uniqueTokens = (tokens*) ^? (
{ case t if (t == t.removeDuplicates) => t },
{ "duplicate tokens found: " + _ })
下面是一个例子,可以让你按任意顺序输入任何四个臭皮匠,但失败如果遇到重复解析:
package blevins.example
import scala.util.parsing.combinator._
case class Stooge(name: String)
object StoogesParser extends RegexParsers {
def moe = "Moe".r
def larry = "Larry".r
def curly = "Curly".r
def shemp = "Shemp".r
def stooge = (moe | larry | curly | shemp) ^^ { case s => Stooge(s) }
def certifiedStooge = stooge | """\w+""".r ^? (
{ case s: Stooge => s },
{ "not a stooge: " + _ })
def stooges = (certifiedStooge*) ^? (
{ case x if (x == x.removeDuplicates) => x.toSet },
{ "duplicate stooge in: " + _ })
def parse(s: String): String = {
parseAll(stooges, new scala.util.parsing.input.CharSequenceReader(s)) match {
case Success(r,_) => r.mkString(" ")
case Failure(r,_) => "failure: " + r
case Error(r,_) => "error: " + r
}
}
}
和一些用法示例:
package blevins.example
object App extends Application {
def printParse(s: String): Unit = println(StoogesParser.parse(s))
printParse("Moe Shemp Larry")
printParse("Moe Shemp Shemp")
printParse("Curly Beyonce")
/* Output:
Stooge(Moe) Stooge(Shemp) Stooge(Larry)
failure: duplicate stooge in: List(Stooge(Moe), Stooge(Shemp), Stooge(Shemp))
failure: not a stooge: Beyonce
*/
}
在这种情况下,每个标记都是json样式的对象属性。因此,一个命令可能看起来像是“todo message:将Todo类链接到数据库”,因为:next tuesday“。因此,在scala风格中定义的通用规则类似于”token = alphanum〜':'〜repsep(alphanum,'')。但我确实需要以不同的方式处理特定的属性。 –
你必须确定,同一个不会出现一次以上? – ziggystar
是的,这是计划,一些属性是可选的,他们应该只出现一次。 –