lib/sexpistol/parser.rb in sexpistol-0.1.1 vs lib/sexpistol/parser.rb in sexpistol-0.1.2
- old
+ new
@@ -8,23 +8,25 @@
STRING = /"([^"\\]|\\.)*"/.freeze
FLOAT = /[\-+]? [0-9]+ ((e[0-9]+) | (\.[0-9]+(e[0-9]+)?)) (?=[\s()])/x.freeze
INTEGER = /([\-+]?[0-9]+)(?=[\s()])/.freeze
SYMBOL = /[^0-9()\s]+[^()\s]*/.freeze
- def initialize(string)
+ def initialize(string, parse_ruby_keyword_literals = false)
raise 'String given is not an s-expression' if string.strip[0] != '('
raise 'Invalid s-expression' if string.count('(') != string.count(')')
+ @parse_ruby_keyword_literals = parse_ruby_keyword_literals
+
super(string.strip)
end
def parse(level = 0, exp = [])
until eos?
case token = fetch_token
when ')' then break
when '(' then exp << parse(level + 1)
- when String, Integer, Float, Symbol then exp << token
+ when String, Integer, Float, Symbol then exp << convert_ruby_keyword_literals(token)
end
end
if level.zero?
exp = exp.first if exp.first.is_a?(Array) && exp.length == 1
@@ -42,8 +44,19 @@
return matched.to_f if scan(FLOAT)
return matched.to_i if scan(INTEGER)
return matched.to_sym if scan(SYMBOL)
raise "Invalid token at position #{pos} near '#{scan(/.{0,20}/)}'."
+ end
+
+ def convert_ruby_keyword_literals(token)
+ return token unless @parse_ruby_keyword_literals && token.is_a?(Symbol)
+
+ case token
+ when :nil then nil
+ when :true then true
+ when :false then false
+ else token
+ end
end
end
end