UNB/ CS/ David Bremner/ teaching/ java/ StringParser2.java
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);
    }


}
//