### ### $Rev$ ### $Release: 0.7.2 $ ### copyright(c) 2005-2010 kuwata-lab all rights reserved. ### require 'strscan' require 'kwalify/errors' require 'kwalify/util' ## ## base class for Yaml::Parser ## class Kwalify::BaseParser def reset(input, filename=nil, untabify=false) input = Kwalify::Util.untabify(input) if untabify @scanner = StringScanner.new(input) @filename = filename @linenum = 1 @column = 1 end attr_reader :filename, :linenum, :column def scan(regexp) ret = @scanner.scan(regexp) return nil if ret.nil? _set_column_and_linenum(ret) return ret end def _set_column_and_linenum(s) pos = s.rindex(?\n) if pos @column = s.length - pos @linenum += s.count("\n") else @column += s.length end end def match?(regexp) return @scanner.match?(regexp) end def group(n) return @scanner[n] end def eos? return @scanner.eos? end def peep(n=1) return @scanner.peep(n) end def _getch ch = @scanner.getch() if ch == "\n" @linenum += 1 @column = 0 else @column += 1 end return ch end CHAR_TABLE = { "\""=>"\"", "\\"=>"\\", "n"=>"\n", "r"=>"\r", "t"=>"\t", "b"=>"\b" } def scan_string ch = _getch() ch == '"' || ch == "'" or raise "assertion error" endch = ch s = '' while !(ch = _getch()).nil? && ch != endch if ch != '\\' s << ch elsif (ch = _getch()).nil? raise _syntax_error("%s: string is not closed." % (endch == '"' ? "'\"'" : '"\'"')) elsif endch == '"' if CHAR_TABLE.key?(ch) s << CHAR_TABLE[ch] elsif ch == 'u' ch2 = scan(/(?:[0-9a-f][0-9a-f]){1,4}/) unless ch2 raise _syntax_error("\\x: invalid unicode format.") end s << [ch2.hex].pack('U*') elsif ch == 'x' ch2 = scan(/[0-9a-zA-Z][0-9a-zA-Z]/) unless ch2 raise _syntax_error("\\x: invalid binary format.") end s << [ch2].pack('H2') else s << "\\" << ch end elsif endch == "'" ch == '\'' || ch == '\\' ? s << ch : s << '\\' << ch else raise "unreachable" end end #_getch() return s end def _syntax_error(message, path=nil, linenum=@linenum, column=@column) #message = _build_message(message_key) return _error(Kwalify::SyntaxError, message.to_s, path, linenum, column) end protected :_syntax_error end