class JSON::Expect::Parser

Constants

FLOAT
INTEGER
NUM_FIRST
STRING

from json/pure

VERSION

Public Class Methods

new(input, opts = {}) click to toggle source
# 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

Public Instance Methods

array() { || ... } click to toggle source
# 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_null() { || ... } click to toggle source
# File lib/json/expect/parser.rb, line 271
def array_or_null
  null_or { array { yield } }
end
boolean() click to toggle source
# 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
float()
Alias for: number
integer() click to toggle source
# 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
key() click to toggle source
# 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
null() click to toggle source
# 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_or() { || ... } click to toggle source
# 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
number() click to toggle source
# 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
Also aliased as: float
object() { || ... } click to toggle source
# 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_null() { || ... } click to toggle source
# File lib/json/expect/parser.rb, line 267
def object_or_null
  null_or { object { yield } }
end
parse()
Alias for: value
rewind() click to toggle source
# File lib/json/expect/parser.rb, line 307
def rewind
  @buffer.rewind
end
string() click to toggle source
# 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
value() click to toggle source
# 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
Also aliased as: parse

Private Instance Methods

check_tail() click to toggle source
# File lib/json/expect/parser.rb, line 323
def check_tail
  case ch = @buffer.next_without_whitespace
  when ","
    raise ParseError, "unexpected \",\"" if @count_stack.empty?
    ch = @buffer.next_without_whitespace
    raise ParseError, "expected next token but was EOF" unless ch
    case ch
    when "]", "}", ","
      raise ParseError, "expected next token but was #{ch.inspect}"
    else
      @buffer.back
    end
  when nil
  else
    @buffer.back
  end
end
count_up() click to toggle source
# File lib/json/expect/parser.rb, line 313
def count_up
  if !@count_stack.empty?
    @count_stack[-1] += 1
  end
end
current_count() click to toggle source
# File lib/json/expect/parser.rb, line 319
def current_count
  @count_stack[-1]
end
expect_char(expect) click to toggle source
# File lib/json/expect/parser.rb, line 341
def expect_char(expect)
  actual = @buffer.next_without_whitespace
  unless actual == expect
    raise ParseError, "expected #{expect.inspect} but was #{actual.inspect}"
  end
  actual
end