就是lisp用的s表達(dá)式,可以向json一樣用來(lái)讀取保存的數(shù)據(jù),也可以用來(lái)做DSL什么的。
代碼的各種情況還考慮得不是很完全,等用到一種測(cè)試用例再來(lái)補(bǔ)充對(duì)應(yīng)的實(shí)現(xiàn)吧。
這個(gè)實(shí)現(xiàn)對(duì)S表達(dá)式的格式以及這個(gè)解析函數(shù)在各方面都暫且以簡(jiǎn)單能用首要目的來(lái)著。
[Ruby]代碼- 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}
復(fù)制代碼 |