docs: def NextToken(self):
      """Fetch the next token by trying to match any of the regexes in order."""
      # Nothing in the input stream - no token can match.
      if not self.buffer:
        return
  
      current_state = self.state
      for token in self._tokens:
        # Does the rule apply to us?
        if token.state_regex and not token.state_regex.match(current_state):
          continue
  
        if self.verbose:
          logging.debug("%s: Trying to match %r with %r", self.state,
                        self.buffer[:10], token.re_str)
  
        # Try to match the rule
        m = token.regex.match(self.buffer)
        if not m:
          continue
  
        if self.verbose:
          logging.debug("%s matched %s", token.re_str, m.group(0))
  
        # A token matched the empty string. We can not consume the token from the
        # input stream.
        if m.end() == 0:
          raise RuntimeError("Lexer bug! Token can not match the empty string.")
  
        # The match consumes the data off the buffer (the handler can put it back
        # if it likes)
        self.processed_buffer += self.buffer[:m.end()]
        self.buffer = self.buffer[m.end():]
        self.processed += m.end()
  
        next_state = token.next_state
        for action in token.actions:
          if self.verbose:
            logging.debug("Calling %s with %s", action, m.group(0))
  
          # Is there a callback to handle this action?
          cb = getattr(self, action, self.Default)
  
          # Allow a callback to skip other callbacks.
          try:
            possible_next_state = cb(string=m.group(0), match=m)
            if possible_next_state == "CONTINUE":
              continue
            # Override the state from the Token
            elif possible_next_state:
              next_state = possible_next_state
          except ParseError as e:
            self.Error(e)
  
        # Update the next state
        if next_state:
          self.state = next_state
  
        return token
  
      # Check that we are making progress - if we are too full, we assume we are
      # stuck.
      self.Error("Lexer stuck at state %s" % (self.state))
      self.processed_buffer += self.buffer[:1]
      self.buffer = self.buffer[1:]
      return "Error"