| Class | JSON::Parser |
| In: |
lib/json.rb
|
| Parent: | StringScanner |
| STRING | = | /"((?:[^"\\]|\\.)*)"/ |
| INTEGER | = | /-?\d+/ |
| FLOAT | = | /-?\d+\.(\d*)(?i:e[+-]?\d+)?/ |
| OBJECT_OPEN | = | /\{/ |
| OBJECT_CLOSE | = | /\}/ |
| ARRAY_OPEN | = | /\[/ |
| ARRAY_CLOSE | = | /\]/ |
| PAIR_DELIMITER | = | /:/ |
| COLLECTION_DELIMITER | = | /,/ |
| TRUE | = | /true/ |
| FALSE | = | /false/ |
| NULL | = | /null/ |
| IGNORE | = | %r( (?: //[^\n\r]*[\n\r]| # line comments /\* # c-style comments (?: [^*/]| # normal chars /[^*]| # slashes that do not start a nested comment \*[^/]| # asterisks that do not end this comment /(?=\*/) # single slash before this comment's end )* \*/ # the end of this comment |\s+ # whitespaces )+ )mx |
| UNPARSED | = | Object.new |
Parses the current JSON string and returns the complete data structure as a result.
# File lib/json.rb, line 249
249: def parse
250: reset
251: until eos?
252: case
253: when scan(ARRAY_OPEN)
254: return parse_array
255: when scan(OBJECT_OPEN)
256: return parse_object
257: when skip(IGNORE)
258: ;
259: when !((value = parse_value).equal? UNPARSED)
260: return value
261: else
262: raise ParserError, "source '#{peek(20)}' not in JSON!"
263: end
264: end
265: end
# File lib/json.rb, line 320
320: def parse_array
321: result = []
322: until eos?
323: case
324: when (value = parse_value) != UNPARSED
325: result << value
326: skip(IGNORE)
327: unless scan(COLLECTION_DELIMITER) or match?(ARRAY_CLOSE)
328: raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
329: end
330: when scan(ARRAY_CLOSE)
331: break
332: when skip(IGNORE)
333: ;
334: else
335: raise ParserError, "unexpected token in array at '#{peek(20)}'!"
336: end
337: end
338: result
339: end
# File lib/json.rb, line 341
341: def parse_object
342: result = {}
343: until eos?
344: case
345: when (string = parse_string) != UNPARSED
346: skip(IGNORE)
347: unless scan(PAIR_DELIMITER)
348: raise ParserError, "expected ':' in object at '#{peek(20)}'!"
349: end
350: skip(IGNORE)
351: unless (value = parse_value).equal? UNPARSED
352: result[string] = value
353: skip(IGNORE)
354: unless scan(COLLECTION_DELIMITER) or match?(OBJECT_CLOSE)
355: raise ParserError,
356: "expected ',' or '}' in object at '#{peek(20)}'!"
357: end
358: else
359: raise ParserError, "expected value in object at '#{peek(20)}'!"
360: end
361: when scan(OBJECT_CLOSE)
362: if klassname = result['json_class']
363: klass = klassname.sub(/^:+/, '').split(/::/).inject(Object) do |p,k|
364: p.const_get(k) rescue nil
365: end
366: break unless klass and klass.json_creatable?
367: result = klass.json_create(result)
368: end
369: break
370: when skip(IGNORE)
371: ;
372: else
373: raise ParserError, "unexpected token in object at '#{peek(20)}'!"
374: end
375: end
376: result
377: end
# File lib/json.rb, line 269
269: def parse_string
270: if scan(STRING)
271: return '' if self[1].empty?
272: self[1].gsub(%r(\\(?:[\\bfnrt"/]|u([A-Fa-f\d]{4})))) do
273: case $~[0]
274: when '\\\\' then '\\'
275: when '\\b' then "\b"
276: when '\\f' then "\f"
277: when '\\n' then "\n"
278: when '\\r' then "\r"
279: when '\\t' then "\t"
280: when '\\"' then '"'
281: when '\\/' then '/'
282: else
283: if JSON.support_unicode? and $KCODE == 'UTF8'
284: JSON.utf16_to_utf8($~[1])
285: else
286: # if utf8 mode is switched off or unicode not supported, try to
287: # transform unicode \u-notation to bytes directly:
288: $~[1].to_i(16).chr
289: end
290: end
291: end
292: else
293: UNPARSED
294: end
295: end
# File lib/json.rb, line 297
297: def parse_value
298: case
299: when scan(FLOAT)
300: Float(self[0])
301: when scan(INTEGER)
302: Integer(self[0])
303: when scan(TRUE)
304: true
305: when scan(FALSE)
306: false
307: when scan(NULL)
308: nil
309: when (string = parse_string) != UNPARSED
310: string
311: when scan(ARRAY_OPEN)
312: parse_array
313: when scan(OBJECT_OPEN)
314: parse_object
315: else
316: UNPARSED
317: end
318: end