def finished!
      return if @closed
      @closed = true

      # if 'start' nonterminal was not explicitly set, just take the first one
      @start ||= map(&:target).detect { |sym| !sym.generated? }
      fail CompileError, 'no rules in input' if @rules.empty?
      add_start_rule

      @rules.freeze
      @symbols.each do |sym|
        sym.heads.freeze
        sym.locate.freeze
      end
      @cache.freeze

      fix_ident
      check_terminals
      check_rules
    end
def finished!
      return if @closed
      @closed = true

      # if 'start' nonterminal was not explicitly set, just take the first one
      @start ||= map(&:target).detect { |sym| !sym.generated? }
      fail CompileError, 'no rules in input' if @rules.empty?
      add_start_rule

      @rules.freeze
      @symbols.each do |sym|
        sym.heads.freeze
        sym.locate.freeze
      end
      @cache.freeze

      fix_ident
      check_terminals
      check_rules
    end
Computation