Skip to content

Instantly share code, notes, and snippets.

@shanna
Forked from aarongough/sexp_benchmark.rb
Created October 15, 2010 05:20
Show Gist options
  • Save shanna/627665 to your computer and use it in GitHub Desktop.
Save shanna/627665 to your computer and use it in GitHub Desktop.
require 'benchmark'
require 'sexpistol'
require 'sxp'
require 'strscan'
class Lexer < StringScanner
def next_token
# Housekeeping.
skip /\s*/
return if eos?
@token = if scan %r{"([^"]*)"}
self[1]
elsif scan %r{ == | [()+*\-] | [a-z_][a-z0-9_]* }ix
matched.to_sym
elsif scan %r{[+-]?[0-9][0-9\.]*}
matched.to_i
else
# TODO: Unscan /\r\n|\r|\n/ to get line number.
near = scan %r{.{0,20}}
raise "Invalid character at position #{pos} near '#{near}'."
end
end
end
class Parser < Lexer
def self.parse(str)
Parser.new(str).parse
end
def parse
exp = []
while true
case next_token
when :'('
exp << parse
raise 'Missing closing parenthesis' if @token != :')'
when :')'
break
when String, Fixnum, Symbol
exp << @token
when nil
break
end
end
exp
end
end
example_sexp = <<-EOD
((display "This is a test string!")
(define test (lambda () (begin
(display (+ 1 1))
(display (+ true true))
(display (+ false false))
(display (+ nil nil))
(display (+ 2 1))
(display (+ 26 212))
))))
EOD
Benchmark.bmbm do |b|
b.report("Sexpistol") do
5000.times do
parser = Sexpistol.new
test = parser.parse_string(example_sexp)
end
end
b.report("SXP") do
5000.times do
test = SXP.read(example_sexp)
end
end
b.report("Ary") do
5000.times do
test = Parser.parse(example_sexp)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment