Class: JSON::Expect::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/json/expect/parser.rb,
lib/json/expect/parser/version.rb

Constant Summary collapse

NUM_FIRST =
/\A-|\d/
STRING =

from json/pure

/"(?:[^\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 =
/\A-?0|-?[1-9]\d*/
FLOAT =
/\A-?
  (?:0|[1-9]\d*)
  (?:
    \.\d+(?i:e[+-]?\d+) |
    \.\d+ |
    (?i:e[+-]?\d+)
  )?
/x
VERSION =
"0.0.1"

Instance Method Summary collapse

Constructor Details

#initialize(input, opts = {}) ⇒ Parser

Returns a new instance of Parser.


100
101
102
103
104
105
106
107
108
# File 'lib/json/expect/parser.rb', line 100

def initialize(input, opts = {})
  buffer_size = if opts[:buffer_size]
    opts[:buffer_size]
  else
    4092
  end
  @count_stack = []
  @buffer = Buffer.new(input, buffer_size)
end

Instance Method Details

#arrayObject


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/json/expect/parser.rb', line 133

def array
  return to_enum(:array) unless block_given?

  expect_char("[")
  count_up
  @count_stack.push(0)
  while true
    case ch = @buffer.next_without_whitespace
    when "]"
      check_tail
      break @count_stack.pop
    when nil
      raise ParseError, "expected any array item but EOF"
    else
      @buffer.back(ch.length)
      before_count = current_count
      yield
      raise ParseError, "nothing expectation in block" unless before_count != current_count
      check_tail
    end
  end
end

#array_or_nullObject


271
272
273
# File 'lib/json/expect/parser.rb', line 271

def array_or_null
  null_or { array { yield } }
end

#booleanObject


229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
# File 'lib/json/expect/parser.rb', line 229

def boolean
  case ch = @buffer.next_without_whitespace
  when "t"
    if "rue" == (rue = @buffer.next(3))
      count_up
      check_tail
      true
    else
      raise ParseError, "expected true or false but was \"#{ch}#{rue}\""
    end
  when "f"
    if "alse" == (alse = @buffer.next(4))
      count_up
      check_tail
      false
    else
      raise ParseError, "expected true or false but was \"#{ch}#{alse}\""
    end
  else
    raise ParseError, "expected true or false but was \"#{ch}\""
  end
end

#integerObject


181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/json/expect/parser.rb', line 181

def integer
  buffer = @buffer.next_without_whitespace
  if NUM_FIRST =~ buffer
    i = @buffer.next(16)
    buffer << i if i
    while m = INTEGER.match(buffer)
      break if m[0].length != buffer.length
      i = @buffer.next(16)
      break unless i
      buffer << i
    end
    raise ParseError, "expected integer but was #{buffer.inspect}" unless m
    @buffer.back(buffer.length - m[0].length)
    count_up
    check_tail
    m[0].to_i
  else
    raise ParseError, "expected integer but was #{buffer.inspect}"
  end
end

#keyObject


156
157
158
159
160
161
162
163
164
165
166
# File 'lib/json/expect/parser.rb', line 156

def key
  expect_char("\"")
  @buffer.back
  until m = @buffer.scan(STRING)
    if @buffer.fetch.nil?
      raise ParseError, "expected \"\"\" but was EOF"
    end
  end
  expect_char(":")
  m[1..-2]
end

#nullObject


252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/json/expect/parser.rb', line 252

def null
  case ch = @buffer.next_without_whitespace
  when "n"
    if "ull" == (ull = @buffer.next(3))
      count_up
      check_tail
      nil
    else
      raise ParseError, "expected null but was \"#{ch}#{ull}\""
    end
  else
    raise ParseError, "expected null but was #{ch.inspect}"
  end
end

#null_orObject


275
276
277
278
279
280
281
282
283
# File 'lib/json/expect/parser.rb', line 275

def null_or
  ch = @buffer.next_without_whitespace
  @buffer.back
  if ch == 'n'
    null
  else
    yield
  end
end

#numberObject Also known as: float


202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/json/expect/parser.rb', line 202

def number
  buffer = @buffer.next_without_whitespace
  if NUM_FIRST =~ buffer
    i = @buffer.next(16)
    buffer << i if i
    if buffer[-1] == "."
      i = @buffer.next(16)
      raise ParseError, "expected number after \".\" but nothing" unless i
      buffer << i
    end
    while m = FLOAT.match(buffer)
      break if m[0].length != buffer.length
      i = @buffer.next(16)
      break unless i
      buffer << i
    end
    raise ParseError, "expected number but was #{buffer.inspect}" unless m
    @buffer.back(buffer.length - m[0].length)
    count_up
    check_tail
    m[0].to_f
  else
    raise ParseError, "expected number but was #{buffer.inspect}"
  end
end

#objectObject


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/json/expect/parser.rb', line 110

def object
  return to_enum(:object) unless block_given?

  expect_char("{")
  count_up
  @count_stack.push(0)
  while true
    case ch = @buffer.next_without_whitespace
    when "}"
      check_tail
      break @count_stack.pop
    when "\""
      @buffer.back(ch.length)
      before_count = current_count
      yield
      raise ParseError, "nothing expectation in block" unless before_count != current_count
      check_tail
    else
      raise ParseError, "expected \"}\" or \"\"\" but was #{ch.inspect}"
    end
  end
end

#object_or_nullObject


267
268
269
# File 'lib/json/expect/parser.rb', line 267

def object_or_null
  null_or { object { yield } }
end

#rewindObject


307
308
309
# File 'lib/json/expect/parser.rb', line 307

def rewind
  @buffer.rewind
end

#stringObject


168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/json/expect/parser.rb', line 168

def string
  expect_char("\"")
  @buffer.back
  until m = @buffer.scan(STRING)
    if @buffer.fetch.nil?
      raise ParseError, "expected \"\"\" but was EOF"
    end
  end
  count_up
  check_tail
  m[1..-2]
end

#valueObject Also known as: parse


285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'lib/json/expect/parser.rb', line 285

def value
  ch = @buffer.next_without_whitespace
  @buffer.back
  case ch
  when "["
    array.map { value }
  when "{"
    Hash[object.map { [key, value] }]
  when "n"
    null
  when "t", "f"
    boolean
  when "\""
    string
  when NUM_FIRST
    number
  else
    raise ParseError, "expected any value but was #{ch.inspect}"
  end
end