private function validateDeterministic(Grammar $grammar): void
    {
        /** @var Item[] */
        $finite = [];
        $terminals = [];
        $non_terminals = [];
        foreach ($this->items as $item) {
            $next_symbol = $item->getExpected();
            if (!$next_symbol) {
                $finite[] = $item;
            } elseif ($next_symbol->isTerminal()) {
                $terminals[] = $item;
            } else {
                $non_terminals[] = $item;
            }
        }

        $this->validateDeterministicShiftReduce(
            $finite,
            $terminals,
            $non_terminals,
            $grammar
        );
        $this->validateDeterministicReduceReduce($finite);
    }