iterate(s.defaultTransition,visited) ;
}
}
}
public void spew(String packageName,String name,Writer writer) throws IOException {
State s = StateMachine.union(regexps.toArray(new State[0])) ;
Set<State> stateList = new HashSet<State>() ;
iterate(s,stateList) ;
writer.write("// generated code. You probably don't want to edit it.\n") ;
writer.write("package "+packageName+";\n") ;
for(String imp: imports) {
writer.write("import "+imp+";\n") ;
}
writer.write("import java.io.Reader;\n") ;
writer.write("import org.allspice.parser.parsetable.Token;\n") ;
writer.write("import org.allspice.parser.parsetable.SyntaxError;\n") ;
writer.write("import org.allspice.tok.UnexpectedCharacter;\n") ;
writer.write("public final class "+name+" extends "+baseClass+" {\n") ;
writer.write("\tpublic static final int START_STATE = "+s.hashCode()+";\n") ;
writer.write("\tpublic "+name+"(Reader r) {\n") ;
writer.write("\t\tsuper(r);\n") ;
writer.write("\t}\n") ;
writer.write("\tprivate class Machine extends MachineBase {\n") ;
writer.write("\t\tpublic Machine() {\n") ;
writer.write("\t\t\t\t\tsuper(START_STATE);\n") ;
writer.write("\t\t}\n") ;
for(State st: stateList) {
if (st.tag != null) {
writer.write("/**\n") ;
writer.write(" * @throws SyntaxError\n") ;
writer.write(" * @return The token\n") ;
writer.write(" */\n") ;
writer.write("private Token makeToken"+st.hashCode()+"() throws SyntaxError ") ;
writer.write(st.tag+"\n") ;
}
}
writer.write("\t\t@Override\n") ;
writer.write("\t\tpublic Token next() throws SyntaxError {\n") ;
writer.write("\t\t\tfor(;;) {\n") ;
writer.write("\t\t\t\tswitch(state) {\n") ;
for(State st: stateList) {
writer.write("\t\t\t\tcase "+st.hashCode()+":\n") ;
if (st == s) {
writer.write("\t\t\tif (currChar < 0) return org.allspice.parser.parsetable.Parser.EOF ;\n") ;
}
if (st.transitions.isEmpty() && st.defaultTransition == null) {
writeFinal(writer, st);
}
else {
writer.write("\t\t\t\t\tswitch(currChar) {\n") ;
Map<State,Set<Character>> rev = new HashMap<State,Set<Character>>() ;
for(Map.Entry<Character,State> e: st.transitions.entrySet()) {
Character c = e.getKey() ;
State t = e.getValue() ;
Set<Character> l = rev.get(t) ;
if (l == null) {
l = new TreeSet<Character>() ;
rev.put(t, l) ;
}
l.add(c) ;
}
for(Map.Entry<State,Set<Character>> e: rev.entrySet()) {
Set<Character> l = e.getValue() ;
State t = e.getKey() ;
for(Character c: l) {
String sc ;
if (c == '\t') {
sc = "\\t" ;
}
else if (c == '\b') {
sc = "\\b" ;
}
else if (c == '\f') {
sc = "\\f" ;
}
else if (c == '\n') {
sc = "\\n" ;
}
else if (c == '\r') {
sc = "\\r" ;
}
else if (c < 32 || c >= 127) {
sc = "\\"+Integer.toOctalString(c) ;
}
else if (c == '\\') {
sc = "\\\\" ;
}
else if (c == '\'') {
sc = "\\'" ;
}
else {
sc = String.valueOf(c) ;
}
writer.write("\t\t\t\t\tcase '"+sc+"':\n") ;
}
writer.write("\t\t\t\t\t\tmove("+t.hashCode()+");\n") ;
writer.write("\t\t\t\t\t\tbreak;\n") ;
}
if (st.defaultTransition != null) {
writer.write("\t\t\t\t\tcase -1:\n") ;
writeFinal(writer, st);