| 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 195
195: def parse
196: reset
197: until eos?
198: case
199: when scan(ARRAY_OPEN)
200: return parse_array
201: when scan(OBJECT_OPEN)
202: return parse_object
203: when skip(IGNORE)
204: ;
205: when !((value = parse_value).equal? UNPARSED)
206: return value
207: else
208: raise ParserError, "source '#{peek(20)}' not in JSON!"
209: end
210: end
211: end
# File lib/json.rb, line 265
265: def parse_array
266: result = []
267: until eos?
268: case
269: when (value = parse_value) != UNPARSED
270: result << value
271: skip(IGNORE)
272: unless scan(COLLECTION_DELIMITER) or match?(ARRAY_CLOSE)
273: raise ParserError, "expected ',' or ']' in array at '#{peek(20)}'!"
274: end
275: when scan(ARRAY_CLOSE)
276: break
277: when skip(IGNORE)
278: ;
279: else
280: raise ParserError, "unexpected token in array at '#{peek(20)}'!"
281: end
282: end
283: result
284: end
# File lib/json.rb, line 286
286: def parse_object
287: result = {}
288: until eos?
289: case
290: when (string = parse_string) != UNPARSED
291: skip(IGNORE)
292: unless scan(PAIR_DELIMITER)
293: raise ParserError, "expected ':' in object at '#{peek(20)}'!"
294: end
295: skip(IGNORE)
296: unless (value = parse_value).equal? UNPARSED
297: result[string] = value
298: skip(IGNORE)
299: unless scan(COLLECTION_DELIMITER) or match?(OBJECT_CLOSE)
300: raise ParserError,
301: "expected ',' or '}' in object at '#{peek(20)}'!"
302: end
303: else
304: raise ParserError, "expected value in object at '#{peek(20)}'!"
305: end
306: when scan(OBJECT_CLOSE)
307: if klassname = result['json_class']
308: klass = klassname.sub(/^:+/, '').split(/::/).inject(Object) do |p,k|
309: p.const_get(k) rescue nil
310: end
311: break unless klass and klass.json_creatable?
312: result = klass.json_create(result)
313: end
314: break
315: when skip(IGNORE)
316: ;
317: else
318: raise ParserError, "unexpected token in object at '#{peek(20)}'!"
319: end
320: end
321: result
322: end
# File lib/json.rb, line 215
215: def parse_string
216: if scan(STRING)
217: return '' if self[1].empty?
218: self[1].gsub(/\\(?:[\\bfnrt"]|u([A-Fa-f\d]{4}))/) do
219: case $~[0]
220: when '\\\\' then '\\'
221: when '\\b' then "\b"
222: when '\\f' then "\f"
223: when '\\n' then "\n"
224: when '\\r' then "\r"
225: when '\\t' then "\t"
226: when '\\"' then '"'
227: else
228: if JSON.support_unicode? and $KCODE == 'UTF8'
229: JSON.utf16_to_utf8($~[1])
230: else
231: # if utf8 mode is switched off or unicode not supported, try to
232: # transform unicode \u-notation to bytes directly:
233: $~[1].to_i(16).chr
234: end
235: end
236: end
237: else
238: UNPARSED
239: end
240: end
# File lib/json.rb, line 242
242: def parse_value
243: case
244: when scan(FLOAT)
245: Float(self[0])
246: when scan(INTEGER)
247: Integer(self[0])
248: when scan(TRUE)
249: true
250: when scan(FALSE)
251: false
252: when scan(NULL)
253: nil
254: when (string = parse_string) != UNPARSED
255: string
256: when scan(ARRAY_OPEN)
257: parse_array
258: when scan(OBJECT_OPEN)
259: parse_object
260: else
261: UNPARSED
262: end
263: end