import java.util.Iterator; public class TokenString implements Iterable { private final String str; public TokenString(String str) { this.str = str; } public Iterator iterator() { return new TokenIterator(str); } } class TokenIterator implements Iterator { private static final char END = '\0'; private final String str; private int pos; private Token next; public TokenIterator(String str) { this.str = str; next = advance(); } public Token next() { Token tok = next; next = advance(); return tok; } public boolean hasNext() { return next != null; } public void remove() { throw new UnsupportedOperationException(); } private Token advance() { while ((pos < str.length()) && Character.isWhitespace(cur())) ++pos; char ch = cur(); if (ch == END) return null; if (Character.isDigit(ch)) { int start = pos; ++pos; while (Character.isDigit(cur())) ++pos; return Value.parse(str.substring(start, pos)); } else if (Operator.isOperatorChar(ch)) { int start = pos; ++pos; while (Operator.isOperatorChar(cur())) ++pos; return Operator.getBySymbol(str.substring(start, pos)); } else if (NameToken.isNameStartChar(ch)) { int start = pos; ++pos; while (NameToken.isNameChar(cur())) ++pos; return new NameToken(str.substring(start, pos)); } else if (ch == '(') { ++pos; return OpenParenthesisToken.INSTANCE; } else if (ch == ')') { ++pos; return CloseParenthesisToken.INSTANCE; } else if (ch == ',') { ++pos; return CommaToken.INSTANCE; } else { throw new IllegalArgumentException("illegal character " + ch + " at position " + pos + " in " + str); } } private char cur() { return charAt(pos); } private char charAt(int i) { if (i == str.length()) return END; else return str.charAt(i); } }