
  MAILP_DEBUG = false

  def initialize
    self.debug = MAILP_DEBUG
  end

  def debug=( flag )
    @yydebug = flag && DEBUG_PARSER
    @scanner_debug = flag
  end

  def debug
    @yydebug
  end


  def Mailp.parse( str, obj, ident )
    new.parse( str, obj, ident )
  end


  def parse( str, obj, ident )
    return if /\A\s*\z/ === str

    @field = obj

    case obj
    when MsgidH
      msgid_parse str
    when RefH
      refs_parse str
    else
      unless ident then
        ident = obj.type.name.split('::')[-1].to_s
        cmt = []
        obj.comments.replace cmt
      else
        cmt = nil
      end

      @scanner = MailScanner.new( str, ident, cmt )
      @scanner.debug = @scanner_debug
      @first = [ ident.intern, ident ]
      @pass_array = [nil, nil]

      do_parse
    end
  end


  private


  def next_token
    if @first then
      ret = @first
      @first = nil
      ret
    else
      @scanner.scan @pass_array
    end
  end
  
  def on_error( tok, val, vstack )
    raise ParseError,
      "\nparse error in '#{@field.name}' header, on token #{val.inspect}"
  end


  def refs_parse( str )
    arr = []

    while ::TMail::MSGID === str do
      p   = $`
      m   = $&
      str = $'

      p.strip!
      arr.push p
      arr.push m
    end
    str.strip!
    arr.push str unless str.empty?

    @field.refs.replace arr
  end

  def msgid_parse( str )
    if ::TMail::MSGID === str then
      @field.msgid = $&
    else
      raise ParseError, "wrong Message-ID format: #{str}"
    end
  end

