Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Wrote this in the bathtub just as a curiousity to see how hard it'd be :shrug:
- require 'strscan'
- def scan(str)
- tokens = []
- scanner = StringScanner.new str
- loop do
- next if scanner.scan /\s+/
- token = scanner.scan /[()]/
- next tokens << token if token
- token = scanner.scan /[^\s()"']+/
- next tokens << token if token
- break
- end
- tokens# scanner.pos
- end
- def parse(str)
- tokens = scan str
- stack = [[]]
- until tokens.empty?
- current = stack.last
- token = tokens.shift
- case token
- when '('
- stack.push []
- when ')'
- current = stack.pop
- stack.last.push current
- when /\A\d+\z/
- stack.last.push token.to_f
- else
- stack.last.push token.intern
- end
- end
- raise unless stack.one?
- stack.pop
- end
- parse <<~LISP
- (=(+(* a (square x))
- (* b x)
- c)
- 0)
- (= (f (x))
- (square x))
- LISP
- # => [[:"=", [:+, [:*, :a, [:square, :x]], [:*, :b, :x], :c], 0.0],
- # [:"=", [:f, [:x]], [:square, :x]]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement