module Yamlr module Reader module Parser class IndentError < StandardError; end def self.parse(line, opts, num) results = self.parse_line(line, opts) phs = self.results_to_hash(results, opts) self.check_indent(line, phs[:spc], opts[:indent], num) phs end # invalid number of spaces, line num and truncated line for context # def self.check_indent(line, spc, idt, num) raise IndentError, "#{num} #{line[1..50]}" if spc % idt != 0 end # parses line, returns array, dependent on Node module # def self.parse_line(line, opts) nod = Yamlr::Reader::Node spc = opts[:space] hsh = opts[:hash] sym = opts[:symbol] dcs = opts[:doc_start] dct = opts[:doc_term] arr = opts[:array] com = opts[:comment] begin case line when nod.left_match(arr, spc) then [:arr, Regexp.last_match.captures] when nod.left_match(com, spc) then [:com, Regexp.last_match.captures] when nod.hashkey_sym(hsh, sym, spc) then [:hky, Regexp.last_match.captures, nil, true] when nod.hashkey(hsh, spc) then [:hky, Regexp.last_match.captures] when nod.hashpair_sym_all(hsh, sym, spc) then [:hpr, Regexp.last_match.captures, true, true] when nod.hashpair_sym_key(hsh, sym, spc) then [:hpr, Regexp.last_match.captures, true] when nod.hashpair_sym_val(hsh, sym, spc) then [:hpr, Regexp.last_match.captures, nil, true] when nod.hashpair(hsh, sym, spc) then [:hpr, Regexp.last_match.captures] when /^\s*$/ then [:bla] when nod.document(dcs, spc) then [:dcs] when nod.document(dct, spc) then [:dct] else raise 'MALFORMED' end rescue => e # log or whatever [:mal, '', nil, line.strip] end end # creates hash with array vals, includes options # def self.results_to_hash(results, opt) #raise results.flatten.to_s + " results.class => #{results.class}" msg, spc, key, val, ask, asv = results.flatten { :msg => msg, :spc => (spc.nil? ? 0 : spc.length), :key => key.to_s.sub(/^:/, ''), :val => val.to_s.sub(/^:/, ''), :ask => ask, :asv => asv, :opt => opt} end end end end