# File lib/Getopt/Declare.rb, line 960
  def initialize(*opts)

    # HANDLE SHORT-CIRCUITS

    return if opts.length()==2 && (!opts[1] || opts[1] == '-SKIP') 

    grammar, source = opts

    if grammar.nil?
      raise "Error: No grammar description provided."
    end

    ### REMOVED PREDEF GRAMMAR AS IT WAS NOT DOCUMENTED NOR 

    ### WORKING IN PERL'S Declare.pm VERSION.


    # PRESERVE ESCAPED '['s

    grammar.gsub!(/\\\[/,"\255")

    # MAKE SURE GRAMMAR ENDS WITH A NEWLINE.

    grammar.sub!(/([^\n])\Z/,'\1'+"\n")

    @usage   = grammar.dup

    # SET-UP

    i = grammar
    _args = []
    _mutex = {}
    _strict = false
    _all_repeatable = false
    _lastdesc = nil
    Getopt::Declare::_nocase( 0 )
    Getopt::Declare::ScalarArg::_reset_stdtype()

    # CONSTRUCT GRAMMAR

    while i.length > 0

      # COMMENT:

      i.sub!(/\A[ \t]*#.*\n/,"") and next

      # TYPE DIRECTIVE:

      se  = DelimScanner::new( i )

      if i =~ /\A\s*\[pvtype:/ 
        _action = se.extractBracketed("[")
        if _action
          i.sub!( Regexp::quote( _action ).to_re, "" )   ### @GGA: added

          i.sub!(/\A[ \t]*\n/,"")                        ### @GGA: added

          _action.sub!(/.*?\[pvtype:\s*/,"")
          _typedef(_action)
          next
        end # if

      end

      # ACTION  

      codeblockDelimiters = {
        '{'     => '}',
      }


      _action = se.extractCodeblock(codeblockDelimiters)
      if _action
        i.sub!( Regexp::quote(_action ).to_re, "" )
        i.sub!(/\A[ \t]*\n/,"")
        _action = _action[1..-2]

        if !valid_syntax?( _action )
          raise "Error: bad action in Getopt::Declare specification:" +
            "\n\n#{_action}\n\n\n"
        end

        if _args.length() == 0
          raise "Error: unattached action in Getopt::Declare specification:\n#{_action}\n" +
                "\t(did you forget the tab after the preceding parameter specification?)\n"
        end

        _args.last().actions.push( _action )
        next
      elsif i =~ /\A(\s*[{].*)/
        raise "Error: incomplete action in Getopt::Declare specification:\n$1.....\n" +
              "\t(did you forget a closing '}'?)\n"
      end

      # ARG + DESC:

      if i.sub!(/\A(.*?\S.*?)(\t.*\n)/,"")
        spec = "#$1"
        desc = "#$2"
        _strict ||= desc =~ /\[strict\]/

        desc += "#$1" while i.sub!(/\A((?![ \t]*(\{|\n)|.*?\S.*?\t.*?\S).*?\S.*\n)/,"")
        
        ditto = nil
        ditto = 1 if _lastdesc and desc.sub!(/\A\s*\[ditto\]/,_lastdesc)
        _lastdesc = desc

        arg = Arg.new(spec,desc,ditto)
        _args.push( arg )

        _infer(desc, arg, _mutex)
        next
      end

      # OTHERWISE: DECORATION

      i.sub!(/((?:(?!\[pvtype:).)*)(\n|(?=\[pvtype:))/,"")
      decorator = "#$1"
      _strict ||= decorator =~ /\[strict\]/
      _infer(decorator, nil, _mutex)

      _all_repeatable = true if decorator =~ /\[repeatable\]/

    end # while i.length



    _lastactions = nil
    for i in _args
      if _lastactions && i.ditto && i.actions.size == 0
        i.actions = _lastactions
      else
        _lastactions = i.actions
      end

      if _all_repeatable
        i.repeatable = 1
      end
    end

    # Sort flags based on criteria described in docs

    _args = _args.sort() { |a,b|
     ( b.flag.length() <=> a.flag.length() ) or
        ( b.flag == a.flag and ( b.args.length() <=> a.args.length() ) ) or
        ( a.id <=> b.id )
    }

    # Handle clump

    clump = (@usage =~ /\[cluster:\s*none\s*\]/i)     ? 0 :
      (@usage =~ /\[cluster:\s*singles?\s*\]/i) ? 1 :
      (@usage =~ /\[cluster:\s*flags?\s*\]/i)   ? 2 :
      (@usage =~ /\[cluster:\s*any\s*\]/i)      ? 3 :
      (@usage =~ /\[cluster:(.*)\s*\]/i)         ? "r" : 3
    raise "Error: unknown clustering mode: [cluster:#$1]\n" if clump == "r"

    # CONSTRUCT OBJECT ITSELF

    @args    = _args
    @mutex   = _mutex
    @helppat = Arg::helppat()
    @verspat = Arg::versionpat()

    @strict  = _strict
    @clump   = clump
    @source  = ''
    @tight   = @usage =~ /\[tight\]/i
    @caller  = caller()

    # VESTIGAL DEBUGGING CODE

    if @@Declare_debug > 0
      f = File.new(".CODE.rb","w") and
        f.puts( code() ) and
        f.close() 
    end

    # DO THE PARSE (IF APPROPRIATE)

    if (opts.length() == 2)
        return nil unless parse(opts[1])
    else
      return nil unless parse()
    end

  end