public class Calc2 {

	static enum TOKEN {
		PLUS, MINUS, MUL, DIV, NUMBER, LP, RP, END, FUNCTION;
	}

	double expr() {
		double left = term();
		while (true) {
			switch (curr_tok) {
			case PLUS:
				left += term();
				break;
			case MINUS:
				left -= term();
				break;
			default:
				return left;
			}
		}
	}

	double term() {
		double left = prim();
		while (true) {
			switch (curr_tok) {
			case MUL:
				left *= prim();
				break;
			case DIV:
				left /= prim();
				break;
			default:
				return left;
			}
		}
	}

	double prim() {
		get_token();
		switch (curr_tok) {
		case NUMBER:
			double v = number_value;
			get_token();
			return v;
		case MINUS:
			return -prim();
		case LP:
			double e = expr();
			if (curr_tok != TOKEN.RP)
				return error(")expected");
			return e;
		case FUNCTION:
			String f = function_name;
			get_token();
			if (curr_tok != TOKEN.LP)
				return error("( expected");
			double z = prim();
			if (curr_tok != TOKEN.RP)
				return error(") expected");
			if ("sin".equals(f)) {
				return Math.sin(z);
			} else {
				return error("unknown function");
			}
		default:
			return error("primary expression expected");
		}
	}

	double error(String msg) {
		error_msg = msg;
		return Double.NaN;
	}

	TOKEN curr_tok;
	double number_value;
	String function_name;
	String error_msg;
	String input;
	int pos;

	void get_token() {
		if (pos >= input.length()) {
			curr_tok = TOKEN.END;
			return;
		}
		char x = input.charAt(pos++);
		switch (x) {
		case '+':
			curr_tok = TOKEN.PLUS;
			break;
		case '-':
			curr_tok = TOKEN.MINUS;
			break;
		case '*':
			curr_tok = TOKEN.MUL;
			break;
		case '/':
			curr_tok = TOKEN.DIV;
			break;
		case '(':
			curr_tok = TOKEN.LP;
			break;
		case ')':
			curr_tok = TOKEN.RP;
			break;
		default:
			if (Character.isDigit(x) || x == '.') {
				curr_tok = TOKEN.NUMBER;
				String s = "" + x;
				while (pos < input.length() && (Character.isDigit(input.charAt(pos)) || input.charAt(pos) == '.')) {
					s += input.charAt(pos);
					++pos;
				}
				number_value = Double.parseDouble(s);
			} else if (Character.isLetter(x)) {
				curr_tok = TOKEN.FUNCTION;
				String s = "" + x;
				while (pos < input.length() && Character.isLetter(input.charAt(pos))) {
					s += input.charAt(pos);
					++pos;
				}
				function_name = s;
			}
		}
	}

	public static void main(String[] args) {
		Calc2 calc = new Calc2();
		calc.input = "sin(1)";
		calc.pos = 0;
		double res = calc.expr();
		if (Double.isNaN(res)) {
			System.out.println(calc.error_msg);
		} else {
			System.out.println(res);
		}
	}
}
