これは、あなたがやろうとしていることの本当に簡単な実装です:
まず、式の階層を定義します。これを特定の問題に合わせて調整する必要があります。
trait Expr {
def eval: Int
}
case class IntLeaf(n: Int) extends Expr {
def eval = n
override def toString = "%d".format(n)
}
case class Sum(a: Expr, b: Expr) extends Expr {
def eval = a.eval + b.eval
override def toString = "(%s + %s)".format(a, b)
}
そして、一番下の枝だけを組み合わせる機能。
def combineLeaves(e: Expr): Expr = {
e match {
case IntLeaf(n) => IntLeaf(n)
case Sum(IntLeaf(a), IntLeaf(b)) => IntLeaf(a + b)
case Sum(a, b) => Sum(combineLeaves(a), combineLeaves(b))
}
}
次に、ツリーを一度に 1 レベルずつ結合し、その都度印刷する関数。
def printEval(e: Expr) {
println(e)
e match {
case IntLeaf(n) =>
case _ => printEval(combineLeaves(e))
}
}
さて、パーサー。繰り返しますが、これをデータに合わせて調整する必要があります。
object ArithmeticParser extends RegexParsers {
private def int: Parser[IntLeaf] = regex(new Regex("""\d+""")).map(s => IntLeaf(s.toInt))
private def sum: Parser[Sum] = ("(" ~> expr ~ "+" ~ expr <~ ")").map { case (a ~ _ ~ b) => Sum(a, b) }
private def expr = int | sum
def parse(str: String): ParseResult[Expr] = parseAll(expr, str)
def apply(str: String): Expr = ArithmeticParser.parse(str) match {
case ArithmeticParser.Success(result: Expr, _) => result
case _ => sys.error("Could not parse the input string: " + str)
}
}
そして、これを使用する方法は次のとおりです。
scala> printEval(ArithmeticParser("((1 + 7) + ((3 + 9) + 5))"))
((1 + 7) + ((3 + 9) + 5))
(8 + (12 + 5))
(8 + 17)
25