/** * */ package xhail.core.parser; import java.io.IOException; import java.io.InputStream; import xhail.core.Logger; /** * @author stefano * */ public class Tokeniser { private static interface State { public boolean process(Tokeniser tokeniser); } private static enum States implements State { EOF { public boolean process(Tokeniser tokeniser) { tokeniser.setToken(null); tokeniser.setState(EOF); return true; } }, ESCAPE { public boolean process(Tokeniser tokeniser) { int ch = tokeniser.read(); switch (ch) { case -1: tokeniser.setToken(token); tokeniser.setState(EOF); return false; default: token += (char) ch; tokeniser.setState(STRING); return false; } } }, NORMAL { public boolean process(Tokeniser tokeniser) { int ch = tokeniser.read(); switch (ch) { case -1: tokeniser.setToken(token); tokeniser.setState(EOF); return false; case '\"': token += (char) ch; tokeniser.setState(STRING); return false; case '\r': case '\n': case ' ': tokeniser.setToken(token); tokeniser.setState(SKIP); token = ""; return true; default: token += (char) ch; return false; } } }, SKIP { public boolean process(Tokeniser tokeniser) { int ch = tokeniser.read(); switch (ch) { case -1: tokeniser.setToken(token); tokeniser.setState(EOF); return false; case '\r': case '\n': case ' ': return false; default: token += (char) ch; tokeniser.setState(NORMAL); return false; } } }, STRING { public boolean process(Tokeniser tokeniser) { int ch = tokeniser.read(); switch (ch) { case -1: tokeniser.setToken(token); tokeniser.setState(EOF); return false; case '\\': token += (char) ch; tokeniser.setState(ESCAPE); return false; case '\"': token += (char) ch; tokeniser.setState(NORMAL); return false; default: token += (char) ch; return false; } } }; private static String token = ""; @Override public boolean process(Tokeniser tokeniser) { System.out.println("Hello world!"); return true; } } public static Tokeniser from(InputStream stream) { if (null == stream) throw new IllegalArgumentException("Illegal 'stream' argument in Tokeniser.from(InputStream): " + stream); return new Tokeniser(stream); } private State state; private InputStream stream; private String token; private Tokeniser(InputStream stream) { if (null == stream) throw new IllegalArgumentException("Illegal 'stream' argument in Tokeniser.Tokeniser(InputStream): " + stream); this.stream = stream; this.setState(States.SKIP); } public String next() { boolean finished = false; while (!finished) finished = state.process(this); return token; } private int read() { try { if (null == stream) return -1; return stream.read(); } catch (IOException e) { Logger.error("cannot read for the input stream"); return -1; } } private void setState(State next) { if (null == next) throw new IllegalArgumentException("Illegal 'next' argument in Tokeniser.setState(State): " + next); state = next; } private void setToken(String token) { this.token = token; } }