> The "eval" does seem a bit dangerous though.
Especially if you take it a bit to the edge like this (plug into the
other solution):
RXE = /
[\[\]\{\}[:space:][:cntrl:]truefals]+|
(:)|
(?:,(?>\s*)(?![}\]]))|
("(?>[^"\\]+|\\(?:u[0-9a-fA-F]{4}|[bfnrt"\/\\]))*")|
-?(?=\d)(?>0|[1-9]\d*)(?>\.\d+)?(?>[Ee][+-]?\d+)?(?=\D|$)|
(null)|
(.+)
/xmu
def parse(json)
ruby = json.gsub(RXE) do |t|
if !$4.nil? then invalid($4)
elsif !$3.nil? then 'nil'
elsif !$1.nil? then '=>'
elsif !$2.nil? then $2.gsub(/#/, '\\\\#')
else
t
end
end
begin
return eval(ruby)
rescue Exception => e
invalid(json)
end
end
This works because the "null" token does not *start* with any letter
in "true" or "false". "fnull" would be happily converted to "fnil",
but eval catches that luckily.
As ugly as it is, it cranks in 200kb/sec on my machine, which should
be more than 400kb/sec on yours. 25-30% of C speed is quite
impressive (I had to say this since I was bitching about Ruby's speed
last week...).
Paolo