あなたは "パーサー。^?" を使用することができます演算子を使用して、重複する要素の解析要素のグループをチェックします。ここで
def tokens = tokenA | tokenB | tokenC
def uniqueTokens = (tokens*) ^? (
{ case t if (t == t.removeDuplicates) => t },
{ "duplicate tokens found: " + _ })
は、あなたが任意の順序で4人の大将のいずれかを入力することができますが、重複が発生した場合の解析に失敗した例です。
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クラスのリンク" due:next tuesdayのように見えるかもしれないので、scalaスタイルで定義されたジェネリックルールは "token = alphanum〜 ':'〜repsep(alphanum、 '')のようなものです。しかし、私は特定のプロパティを別々に扱う必要があります。 –
あなたは、同じものが2回以上出現しないことを確認しなければなりませんか? – ziggystar
それは計画ですが、一部のプロパティはオプションであり、一度だけ発生する必要があります。 –