def parse_root
      @input += "\n" unless @input.end_with?("\n")

      s0 = @current_pos
      s1 = []
      s2 = parse_skipline
      while s2 != :failed
        s1 << s2
        s2 = parse_skipline
      end

      s2 = []
      s3 = parse_header
      while s3 != :failed
        s2 << s3
        s3 = parse_header
      end
      s3 = parse_initialboard
      s3 = nil if s3 == :failed
      s4 = []
      s5 = parse_header
      while s5 != :failed
        s4 << s5
        s5 = parse_header
      end
      parse_split
      s6 = parse_moves
      if s6 != :failed
        s7 = []
        s8 = parse_fork
        while s8 != :failed
          s7 << s8
          s8 = parse_fork
        end
        parse_nl
        @reported_pos = s0
        s0 = transform_root(s2, s3, s4, s6, s7)
      else
        @current_pos = s0
        s0 = :failed
      end

      s0
    end
def parse_root
      @input += "\n" unless @input.end_with?("\n")

      s0 = @current_pos
      s1 = []
      s2 = parse_skipline
      while s2 != :failed
        s1 << s2
        s2 = parse_skipline
      end

      s2 = []
      s3 = parse_header
      while s3 != :failed
        s2 << s3
        s3 = parse_header
      end
      s3 = parse_initialboard
      s3 = nil if s3 == :failed
      s4 = []
      s5 = parse_header
      while s5 != :failed
        s4 << s5
        s5 = parse_header
      end
      parse_split
      s6 = parse_moves
      if s6 != :failed
        s7 = []
        s8 = parse_fork
        while s8 != :failed
          s7 << s8
          s8 = parse_fork
        end
        parse_nl
        @reported_pos = s0
        s0 = transform_root(s2, s3, s4, s6, s7)
      else
        @current_pos = s0
        s0 = :failed
      end

      s0
    end
kifu : skipline* header* initialboard? header* split? moves fork* nl?