Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require 'benchmark'
- require 'sexpistol'
- require 'sxp'
- class Lexer
- def initialize(str)
- @str = str
- @p = 0
- end
- def next_token
- while true
- case c
- when nil
- return @token = nil
- when ' ', "\n", "\r", "\t"
- @p += 1
- next
- when '('
- @p += 1
- return @token = :'('
- when ')'
- @p += 1
- return @token = :')'
- when '"'
- start = @p
- while c! != '"' && c != nil
- end
- @p += 1
- return @token = @str[start + 1 ... @p - 1]
- when /[0-9\+\-]/
- start = @p
- @p += 1
- while true
- case c
- when /[0-9]/
- @p += 1
- else
- break
- end
- end
- return @token = @str[start ... @p].to_i
- when /[a-zA-Z\_]/
- start = @p
- while true
- case c
- when /[a-zA-Z0-9\_]/
- @p += 1
- else
- break
- end
- end
- return @token = @str[start ... @p].to_sym
- else
- raise 'Invalid character'
- end
- end
- end
- def c
- x = @str[@p]
- end
- def c!
- @p += 1
- c
- 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
Add Comment
Please, Sign In to add comment