       true -> string(data, pos + 2, [Map.get(@escapes, char)|chars])
     end
   end
-  defp string(<<@escape>> <> _data, pos, _chars),
+  defp string(<<?\\>> <> _data, pos, _chars),
     do: throw {:string, pos}
   defp string(<<char>> <> data, pos, chars),
     do: string(data, pos + 1, [char|chars])
 
   defp unicode(<<a1, b1, c1, d1, ?\\, ?u, a2, b2, c2, d2>> <> data, pos, chars)
-    when a1 in @surrogate_a and a2 in @surrogate_a and b1 in @surrogate_b1 and b2 in @surrogate_b2 do
+    when a1 in 'dD' and a2 in 'dD' and b1 in '89abAb' and b2 in 'cedfCDEF' do
     hi = List.to_integer([a1, b1, c1, d1], 16)
     lo = List.to_integer([a2, b2, c2, d2], 16)
     codepoint = 0x10000 + ((hi &&& 0x03FF) <<< 10) + (lo &&& 0x03FF)

  defp float(data, pos, chars, _last),
    do: {chars |> IO.iodata_to_binary |> String.to_float, data, pos}

  defp string(<<@quotation_mark>> <> data, pos, chars),
    do: {chars |> Enum.reverse |> IO.iodata_to_binary, data, pos}
  defp string(<<?\\, char>> <> data, pos, chars) when char in @escape_chars do
    cond do

    do: {chars |> IO.iodata_to_binary |> String.to_float, data, pos}

  defp float(<<char>> <> _data, pos, _chars, :full_stop)
    when char in 'eE',
    do: throw {:float, pos}
  defp float(<<char>> <> data, pos, chars, _last)
    when char in 'eE',
    do: exponential(data, pos + 1, [chars, 'e'], :exp)
  defp float(<<char>> <> data, pos, chars, _last)
    when char in @digits,
