The following is not exactly how your rep1sepDependent , but it works:
def rep1sepUnique[T](p: => Parser[T], q: => Parser[Any]) = { def checkIfSeen(seen: Set[T]): Parser[Set[T]] = q ~> p >> (v => if (seen(v)) failure("Duplicate: %s".format(v)) else checkIfSeen(seen + v) ) | success(seen) p >> (v => checkIfSeen(Set(v))) }
For instance:
import scala.util.parsing.combinator._ object parseUniqueWords extends RegexParsers { def rep1sepUnique[T](p: => Parser[T], q: => Parser[Any]) = { def checkIfSeen(seen: Set[T]): Parser[Set[T]] = q ~> p >> (v => if (seen(v)) failure("Duplicate: %s".format(v)) else checkIfSeen(seen + v) ) | success(seen) p >> (v => checkIfSeen(Set(v))) } def apply(s: String) = parseAll(rep1sepUnique("\\w+".r, ","), s) }
What gives us:
scala> parseUniqueWords("aaa,bb,c") res0: parseUniqueWords.ParseResult[Set[String]] = [1.9] parsed: Set(aaa, bb, c) scala> parseUniqueWords("aaa,bb,aaa") res1: parseUniqueWords.ParseResult[Set[String]] = [1.11] failure: Duplicate: aaa aaa,bb,aaa ^
This is what we want.
source share