public class Token implements Cloneable { //Instance Variables private String symbol; private Type type; private int priority; //Constructor: create a new token from a string literal public Token(String symbol) { this.symbol = symbol.trim(); this.priority = 0; //Default, only operators have non-0 switch ( this.symbol ) { case "(" : this.type = Type.LEFT_PAREN; break; case ")" : this.type = Type.RIGHT_PAREN; break; case "+" : case "-" : case "*" : case "/" : case "^" : this.type = Type.OPERATOR; this.priority = "+-*/^".indexOf(this.symbol) / 2 + 1; break; default : this.type = Type.OPERAND; if (!isNumeric(this.symbol)) throw new RuntimeException("Invalid Expression Token"); } } //Constructor: create a new token from an integer literal public Token(int number) { this( "" + number ); } //Helper: Answer is the parameter is an integer literal private static boolean isNumeric(String str) { try { Integer.parseInt(str); return true; } catch (NumberFormatException nfe) { return false; } } //Return a printable image of a token public String toString() { return this.symbol; } //Return the precedence level of a token // Default precedence 0 for non-operator tokens // Standard precedence for arithmetic operators public int getPriority() { return this.priority; } //Answer if a token is a left-parenthesis public boolean isLeftParen() { return this.type == Type.LEFT_PAREN; } //Answer if a token is a right-parenthesis public boolean isRightParen() { return this.type == Type.RIGHT_PAREN; } //Answer if a token is an operator: +, -, *, /, ^ public boolean isOperator() { return this.type == Type.OPERATOR; } //Answer of a token is an operand public boolean isOperand() { return this.type == Type.OPERAND; } //Return the integer value of an operand public int operandValue() { if (!this.isOperand()) throw new RuntimeException("Integer Operand Expected"); return Integer.parseInt(this.symbol); } //Return the result of applying an operator //Parameters, in order, are the left and right operands public int applyOperator(Token left, Token right) { int a = left.operandValue(); int b = right.operandValue(); switch (this.symbol) { case "+" : return a + b; case "-" : return a - b; case "*" : return a * b; case "/" : return a / b; case "^" : int result = 1; for ( ; b > 0; b--) result *= a; return result; default : throw new RuntimeException("Unrecognized Operator " + this); } } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException cnse) { return null; } } private enum Type { OPERAND, OPERATOR, LEFT_PAREN, RIGHT_PAREN; } }