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