# File lib/Getopt/Declare.rb, line 1000
  def initialize(*opts)
    @cache = nil

    Getopt::Declare::Arg::clear

    # HANDLE SHORT-CIRCUITS

    return if opts.size==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
    arg = nil
    Getopt::Declare::nocase = false
    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*\[\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!(/.*?\[\s*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!(re_argument,"")
        spec = "#$1".strip
        desc = "#$2"
        _strict ||= desc =~ /\[\s*strict\s*\]/

        while i.sub!(re_more_desc,"")
          desc += "#$1"
        end
        
        ditto = nil
        if _lastdesc and desc.sub!(/\A\s*\[\s*ditto\s*\]/,_lastdesc)
          ditto = arg
        else
          _lastdesc = desc
        end

        # Check for GNU spec line like:  -d, --debug

        arg = nil
        if spec =~ /(-[\w_\d]+),\s+(--[\w_\d]+)(\s+.*)?/
          specs = ["#$1#$3", "#$2#$3"]
          specs.each { |spec|
            arg = Arg.new(spec,desc,ditto)
            _args.push( arg )
            _infer(desc, arg, _mutex)
            ditto = arg
          }
        else
          arg = Arg.new(spec,desc,ditto)
          _args.push( arg )
          _infer(desc, arg, _mutex)
        end


        next
      end

      # OTHERWISE: DECORATION

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

      _all_repeatable = true if decorator =~ /\[\s*repeatable\s*\]/
      @@debug = true if decorator =~ /\[\s*debug\s*\]/

    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

    # Sadly, this cannot be reduced to sort_by

    _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 )
    }
    # _args = _args.sort_by { |a| [a.flag.size, a.flag, a.args.size, a.id] }



    # Handle clump

    clump = (@usage =~ /\[\s*cluster:\s*none\s*\]/i)     ? 0 :
      (@usage =~ /\[\s*cluster:\s*singles?\s*\]/i) ? 1 :
      (@usage =~ /\[\s*cluster:\s*flags?\s*\]/i)   ? 2 :
      (@usage =~ /\[\s*cluster:\s*any\s*\]/i)      ? 3 :
      (@usage =~ /\[\s*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 =~ /\[\s*tight\s*\]/i
    @caller  = caller()

    # VESTIGAL DEBUGGING CODE

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

    # DO THE PARSE (IF APPROPRIATE)

    if opts.size == 2
      return nil unless parse(source)
    else
      return nil unless parse()
    end

  end