class Jsonerino::Parser

Public Class Methods

new(lexer) click to toggle source
# File lib/jsonerino/parser.rb, line 8
def initialize(lexer)
  @lexer = lexer
  @current_token = lexer.next_token
  @previous_token = nil
end

Public Instance Methods

parse() click to toggle source
# File lib/jsonerino/parser.rb, line 14
def parse
  raise_end_of_data unless @current_token

  v = parse_json_value
  raise_unexpected_token unless v
  v
end
parse_json_value() click to toggle source
# File lib/jsonerino/parser.rb, line 22
def parse_json_value
  case @current_token.token
  when Token::TOKEN_LBRACKET
    parse_array
  when Token::TOKEN_LCURLY
    parse_object
  when Token::TOKEN_STRING
    JsonString.new consume(Token::TOKEN_STRING)
  when Token::TOKEN_NUMBER
    JsonNumber.new consume(Token::TOKEN_NUMBER)
  when Token::TOKEN_ID
    parse_id
  end
end

Private Instance Methods

consume(token) click to toggle source
# File lib/jsonerino/parser.rb, line 39
def consume(token)
  if @current_token.nil?
    raise_end_of_data
  elsif token != @current_token.token
    raise_unexpected_token
  end

  value = @current_token.value
  @previous_token = @current_token
  @current_token = @lexer.next_token
  value
end
parse_array() click to toggle source
# File lib/jsonerino/parser.rb, line 81
def parse_array
  consume Token::TOKEN_LBRACKET
  arr = JsonArray.new
  if @current_token && @current_token.token != Token::TOKEN_RBRACKET
    loop do
      arr.push parse
      break if @current_token && @current_token.token != Token::TOKEN_COMMA

      consume(Token::TOKEN_COMMA)
    end
  end
  consume Token::TOKEN_RBRACKET
  arr
end
parse_id() click to toggle source
# File lib/jsonerino/parser.rb, line 96
def parse_id
  case consume(Token::TOKEN_ID)
  when 'true'
    JsonBool.new true
  when 'false'
    JsonBool.new false
  when 'null'
    JsonNull.new
  else
    raise_unexpected_token
  end
end
parse_object() click to toggle source
# File lib/jsonerino/parser.rb, line 63
def parse_object
  consume Token::TOKEN_LCURLY
  obj = JsonObject.new
  if @current_token && @current_token.token != Token::TOKEN_RCURLY
    loop do
      key = consume(Token::TOKEN_STRING)
      consume(Token::TOKEN_COLON)
      value = parse
      obj.push key, value
      break if @current_token && @current_token.token != Token::TOKEN_COMMA

      consume(Token::TOKEN_COMMA)
    end
  end
  consume Token::TOKEN_RCURLY
  obj
end
raise_end_of_data() click to toggle source
# File lib/jsonerino/parser.rb, line 59
def raise_end_of_data
  raise JsonParseError.new, 'End of data while reading object contents of the JSON data'
end
raise_unexpected_token() click to toggle source
# File lib/jsonerino/parser.rb, line 52
def raise_unexpected_token
  token = @current_token.nil? ? @previous_token : @current_token
  message = "Unexpected token '#{token.value}'"\
            " at line #{token.line} column #{token.start} of the JSON data"
  raise JsonParseError.new, message
end