import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public class ExpressionParserRecursiveDescent { String s; int pos; char token; double tokval; static boolean isDigitOrDot(char x) { return Character.isDigit(x) || x == '.'; } int next() { while (true) { if (pos == s.length()) return token = 255; char c = s.charAt(pos++); if ("+-*/^()\n".indexOf(c) != -1) return token = c; if (Character.isSpaceChar(c)) continue; if (Character.isDigit(c) || c == '.') { String operand = "" + c; while (pos < s.length() && isDigitOrDot(s.charAt(pos))) operand += c = s.charAt(pos++); tokval = Double.parseDouble(operand); return token = 'n'; } throw new RuntimeException("Bad character: " + c); } } void skip(int ch) { if (token != ch) throw new RuntimeException("Bad character: " + token + ", expected: " + ch); next(); } // number ::= number | '(' expression ')' double number() { if (token == 'n') { double v = tokval; skip('n'); return v; } skip('('); double v = expression(); skip(')'); return v; } // factor ::= number | number '^' factor double factor() { double v = number(); if (token == '^') { skip('^'); v = Math.pow(v, factor()); } return v; } // term ::= factor | term '*' factor | term '/' factor double term() { double v = factor(); while (true) { if (token == '*') { skip('*'); v *= factor(); } else if (token == '/') { skip('/'); v /= factor(); } else return v; } } // expression ::= term | expression '+' term | expression '-' term double expression() { double v = term(); for (; ; ) { if (token == '+') { skip('+'); v += term(); } else if (token == '-') { skip('-'); v -= term(); } else return v; } } public static void main(String[] args) throws Exception { ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); String exp = "1+2*3*4+3*(2+2)-100\n"; System.out.println(engine.eval(exp)); ExpressionParserRecursiveDescent parser = new ExpressionParserRecursiveDescent(); parser.s = exp; parser.next(); while (parser.token != 255) { if (parser.token == '\n') { parser.skip('\n'); continue; } System.out.printf("%.5f", parser.expression()); } } }