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);
}
}
//