Problem:
ICPC Calculator

In mathematics, we usually specify the order of operations by using
parentheses.
For example, 7 × (3 + 2) always means multiplying 7 by the result of 3 + 2 and never means adding 2 to the result of 7 × 3.

However, there are people who do not like parentheses.
International Counter of Parentheses Council (ICPC) is attempting
to make a notation without parentheses the world standard.
They are always making studies of such no-parentheses notations.

Dr. Tsukuba, a member of ICPC, invented a new parenthesis-free notation.
In his notation, a single expression is represented by multiple
lines, each of which contains an addition operator (+), a
multiplication operator (*) or an integer.
An expression is either a single integer or an operator application to operands.
Integers are denoted in decimal notation in one line.
An operator application is denoted by a line of its operator immediately
followed by lines denoting its two or more operands,
each of which is an expression, recursively.
Note that when an operand is an operator application,
it comprises multiple lines.

As expressions may be arbitrarily nested,
we have to make it clear which operator is applied to which operands.
For that purpose, each of the expressions is given its nesting level.
The top level expression has the nesting level of 0.
When an expression of level n is an operator application,
its operands are expressions of level n + 1.
The first line of an expression starts with a sequence of periods (.),
the number of which indicates the level of the expression.

For example, 2 + 3 in the regular mathematics is denoted as in Figure 1.
An operator can be applied to two or more operands.
Operators + and * represent operations
of summation of all operands and multiplication of all operands,
respectively. For example, Figure 2 shows an expression multiplying
2, 3, and 4.
For a more complicated example, an expression (2 + 3 + 4) × 5 in
the regular mathematics can be expressed as in Figure 3 while (2 + 3) × 4 × 5
can be expressed as in Figure 4.

+
.2
.3

Figure 1: 2 + 3

*
.2
.3
.4

Figure 2: An expression multiplying 2, 3, and 4

*
.+
..2
..3
..4
.5

Figure 3: (2 + 3 + 4) × 5

*
.+
..2
..3
.4
.5

Figure 4: (2 + 3) × 4 × 5

Your job is to write a program that computes the value of expressions
written in Dr. Tsukuba's notation to help him.

Input

The input consists of multiple datasets. Each dataset
starts with a line containing a positive integer n, followed by
n lines denoting a single expression in Dr. Tsukuba's notation.

You may assume that, in the expressions given in the input,
every integer comprises a single digit and that
every expression has no more than nine integers.
You may also assume that all the input expressions are valid
in the Dr. Tsukuba's notation.
The input contains no extra characters, such as spaces or empty lines.

The last dataset is immediately followed by a line with a single zero.

Output

For each dataset, output a single line containing an integer
which is the value of the given expression.

Sample Input

1
9
4
+
.1
.2
.3
9
+
.0
.+
..*
...1
...*
....1
....2
..0
10
+
.+
..6
..2
.+
..1
..*
...7
...6
.3
0

Output for the Sample Input

9
6
2
54

Solution in Scala (judge verdict: Accepted)

object Main extends App {

  import scala.io.StdIn._
  import scala.math._
  solve
  def solve: Unit = {
    val n = readLine.trim.toInt
    if (n == 0) return
    println(solveExpression(List.tabulate(n){_ ⇒ readLine.trim}))
    solve
  }
  def solveExpression(expression: List[String]): Long = {
    def solveDepth(expression: List[String], depth: Int, result: List[Long] = Nil): (List[Long], List[String]) = {
      expression match {
        case h::t if h.isDepthN(depth) ⇒
          h.asDepthN(depth) match{
            case n if n.isDigit ⇒ solveDepth(t, depth, n.asDigit::result)
            case o ⇒
              val (numbers, rest) = solveDepth(t, depth + 1)
              o match {
                case '+' ⇒ solveDepth(rest, depth, numbers.sum::result)
                case '*' ⇒ solveDepth(rest, depth, numbers.product::result)
                case _ ⇒ ???
              }
          }
        case _ ⇒ (result, expression)
      }
    }
    solveDepth(expression, 0)._1.head
  }
  implicit class Token(str: String){
    def isDepthN(n: Int): Boolean = if (n == 0) str(n) != '.'
    else str.indices.contains(n - 1) && str(n - 1) == '.' && str(n) != '.'
    def asDepthN(n: Int): Char = str(n)

  }

  @inline
  def lowerBound[T](array: Array[T], target: T)(implicit ord: Ordering[T]): Int = {
    var left = 0
    var right = array.length
    while (left < right){
      val mid = (left + right) / 2
      if (ord.compare(array(mid), target) < 0){
        left = mid + 1
      }else {
        right = mid
      }
    }
    right
  }
  @inline
  def upperBound[T](array: Array[T], target: T)(implicit ord: Ordering[T]): Int = {
    var left = 0
    var right = array.length
    while (left < right){
      val mid = (left + right) / 2
      if (ord.compare(array(mid), target) <= 0){
        left = mid + 1
      }else {
        right = mid
      }
    }
    right
  }
  implicit class Extension[T](val value :T){
    def also(func: T ⇒ Unit): T = {
      func(value)
      value
    }
    def let[R](func: T ⇒ R): R = func(value)
  }
}