private function backtrack(): bool
    {
        $found = false;

        do {
            $last = \array_pop($this->trace);

            if ($last instanceof Entry) {
                $found = $this->grammar->fetch($last->getRule()) instanceof Alternation;
            } elseif ($last instanceof Escape) {
                $found = $this->grammar->fetch($last->getRule()) instanceof Repetition;
            } elseif ($last instanceof Token) {
                if (! $this->stream->prev()) {
                    return false;
                }
            }
        } while (0 < \count($this->trace) && $found === false);

        if ($found === false) {
            return false;
        }

        $this->todo = $last->getTodo();
        $this->todo[] = new Entry($last->getRule(), $last->getData() + 1);

        return true;
    }