SHARE
TWEET

Untitled

a guest Feb 20th, 2019 66 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Wrote this in the bathtub just as a curiousity to see how hard it'd be :shrug:
  2. require 'strscan'
  3.  
  4. def scan(str)
  5.   tokens  = []
  6.   scanner = StringScanner.new str
  7.   loop do
  8.     next if scanner.scan /\s+/
  9.     token = scanner.scan /[()]/
  10.     next tokens << token if token
  11.     token = scanner.scan /[^\s()"']+/
  12.     next tokens << token if token
  13.     break
  14.   end
  15.   tokens# scanner.pos
  16. end
  17.  
  18. def parse(str)
  19.   tokens = scan str
  20.   stack = [[]]
  21.   until tokens.empty?
  22.     current = stack.last
  23.     token = tokens.shift
  24.     case token
  25.     when '('
  26.       stack.push []
  27.     when ')'
  28.       current = stack.pop
  29.       stack.last.push current
  30.     when /\A\d+\z/
  31.       stack.last.push token.to_f
  32.     else
  33.       stack.last.push token.intern
  34.     end
  35.   end
  36.   raise unless stack.one?
  37.   stack.pop
  38. end
  39.  
  40. parse <<~LISP
  41. (=(+(* a (square x))
  42.     (* b x)
  43.     c)
  44.   0)
  45. (= (f (x))
  46.    (square x))
  47. LISP
  48. # => [[:"=", [:+, [:*, :a, [:square, :x]], [:*, :b, :x], :c], 0.0],
  49. #     [:"=", [:f, [:x]], [:square, :x]]]
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top