public void recognize(PushbackReader r, Token t) {
    // we must allocate StringBuilder here for thread safety.
    StringBuilder sb  = new StringBuilder();
    
    //    if (tracing) {
    //      System.out.println("DFA.recognize " + t);
    //    }
    try {
      sb.setLength(0); //StringBuilder sb = new StringBuilder();

      // keep track of the length of the longest token found, and
      // the final state it's associated with
      int maxLengthFound = 0;
      int bestFinalState = -1;
      int bestFinalCode = -1;

      //      if (tracing) {
      //        System.out.println(" startState = " + startState());
      //      }

      int state = startState();

      while (true) {
        // read character from the reader; exit if eof
        int ch = r.read();
        if (ch < 0) {
          break;
        }

        // add character to buffer for later pushing back
        char c = (char) ch;
        sb.append(c);

        // if this is not a legal character for a token, no match.
        if (c > Token.T_ASCII_END) {
          break;
        }

        int newState = getTransitionState(state, c);
        //        if (tracing) {
        //          System.out.println(" s=" + state + " c=" + c + " d=" + newState);
        //        }
        // if there's no transition on this symbol from the state, no match.
        if (newState < 0) {
          break;
        }

        state = newState; //setState(newState);

        // if state has token code, we've reached a final state.
        //        DFAState s = getState(state);
        int token = getState(state).getTerminalCode();
        //        if (tracing) {
        //          System.out.println(" termCode=" + token);
        //        }

        if (token >= 0) {
          maxLengthFound = sb.length();
          bestFinalCode = token;
          bestFinalState = newState;
          //          if (tracing) {
          //            System.out.println("  found token length " + maxLengthFound);
          //          }
        }
      }
      state = bestFinalState; //setState(bestFinalState);

      // push back all characters we read, since location tracking
      // has probably been disabled.
      for (int i = sb.length() - 1; i >= 0; i--) {
        r.unread(sb.charAt(i));
      }

      if (bestFinalCode >= 0) {
        t.setId(bestFinalCode);
        t.setText(sb.substring(0, maxLengthFound));
      } else if (sb.length() == 0) {
        t.setText("");
        t.setId(Token.T_EOF);
      } else {
        t.setText(sb.substring(0, 1));
        t.setId(sb.charAt(0));
      }

      //      if (tracing) {
      //        System.out.println(" returning token " + t);
      //      }
    } catch (IOException e) {
      throw new ScanException(e.toString());
    }
  }