Class: JSON::Pure::Parser

Inherits:
StringScanner
  • Object
show all
Defined in:
lib/json/pure/parser.rb

Overview

This class implements the JSON parser that is used to parse a JSON string into a Ruby data structure.

Constant Summary collapse

STRING =
/" ((?:[^\x0-\x1f"\\] |
     # escaped special characters:
    \\["\\\/bfnrt] |
    \\u[0-9a-fA-F]{4} |
     # match all but escaped special characters:
    \\[\x20-\x21\x23-\x2e\x30-\x5b\x5d-\x61\x63-\x65\x67-\x6d\x6f-\x71\x73\x75-\xff])*)
"/nx
INTEGER =
/(-?0|-?[1-9]\d*)/
FLOAT =
/(-?
(?:0|[1-9]\d*)
(?:
  \.\d+(?i:e[+-]?\d+) |
  \.\d+ |
  (?i:e[+-]?\d+)
)
)/x
NAN =
/NaN/
INFINITY =
/Infinity/
MINUS_INFINITY =
/-Infinity/
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
   (?:
    [\s\S]*?         # any char, repeated lazily
   )
     \*/               # the End of this comment
     |[ \t\r\n]+       # whitespaces: space, horizontal tab, lf, cr
  )+
)mx
UNPARSED =
Object.new.freeze

Instance Method Summary collapse

Constructor Details

#initialize(source, opts = nil) ⇒ Parser

Creates a new JSON::Pure::Parser instance for the string source.

It will be configured by the opts hash. opts can have the following keys:

  • max_nesting: The maximum depth of nesting allowed in the parsed data structures. Disable depth checking with :max_nesting => false|nil|0, it defaults to 100.

  • allow_nan: If set to true, allow NaN, Infinity and -Infinity in defiance of RFC 7159 to be parsed by the Parser. This option defaults to false.

  • freeze: If set to true, all parsed objects will be frozen. Parsed string will be deduplicated if possible.

  • symbolize_names: If set to true, returns symbols for the names (keys) in a JSON object. Otherwise strings are returned, which is also the default. It’s not possible to use this option in conjunction with the create_additions option.

  • create_additions: If set to true, the Parser creates additions when a matching class and create_id are found. This option defaults to false.

  • object_class: Defaults to Hash. If another type is provided, it will be used instead of Hash to represent JSON objects. The type must respond to new without arguments, and return an object that respond to []=.

  • array_class: Defaults to Array If another type is provided, it will be used instead of Hash to represent JSON arrays. The type must respond to new without arguments, and return an object that respond to <<.

  • decimal_class: Specifies which class to use instead of the default

    (Float) when parsing decimal numbers. This class must accept a single
    string argument in its constructor.
    


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/json/pure/parser.rb', line 79

def initialize(source, opts = nil)
  opts ||= {}
  source = convert_encoding source
  super source
  if !opts.key?(:max_nesting) # defaults to 100
    @max_nesting = 100
  elsif opts[:max_nesting]
    @max_nesting = opts[:max_nesting]
  else
    @max_nesting = 0
  end
  @allow_nan = !!opts[:allow_nan]
  @symbolize_names = !!opts[:symbolize_names]
  @freeze = !!opts[:freeze]
  if opts.key?(:create_additions)
    @create_additions = !!opts[:create_additions]
  else
    @create_additions = false
  end
  @symbolize_names && @create_additions and raise ArgumentError,
    'options :symbolize_names and :create_additions cannot be used '\
    'in conjunction'
  @create_id = @create_additions ? JSON.create_id : nil
  @object_class = opts[:object_class] || Hash
  @array_class  = opts[:array_class] || Array
  @decimal_class = opts[:decimal_class]
  @match_string = opts[:match_string]
end

Instance Method Details

#parseObject

Parses the current JSON string source and returns the complete data structure as a result.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/json/pure/parser.rb', line 117

def parse
  reset
  obj = nil
  while !eos? && skip(IGNORE) do end
  if eos?
    raise ParserError, "source is not valid JSON!"
  else
    obj = parse_value
    UNPARSED.equal?(obj) and raise ParserError,
      "source is not valid JSON!"
    obj.freeze if @freeze
  end
  while !eos? && skip(IGNORE) do end
  eos? or raise ParserError, "source is not valid JSON!"
  obj
end

#resetObject



110
111
112
113
# File 'lib/json/pure/parser.rb', line 110

def reset
  super
  @current_nesting = 0
end