public void PrintStates() {
    trace.WriteLine();
    trace.WriteLine("---------- states ----------");
    for (State state = firstState; state != null; state = state.next) {
      boolean first = true;
      if (state.endOf == null) trace.Write("               ");
      else trace.Write("E(" + tab.Name(state.endOf.name) + ")", 12);
      trace.Write(state.nr + ":", 3);
      if (state.firstAction == null) trace.WriteLine();
      for (Action action = state.firstAction; action != null; action = action.next) {
        if (first) {trace.Write(" "); first = false;} else trace.Write("                   ");
        if (action.typ == Node.clas)
          trace.Write(((CharClass)tab.classes.get(action.sym)).name);
        else trace.Write(Ch((char)action.sym), 3);
        for (Target targ = action.target; targ != null; targ = targ.next)
          trace.Write(Integer.toString(targ.state.nr), 3);
        if (action.tc == Node.contextTrans) trace.WriteLine(" context"); else trace.WriteLine();
      }
    }
    trace.WriteLine();
    trace.WriteLine("---------- character classes ----------");
    tab.WriteCharClasses();
  }