/** An instance of this class tokenizes a given arithmetic expression ** (provided in the form of a String ojbect) into its elements, which ** include parentheses, integer constants, identifiers (of the form ** "x" followed by a number, as in "x35"), and various binary ** operators (e.g., ** +,-,*,/) */ public class Tokenizer implements StringTokenizerUofS { public Tokenizer(String expr) { tokenize(expr); } public void tokenize(String expr) { exprStr = expr; k = 0; advanceToNextToken(); } public boolean hasMoreTokens() { return token != null; } public Token getToken() throws UnRecognizableTokenException { if (unrecognizable) { throw new UnRecognizableTokenException(); } return token; } public void advanceToNextToken() { // increment k until it points to the next non-space or goes past end while (k != exprStr.length() && exprStr.charAt(k) == SPACE_CHAR) { k++; } if (k == exprStr.length()) { token = null; // there is no next token } else { parseToken(); // determine the token beginning at position k } } /** Determines the token that begins at position k of exprStr, makes ** it the current token, and updates k to point to the position ** immediately following the new current token. (If the token in ** question cannot be recognized, unrecognizable is set to true.) ** */ private void parseToken() { char ch = exprStr.charAt(k); if (ch == '(') { k++; token = new LeftParen(); } else if (ch == ')') { k++; token = new RightParen(); } else if (ch == '+') { k++; token = new AddOperator(); } else if (ch == '-') { k++; token = new SubtractOperator(); } else if (ch == '*') { k++; token = new MultiplyOperator(); } else if (ch == '/') { k++; token = new DivideOperator(); } else if (Character.isDigit(ch)) { int m = k+1; // find the end of the integer literal while (m != exprStr.length() && Character.isDigit(exprStr.charAt(m)) ) { m++; } // int literal is exprStr[k..m-1]; compute its numeric value int value = Integer.parseInt(exprStr.substring(k,m)); token = new IntConstant(value); k = m; } else { // can't recognize this token unrecognizable = true; } } private static final char SPACE_CHAR = ' '; // a space character private String exprStr; // String to be tokenized private int k; // position within exprStr immediately // following the current token private Token token; // current token (null if there is none) private boolean unrecognizable; // true if current token is unrecognizable }