Это анализирует два приведенных вами примера:
import scala.util.parsing.combinator.syntactical._
sealed abstract class Expr
case class ValueNode(value:String) extends Expr
case class ValueListNode(value:List[Expr]) extends Expr
object GroupParser extends StandardTokenParsers {
lexical.delimiters ++= List("{","}")
def vstring = ident ^^ { case s => ValueNode(s) }
def parens:Parser[Expr] = "{" ~> ( expr ) <~ "}"
def expr = vstring | parens
def exprList:Parser[Expr] = "{" ~> rep1( expr | exprList ) <~ "}" ^^ {
case l => {
ValueListNode(l)
}
}
def anyExpr = expr | exprList
def parse(s:String) = {
val tokens = new lexical.Scanner(s)
phrase(anyExpr)(tokens)
}
def test(s: String) = {
parse(s) match {
case Success(tree, _) =>
println("Tree: " + tree)
case e: NoSuccess => Console.err.println(e)
}
}
def main(args: Array[String]) = {
test("{a}")
test("{{a}}")
test("{{a}{{b}{c}}}")
}
}
И успешно с выводом:
Tree: ValueNode(a)
Tree: ValueNode(a)
Tree: ValueListNode(List(ValueNode(a), ValueListNode(List(ValueNode(b), ValueNode(c)))))