class RDoc::RD::BlockParser

def _reduce_1(val, _values, result)

def _reduce_1(val, _values, result)
 result = RDoc::Markup::Document.new(*val[0])
    result
end

def _reduce_10(val, _values, result)

def _reduce_10(val, _values, result)
 result = [RDoc::Markup::BlankLine.new]
    result
end

def _reduce_11(val, _values, result)

def _reduce_11(val, _values, result)
 result = val[0].parts
    result
end

def _reduce_12(val, _values, result)

def _reduce_12(val, _values, result)
      # val[0] is like [level, title]
      title = @inline_parser.parse(val[0][1])
      result = RDoc::Markup::Heading.new(val[0][0], title)

    result
end

def _reduce_13(val, _values, result)

def _reduce_13(val, _values, result)
      result = RDoc::Markup::Include.new val[0], @include_path

    result
end

def _reduce_14(val, _values, result)

def _reduce_14(val, _values, result)
      # val[0] is Array of String
      result = paragraph val[0]

    result
end

def _reduce_15(val, _values, result)

def _reduce_15(val, _values, result)
 result << val[1].rstrip
    result
end

def _reduce_16(val, _values, result)

def _reduce_16(val, _values, result)
 result = [val[0].rstrip]
    result
end

def _reduce_17(val, _values, result)

def _reduce_17(val, _values, result)
      # val[1] is Array of String
      content = cut_off val[1]
      result = RDoc::Markup::Verbatim.new(*content)

      # imform to lexer.
      @in_verbatim = false

    result
end

def _reduce_18(val, _values, result)

def _reduce_18(val, _values, result)
      # val[0] is Array of String
      content = cut_off val[0]
      result = RDoc::Markup::Verbatim.new(*content)

      # imform to lexer.
      @in_verbatim = false

    result
end

def _reduce_19(val, _values, result)

def _reduce_19(val, _values, result)
      result << val[1]

    result
end

def _reduce_2(val, _values, result)

def _reduce_2(val, _values, result)
 raise ParseError, "file empty"
    result
end

def _reduce_20(val, _values, result)

def _reduce_20(val, _values, result)
      result.concat val[2]

    result
end

def _reduce_21(val, _values, result)

def _reduce_21(val, _values, result)
      result << "\n"

    result
end

def _reduce_22(val, _values, result)

def _reduce_22(val, _values, result)
      result = val
      # inform to lexer.
      @in_verbatim = true

    result
end

def _reduce_27(val, _values, result)

def _reduce_27(val, _values, result)
      result = val[0]

    result
end

def _reduce_28(val, _values, result)

def _reduce_28(val, _values, result)
      result = val[1]

    result
end

def _reduce_29(val, _values, result)

def _reduce_29(val, _values, result)
      result = val[1].push(val[2])

    result
end

def _reduce_3(val, _values, result)

def _reduce_3(val, _values, result)
 result = val[0].concat val[1]
    result
end

def _reduce_30(val, _values, result)

def _reduce_30(val, _values, result)
 result = val[0] << val[1]
    result
end

def _reduce_31(val, _values, result)

def _reduce_31(val, _values, result)
 result = [val[0]]
    result
end

def _reduce_32(val, _values, result)

def _reduce_32(val, _values, result)
      result = RDoc::Markup::List.new :BULLET, *val[0]

    result
end

def _reduce_33(val, _values, result)

def _reduce_33(val, _values, result)
 result.push(val[1])
    result
end

def _reduce_34(val, _values, result)

def _reduce_34(val, _values, result)
 result = val
    result
end

def _reduce_35(val, _values, result)

def _reduce_35(val, _values, result)
      result = RDoc::Markup::ListItem.new nil, val[0], *val[1]

    result
end

def _reduce_36(val, _values, result)

def _reduce_36(val, _values, result)
      result = RDoc::Markup::List.new :NUMBER, *val[0]

    result
end

def _reduce_37(val, _values, result)

def _reduce_37(val, _values, result)
 result.push(val[1])
    result
end

def _reduce_38(val, _values, result)

def _reduce_38(val, _values, result)
 result = val
    result
end

def _reduce_39(val, _values, result)

def _reduce_39(val, _values, result)
      result = RDoc::Markup::ListItem.new nil, val[0], *val[1]

    result
end

def _reduce_4(val, _values, result)

def _reduce_4(val, _values, result)
 result = val[0]
    result
end

def _reduce_40(val, _values, result)

def _reduce_40(val, _values, result)
      result = RDoc::Markup::List.new :NOTE, *val[0]

    result
end

def _reduce_41(val, _values, result)

def _reduce_41(val, _values, result)
 result.push(val[1])
    result
end

def _reduce_42(val, _values, result)

def _reduce_42(val, _values, result)
 result = val
    result
end

def _reduce_43(val, _values, result)

def _reduce_43(val, _values, result)
      term = @inline_parser.parse val[0].strip

      result = RDoc::Markup::ListItem.new term, *val[1]

    result
end

def _reduce_44(val, _values, result)

def _reduce_44(val, _values, result)
      result = RDoc::Markup::List.new :LABEL, *val[0]

    result
end

def _reduce_45(val, _values, result)

def _reduce_45(val, _values, result)
 result.push(val[1])
    result
end

def _reduce_46(val, _values, result)

def _reduce_46(val, _values, result)
 result = val
    result
end

def _reduce_47(val, _values, result)

def _reduce_47(val, _values, result)
      result = RDoc::Markup::ListItem.new "<tt>#{val[0].strip}</tt>", *val[1]

    result
end

def _reduce_48(val, _values, result)

def _reduce_48(val, _values, result)
      result = [val[1]].concat(val[2])

    result
end

def _reduce_49(val, _values, result)

def _reduce_49(val, _values, result)
      result = [val[1]]

    result
end

def _reduce_5(val, _values, result)

def _reduce_5(val, _values, result)
 result = val
    result
end

def _reduce_50(val, _values, result)

def _reduce_50(val, _values, result)
      result = val[2]

    result
end

def _reduce_51(val, _values, result)

def _reduce_51(val, _values, result)
      result = []

    result
end

def _reduce_52(val, _values, result)

def _reduce_52(val, _values, result)
 result.concat val[1]
    result
end

def _reduce_54(val, _values, result)

def _reduce_54(val, _values, result)
 result = val
    result
end

def _reduce_55(val, _values, result)

def _reduce_55(val, _values, result)
 result = val
    result
end

def _reduce_57(val, _values, result)

def _reduce_57(val, _values, result)
 result = []
    result
end

def _reduce_6(val, _values, result)

def _reduce_6(val, _values, result)
 result = val
    result
end

def _reduce_62(val, _values, result)

def _reduce_62(val, _values, result)
      result = paragraph [val[0]].concat(val[1])

    result
end

def _reduce_63(val, _values, result)

def _reduce_63(val, _values, result)
      result = paragraph [val[0]]

    result
end

def _reduce_64(val, _values, result)

def _reduce_64(val, _values, result)
      result = paragraph [val[0]].concat(val[1])

    result
end

def _reduce_65(val, _values, result)

def _reduce_65(val, _values, result)
      result = paragraph [val[0]]

    result
end

def _reduce_66(val, _values, result)

def _reduce_66(val, _values, result)
      result = [val[0]].concat(val[1])

    result
end

def _reduce_67(val, _values, result)

def _reduce_67(val, _values, result)
 result.concat val[1]
    result
end

def _reduce_68(val, _values, result)

def _reduce_68(val, _values, result)
 result = val[1]
    result
end

def _reduce_69(val, _values, result)

def _reduce_69(val, _values, result)
 result = val
    result
end

def _reduce_71(val, _values, result)

def _reduce_71(val, _values, result)
 result = []
    result
end

def _reduce_72(val, _values, result)

def _reduce_72(val, _values, result)
 result = []
    result
end

def _reduce_8(val, _values, result)

def _reduce_8(val, _values, result)
 result = val
    result
end

def _reduce_9(val, _values, result)

def _reduce_9(val, _values, result)
 result = val
    result
end

def _reduce_none(val, _values, result)

def _reduce_none(val, _values, result)
  val[0]
end

def add_footnote content

def add_footnote content
  index = @footnotes.length / 2 + 1

  footmark_link = "{^#{index}}[rdoc-label:footmark-#{index}:foottext-#{index}]"

  @footnotes << RDoc::Markup::Paragraph.new(footmark_link, ' ', *content)
  @footnotes << RDoc::Markup::BlankLine.new

  index
end

def add_label label

def add_label label
  @labels[label] = true

  label
end

def content values

def content values
 values.map { |value| value.content }.join
end

def cut_off(src)

def cut_off(src)
  ret = []
  whiteline_buf = []

  line = src.shift
  /^\s*/ =~ line

  indent = Regexp.quote($&)
  ret.push($')

  while line = src.shift
    if /^(\s*)$/ =~ line
      whiteline_buf.push(line)
    elsif /^#{indent}/ =~ line
      unless whiteline_buf.empty?
        ret.concat(whiteline_buf)
        whiteline_buf.clear
      end
      ret.push($')
    else
      raise "[BUG]: probably Parser Error while cutting off.\n"
    end
  end
  ret
end

def format_line_num(*line_numbers)

def format_line_num(*line_numbers)
  width = line_numbers.collect{|i| i.to_s.length }.max
  line_numbers.collect{|i| sprintf("%#{width}d", i) }
end

def get_included(file)

def get_included(file)
  included = []

  @include_path.each do |dir|
    file_name = File.join dir, file

    if File.exist? file_name then
      included = File.readlines file_name
      break
    end
  end

  included
end

def if_current_indent_equal(indent)

def if_current_indent_equal(indent)
  indent = indent.sub(/\t/, "\s" * 8)
  if @current_indent == indent
    @i += 1 # next line
    yield
  elsif indent.index(@current_indent) == 0
    @indent_stack.push(indent[@current_indent.size .. -1])
    [:INDENT, ":INDENT"]
  else
    @indent_stack.pop
    [:DEDENT, ":DEDENT"]
  end
end

def initialize

def initialize
  @inline_parser = RDoc::RD::InlineParser.new self
  @include_path = []

  # for testing
  @footnotes = []
  @labels    = {}
end

def line_index

def line_index
  @i
end

def next_token # :nodoc:

:nodoc:
def next_token # :nodoc:
  # preprocessing
  # if it is not in RD part
  # => method
  while @in_part != "rd"
    line = @src[@i]
    @i += 1 # next line

    case line
    # src end
    when false
      return [false, false]
    # RD part begin
    when /^=begin\s*(?:\bRD\b.*)?\s*$/
      if @in_part # if in non-RD part
        @part_content.push(line)
      else
        @in_part = "rd"
        return [:WHITELINE, "=begin\n"] # <= for textblockand
      end
    # non-RD part begin
    when /^=begin\s+(\w+)/
      part = $1
=begin # not imported to RDoc
      if @in_part # if in non-RD part
        @part_content.push(line)
      else
        @in_part = part if @tree.filter[part] # if filter exists
#  p "BEGIN_PART: #{@in_part}" # DEBUG
      end
=end
      @in_part = part
    # non-RD part end
    when /^=end(?:$|[\s\0\C-d\C-z])/
      if @in_part # if in non-RD part
=begin # not imported to RDoc
#  p "END_PART: #{@in_part}" # DEBUG
        # make Part-in object
        part = RDoc::RD::Part.new(@part_content.join(""), @tree, "r")
        @part_content.clear
        # call filter, part_out is output(Part object)
        part_out = @tree.filter[@in_part].call(part)

        if @tree.filter[@in_part].mode == :rd # if output is RD formatted
          subtree = parse_subtree(part_out.to_a)
        else # if output is target formatted
          basename = Tempfile.create(["rdtmp", ".#{@in_part}"], @tree.tmp_dir) do |tmpfile|
            tmpfile.print(part_out)
            File.basename(tmpfile.path)
          end
          subtree = parse_subtree(["=begin\n", "<<< #{basename}\n", "=end\n"])
        end
        @in_part = nil
        return [:SUBTREE, subtree]
=end
      end
    else
=begin # not imported to RDoc
      if @in_part # if in non-RD part
        @part_content.push(line)
      end
=end
    end
  end

  @current_indent = @indent_stack.join("")
  line = @src[@i]
  case line
  when false
    if_current_indent_equal("") do
      [false, false]
    end
  when /^=end/
    if_current_indent_equal("") do
      @in_part = nil
      [:WHITELINE, "=end"] # MUST CHANGE??
    end
  when /^\s*$/
    @i += 1 # next line
    return [:WHITELINE, ':WHITELINE']
  when /^\#/  # comment line
    @i += 1 # next line
    self.next_token()
  when /^(={1,4})(?!=)\s*(?=\S)/, /^(\+{1,2})(?!\+)\s*(?=\S)/
    rest = $'                    # '
    rest.strip!
    mark = $1
    if_current_indent_equal("") do
      return [:HEADLINE, [MARK_TO_LEVEL[mark], rest]]
    end
  when /^<<<\s*(\S+)/
    file = $1
    if_current_indent_equal("") do
      suffix = file[-3 .. -1]
      if suffix == ".rd" or suffix == ".rb"
        subtree = parse_subtree(get_included(file))
        [:SUBTREE, subtree]
      else
        [:INCLUDE, file]
      end
    end
  when /^(\s*)\*(\s*)/
    rest = $'                   # '
    newIndent = $2
    if_current_indent_equal($1) do
      if @in_verbatim
        [:STRINGLINE, line]
      else
        @indent_stack.push("\s" + newIndent)
        [:ITEMLISTLINE, rest]
      end
    end
  when /^(\s*)(\(\d+\))(\s*)/
    rest = $'                     # '
    mark = $2
    newIndent = $3
    if_current_indent_equal($1) do
      if @in_verbatim
        [:STRINGLINE, line]
      else
        @indent_stack.push("\s" * mark.size + newIndent)
        [:ENUMLISTLINE, rest]
      end
    end
  when /^(\s*):(\s*)/
    rest = $'                    # '
    newIndent = $2
    if_current_indent_equal($1) do
      if @in_verbatim
        [:STRINGLINE, line]
      else
        @indent_stack.push("\s#{$2}")
        [:DESCLISTLINE, rest]
      end
    end
  when /^(\s*)---(?!-|\s*$)/
    indent = $1
    rest = $'
    /\s*/ === rest
    term = $'
    new_indent = $&
    if_current_indent_equal(indent) do
      if @in_verbatim
        [:STRINGLINE, line]
      else
        @indent_stack.push("\s\s\s" + new_indent)
        [:METHODLISTLINE, term]
      end
    end
  when /^(\s*)/
    if_current_indent_equal($1) do
      [:STRINGLINE, line]
    end
  else
    raise "[BUG] parsing error may occurred."
  end
end

def on_error(et, ev, _values)

def on_error(et, ev, _values)
  prv, cur, nxt = format_line_num(@i, @i+1, @i+2)

  raise ParseError, <<Msg

RD syntax error: line #{@i+1}:
  #{prv}  |#{@src[@i-1].chomp}
  #{cur}=>|#{@src[@i].chomp}
  #{nxt}  |#{@src[@i+1].chomp}

Msg
end

def paragraph value

def paragraph value
  content = cut_off(value).join(' ').rstrip
  contents = @inline_parser.parse content

  RDoc::Markup::Paragraph.new(*contents)
end

def parse src

def parse src
  @src = src
  @src.push false

  @footnotes = []
  @labels    = {}

  # @i: index(line no.) of src
  @i = 0

  # stack for current indentation
  @indent_stack = []

  # how indented.
  @current_indent = @indent_stack.join("")

  # RDoc::RD::BlockParser for tmp src
  @subparser = nil

  # which part is in now
  @in_part = nil
  @part_content = []

  @in_verbatim = false

  @yydebug = true

  document = do_parse

  unless @footnotes.empty? then
    blankline = document.parts.pop

    document.parts << RDoc::Markup::Rule.new(1)
    document.parts.concat @footnotes

    document.parts.push blankline
  end

  document
end

def parse_subtree src

def parse_subtree src
  @subparser ||= RDoc::RD::BlockParser.new

  @subparser.parse src
end

def set_term_to_element(parent, term)

def set_term_to_element(parent, term)
#  parent.set_term_under_document_struct(term, @tree.document_struct)
  parent.set_term_without_document_struct(term)
end