import java.util.LinkedList;
import java.util.Scanner;
import java.util.Stack;

/**
 * @author mitsunoriogihara
 *
 */
public class PostFixEvaluation {

	String[] OPERATOR = {"+", "-", "*", "/"};
	String[] SPECIALS = {"\\+", "-", "\\*", "/"};
	String[] SPECIALS_NEW = {" + ", " - ", " * ", " / "};

	String rawInput;
	LinkedList<String> tokens;

	PostFixEvaluation(String s) {
		this.rawInput = s;
	}
	/**
	 * Convert the input string into tokens
	 */
	private void tokenize() {
		/* insert space before and after every operational symbol */
		String s = this.rawInput.substring(0);
		for (int i=0; i<SPECIALS.length; i++) {
			s = s.replaceAll(SPECIALS[i], SPECIALS_NEW[i]);
		}
		/* split using " " as delimiter */
		String[] parts = s.split(" ");
		/* then take only non empty strings as tokens */
		tokens = new LinkedList<String>();
		for (int i=0; i<parts.length; i++) {
			if (parts[i].length()>0) {
				tokens.add(parts[i]);
			}
		}
	}
	/**
	 * Return whether a string is an operator
	 * @param w	input string
	 * @return	number between -1 and 3, -1 indicating non-operator
	 */
	private int isOperator(String w) {
		if (w.equals(OPERATOR[0])) {
			return 0 ;
		}
		else if (w.equals(OPERATOR[1])) {
			return 1;
		}
		else if (w.equals(OPERATOR[2])) {
			return 2;
		}
		else if (w.equals(OPERATOR[3])) {
			return 3;
		}
		else {
			return -1;
		}		
	}
	/**
	 * For testing tokens generated print all tokens
	 */
	private void printTokens() {
		for (String foo : tokens) {
			System.out.println(foo);
		}
	}
	
	/**
	 * Evalute the tokens with respect to postfix notation
	 * @return	the double value which is the outcome evaluation
	 */
	private double evaluate() {
		/* initialize an empty stack */
		Stack<String> stack = new Stack<String>();
		for (String t : tokens) {
			int v = isOperator(t);
			/* if the input token is not an operator,
			 * push it onto stack
			 */
			if (v<0) stack.push(t);
			else {
				/* pop the two operands and evaluate them as double */
				double o2 = Double.parseDouble(stack.pop());
				double o1 = Double.parseDouble(stack.pop());
				double r = 0.0;
				/* apply the operator and push the return onto stack */
				if (v==0) r = o1+o2;
				else if (v==1) r = o1-o2;
				else if (v==2) r = o1*o2;
				else r = o1/o2;
				stack.push(""+r);
			}
		}
		return Double.parseDouble(stack.pop());
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Scanner sC = new Scanner(System.in);
		while (true) {
			System.out.print("Input > ");
			String s = sC.nextLine();
			if (s.length()==0) break;
			PostFixEvaluation pF = new PostFixEvaluation(s);
			pF.tokenize();
			pF.printTokens();
			System.out.println(pF.evaluate());			
		}
		System.out.println("Program terminates");
		sC.close();
	}

}
