Class: RVS::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/rvs/parse.rb

Instance Method Summary collapse

Constructor Details

#initialize(str) ⇒ Parser

Returns a new instance of Parser.



7
8
9
# File 'lib/rvs/parse.rb', line 7

def initialize(str)
  @scan = StringScanner.new(str)
end

Instance Method Details

#get_chars(count) ⇒ Object



107
108
109
110
111
# File 'lib/rvs/parse.rb', line 107

def get_chars(count)
  retval = @scan.peek(count)
  @scan.pos = @scan.pos + count
  retval
end

#parse_arrayObject



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# 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_hashObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# 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_itemObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 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

#runObject



11
12
13
# File 'lib/rvs/parse.rb', line 11

def run
  parse_item
end