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