def dfa(self, ttab: TransitionTable, init: int = 0) -> int:
        """Run a DFA and return the final (negative) state.

        Args:
            ttab: Transition table (with possible side-effects).
            init: Initial state.

        Raises:
            EndOfInput: If past the end of `self.input`.
        """
        state = init
        while True:
            disp = ttab[state]
            ch = self.peek()
            state = disp.get(ch, disp[""])()
            if state < 0:
                return state
            self.offset += 1