module JSON
class <<self
def read(path)
open(path,'r') do |f|
json = f.read
f.close
end
end
def json2object(path)
jparser = JsonParser.new
return jparser.start(json)
end
end
end
class JsonParser
def start(value)
@escapee = {
'"' => '"',
'\\' => '\\',
'/' => '/',
'b' => 'b',
'f' => '\f',
'n' => '\n',
'r' => '\r',
't' => '\t'
}
@text = value
@at = 0
@ch = ' '
white
if @ch
error("Syntax error")
end
return json
end
def error(m)
raise SyntaxError,"#{@text[0,8]}...[#{@at}] #{m}"
end
def _next(c = nil)
error("Expected '" + c + "' instead of '" + @ch + "'") if c && c != @ch
@ch = @text[@at, 1]
@at += 1
return @ch
end
def number
isfloat = false
string = ''
if @ch == '-'
string = '-'
_next('-')
end
while (@ch <=> '0') >= 0 && (@ch <=> '9') <= 0
string += @ch
_next
end
if @ch == '.'
string += '.'
isfloat = true
while _next && (@ch <=> '0') >= 0 && (@ch <=> '9') <= 0
string += @ch
end
end
if @ch == 'e' || @ch == 'E'
string += 'e'
isfloat = true
_next
if @ch == '-' || @ch == '+'
string += @ch
_next
end
while (@ch <=> '0') >= 0 && (@ch <=> '9') <= 0
string += @ch
_next
end
end
return isfloat ? string.to_f : string.to_i
end
def string
string = ''
if @ch == '"'
while _next
if @ch == '"'
_next
return string
elsif @ch == '\\'
_next
if @ch == 'u'
uffff = '\u'
4.times{|i|uffff += _next}
string += uffff
elsif @escapee[@ch]
string += @escapee[@ch]
else
break
end
else
string += @ch
end
end
end
error("Bad string")
end
def white
while @ch && (@ch <=> ' ') <= 0
_next
end
end
def word
case @ch
when 't'
_next('t')
_next('r')
_next('u')
_next('e')
return true
when 'f'
_next('f')
_next('a')
_next('l')
_next('s')
_next('e')
return false
when 'n'
_next('n')
_next('u')
_next('l')
_next('l')
return nil
end
error("Unexpected '" + @ch + "'")
end
def array
array = []
if @ch == '['
_next('[')
white
if @ch == ']'
_next(']')
return array
end
while @ch
array.push(json)
white
if @ch == ']'
_next(']')
return array
end
_next(',')
white
end
end
error("Bad array")
end
def object
object = {}
if @ch == '{'
_next('{')
white
if @ch == '}'
_next('}')
return object
end
while @ch
key = string
white
_next(':')
object[key.to_sym] = json
white
if @ch == '}'
_next('}')
return object
end
_next(',')
white
end
end
error("Bad object")
end
def json
white
case @ch
when '{'
return object
when '['
return array
when '"'
return string
when '-'
return number
else
return (@ch <=> '0') >= 0 && (@ch <=> '9') <= 0 ? number : word
end
end
end