code: def _rule_container(self):
          
  
          type_name = self._get_token(self.RE_NAME)
          self._expect_token('{')
  
          # consume elements if available
          options = []
          blocks = []
          dupe_blocks = {}
  
          while self._lookahead_token() != '}':
              # is it a block?
              if self._lookahead_token(count=2) == '{':
                  block = self._rule_block()
                  name = block[0]
  
                  # duplicate found, hold for replace
                  if name in self._block_map:
                      dupe_blocks[name] = block
                  else:
                      # update block index and add to block list
                      self._block_map[name] = len(blocks)
                      blocks.append(block)
  
              else:
                  # otherwise, let's go with non-block option
                  options.append(self._rule_option())
  
          # replace duplicate block definitions
          if dupe_blocks:
              for name, block in dupe_blocks.iteritems():
                  block_idx = self._block_map[name]
                  blocks[block_idx] = block
  
          self._expect_token('}')
          self._expect_empty()
  
          return [type_name, options, blocks]
docs: Parses the production rule::
                  container : NAME '{' (option | block)* '}' EOF
  
              Returns tuple (type_name, options_list, blocks_list).