Class: SexpistolParser

Inherits:
StringScanner
  • Object
show all
Defined in:
lib/sexpistol/sexpistol_parser.rb

Instance Method Summary collapse

Constructor Details

#initialize(string) ⇒ SexpistolParser

Returns a new instance of SexpistolParser.



5
6
7
8
9
10
# File 'lib/sexpistol/sexpistol_parser.rb', line 5

def initialize(string)
  unless(string.count('(') == string.count(')'))
    raise Exception, "Missing closing parentheses"
  end
  super(string)
end

Instance Method Details

#fetch_tokenObject



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
# File 'lib/sexpistol/sexpistol_parser.rb', line 34

def fetch_token
  skip(/\s+/)
  return nil if(eos?)

  @token =
  # Match parentheses
  if scan(/[\(\)]/)
    matched
  # Match a string literal
  elsif scan(/"([^"\\]|\\.)*"/)
    eval(matched)
  # Match a float literal
  elsif scan(/[\-\+]? [0-9]+ ((e[0-9]+) | (\.[0-9]+(e[0-9]+)?))/x)
    matched.to_f
  # Match an integer literal
  elsif scan(/[\-\+]?[0-9]+/)
    matched.to_i
  # Match a comma (for comma quoting)
  elsif scan(/'/)
    matched.to_sym
  # Match a symbol
  elsif scan(/[^\(\)\s]+/)
    matched.to_sym
  # If we've gotten here then we have an invalid token
  else
    near = scan %r{.{0,20}}
    raise "Invalid character at position #{pos} near '#{near}'."
  end
end

#parseObject



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/sexpistol/sexpistol_parser.rb', line 12

def parse
  exp = []
  while true
    case fetch_token
      when '('
        exp << parse
      when ')'
        break
      when :"'"
        case fetch_token
        when '(' then exp << [:quote].concat([parse])
        else exp << [:quote, @token]
        end
      when String, Fixnum, Bignum, Float, Symbol
        exp << @token
      when nil
        break
    end
  end
  exp
end