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 JAVA (judge verdict: Accepted)

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;

public class Main {

	static PrintWriter out;
	static InputReader ir;
	static boolean debug = false;

	static void solve() {
		for (;;) {
			int n = ir.nextInt();
			if (n == 0)
				return;
			if (n == 1) {
				out.println(ir.nextInt());
				continue;
			}
			int[] d = new int[n];
			int[] a = new int[n];
			for (int i = 0; i < n; i++) {
				String s = ir.next();
				int ct = 0;
				while (ct < s.length() && s.charAt(ct) == '.')
					ct++;
				d[i] = ct;
				s = s.substring(ct);
				if (s.equals("+")) {
					a[i] = -1;
				} else if (s.equals("*")) {
					a[i] = -2;
				} else {
					a[i] = Integer.parseInt(s);
				}
			}
			out.println(dfs(1, n, 1, a[0], d, a));
		}
	}

	static long dfs(int l, int r, int dep, int op, int[] d, int[] a) {
		long ret = op == -1 ? 0 : 1;
		for (int i = l; i < r; i++) {
			if (d[i] == dep) {
				if (a[i] >= 0) {
					if (op == -1)
						ret += a[i];
					else
						ret *= a[i];
				} else {
					int pre = i++;
					while (i < r && d[i] != dep)
						i++;
					if (op == -1)
						ret += dfs(pre + 1, i, dep + 1, a[pre], d, a);
					else
						ret *= dfs(pre + 1, i, dep + 1, a[pre], d, a);
					i--;
				}
			}
		}
		return ret;
	}

	public static void main(String[] args) throws Exception {
		ir = new InputReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.flush();
	}

	static class InputReader {

		private InputStream in;
		private byte[] buffer = new byte[1024];
		private int curbuf;
		private int lenbuf;

		public InputReader(InputStream in) {
			this.in = in;
			this.curbuf = this.lenbuf = 0;
		}

		public boolean hasNextByte() {
			if (curbuf >= lenbuf) {
				curbuf = 0;
				try {
					lenbuf = in.read(buffer);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return false;
			}
			return true;
		}

		private int readByte() {
			if (hasNextByte())
				return buffer[curbuf++];
			else
				return -1;
		}

		private boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		private void skip() {
			while (hasNextByte() && isSpaceChar(buffer[curbuf]))
				curbuf++;
		}

		public boolean hasNext() {
			skip();
			return hasNextByte();
		}

		public String next() {
			if (!hasNext())
				throw new NoSuchElementException();
			StringBuilder sb = new StringBuilder();
			int b = readByte();
			while (!isSpaceChar(b)) {
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		public int nextInt() {
			if (!hasNext())
				throw new NoSuchElementException();
			int c = readByte();
			while (isSpaceChar(c))
				c = readByte();
			boolean minus = false;
			if (c == '-') {
				minus = true;
				c = readByte();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res = res * 10 + c - '0';
				c = readByte();
			} while (!isSpaceChar(c));
			return (minus) ? -res : res;
		}

		public long nextLong() {
			if (!hasNext())
				throw new NoSuchElementException();
			int c = readByte();
			while (isSpaceChar(c))
				c = readByte();
			boolean minus = false;
			if (c == '-') {
				minus = true;
				c = readByte();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res = res * 10 + c - '0';
				c = readByte();
			} while (!isSpaceChar(c));
			return (minus) ? -res : res;
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public int[] nextIntArray(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		public long[] nextLongArray(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextLong();
			return a;
		}

		public char[][] nextCharMap(int n, int m) {
			char[][] map = new char[n][m];
			for (int i = 0; i < n; i++)
				map[i] = next().toCharArray();
			return map;
		}
	}

	static void tr(Object... o) {
		if (debug)
			out.println(Arrays.deepToString(o));
	}
}