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
return s
end