class RVS::Parser

Public Class Methods

new(str) click to toggle source
# File lib/rvs/parse.rb, line 7
def initialize(str)
  @scan = StringScanner.new(str)
end

Public Instance Methods

get_chars(count) click to toggle source
# File lib/rvs/parse.rb, line 107
def get_chars(count)
  retval = @scan.peek(count)
  @scan.pos = @scan.pos + count
  retval
end
parse_array() click to toggle source
# File lib/rvs/parse.rb, line 66
def parse_array
  retval = []
  while !@scan.eos?
    next_char = @scan.peek(1)
    if next_char == ']'
      # throw away the closing ]
      @scan.getch
      break
    end
    # throw away the ,
    @scan.getch if next_char == ','
    retval.push(parse_item)
  end
  retval
end
parse_hash() click to toggle source
# File lib/rvs/parse.rb, line 82
def parse_hash
  retval = {}
  curr_key = nil
  while !@scan.eos?
    next_char = @scan.peek(1)
    if next_char == '}'
      # throw away the closing }
      @scan.getch
      break
    end
    # throw away the following delimiter chars
    @scan.getch if next_char == ','
    get_chars(2) if next_char == '='

    next_value = parse_item
    if curr_key
      retval[curr_key] = next_value
      curr_key = nil
    else
      curr_key = next_value
    end
  end
  retval
end
parse_item() click to toggle source
# File lib/rvs/parse.rb, line 15
def parse_item
  next_char = @scan.getch
  if next_char == '['
    parse_array
  elsif next_char == '{'
    parse_hash
  elsif next_char == '"'
    if @scan.peek(1) == '"'
      get_chars(1)
      ''
    else
      strval = '"' + @scan.scan(/.*?[^\\]+?\"/)
      Yajl::Parser.new.parse(strval)
    end
  elsif next_char == ':'
    @scan.scan(/[a-zA-Z_]+\w*/).to_sym
  elsif next_char == 'd'
    strval = @scan.scan(/[0-9-]+/)
    if @scan.peek(1) == ' '
      strval += get_chars(9)
      DateTime.strptime(strval, '%Y-%m-%d %H:%M:%S')
    else
      Date.strptime(strval, '%Y-%m-%d')
    end
  elsif next_char == 'f'
    if @scan.peek(1) == 'a'
      get_chars(4)
      false
    else
      @scan.scan(/-?[0-9\.]+/).to_f
    end
  elsif next_char == 't'
    if @scan.peek(1) == 'r'
      get_chars(3)
      true
    else
      Time.strptime(get_chars(19), '%Y-%m-%d %H:%M:%S')
    end
  elsif next_char == 'c'
    BigDecimal(@scan.scan(/-?[0-9\.]+/))
  elsif next_char == 'n'
    get_chars(2)
    nil
  elsif next_char =~ /[0-9-]/
    @scan.pos = @scan.pos - 1
    @scan.scan(/-?\d+/).to_i
  else
    raise "unexpected type identifier *#{next_char}*; string remainder is #{@scan.rest}"
  end
end
run() click to toggle source
# File lib/rvs/parse.rb, line 11
def run
  parse_item
end