import java.io.StreamTokenizer; import java.io.StringReader; import java.io.IOException; import java.lang.IllegalArgumentException; public class StringParser2{ private StreamTokenizer tokens=null; public StringParser2(String str){ tokens=new StreamTokenizer(new StringReader(str)); tokens.ordinaryChar('/'); } private void die(String msg){ throw new RuntimeException(msg+tokens.toString()); } private double eval(int level) throws IOException{ double left=0.0; Trace.indent(level,"enter eval"); int token=tokens.nextToken(); if (token=='('){ // rule 1 left=eval(level+1); if (tokens.nextToken()!=')') die("expected ')'"); } else if (token==StreamTokenizer.TT_NUMBER){ //rule 2 or 3 left=tokens.nval; } else die("Syntax error"); double right=0.0; int op=tokens.nextToken(); if (op=='+' || op=='-' || op=='*' || op=='/'){ right=eval(level+1); return arith(level,op,left,right); } else { tokens.pushBack(); Trace.indent(level,"return "+left); return left; } } private double arith(int level,int op, double left, double right) { double rval; switch(op){ case '+': rval=left+right; break; case '*': rval= left*right; break; case '-': rval= left-right; break; case '/': rval=left/right; break; default: throw new IllegalArgumentException("illegal operator: "+(char)op); } Trace.indent(level,"return "+left+(char)op+""+right+"="+rval); return rval; } public static void main(String[] args) throws IOException{ StringParser2 Parser=new StringParser2("(((3+4)*2)+3)/8)"); double d=Parser.eval(0); System.out.println(d); } } //