用 Ruby 进行简单的 lisp 表达式的解析

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

def parse(line)
  s = line.scan(/\(|\)|"(?:\\.|[^"])*"|[^()" \n]+/)
  f = ->(t=nil){
    case x = t || s.shift
    when ?(
      y = []
      while x = s.shift
        return y if x==?)
        y << f[x]
      end
      fail ")?"
    when nil
      nil
    when /^#(.*)$/
      {?t=>true,?f=>false}[$~[1]]
    when /\d+/
      x.to_i
    when /^\"(.*)\"$/m
      $~[1].gsub(/\\./,'\n'=>"\n","\\\\"=>"\\","\\\""=>'"')
    else
      x.to_sym
    end
  }
  f[]
end

$tests = {
  "" => nil,
  "1" => 1,
  "(a b)" => [:a,:b],
  "(1 2(2 3))" => [1,2,[2,3]],
  '(a"b"c"d"(ef))' => [:a,"b",:c,"d",[:ef]],
  '("a b" (c d-e))' => ["a b",[:c,:"d-e"]],
  "(\"a\nb\"\nb\nc (d))" => ["a\nb",:b,:c,[:d]],
  ' "a\nb"' => "a\nb",
  '"a\\"b"'=>'a"b',
  "\"\\\\\""=> "\\",
  "(#t #f)" => [true,false],
  "(define (f x) (if (zero? x) 0 (+ x (f (- x 1)))))" =>
    [:define,[:f,:x],[:if,[:zero?,:x],0,[:+,:x,[:f,[:-,:x,1]]]]],
}

p $tests.all?{|x,y|parse(x)==y}