- 论坛徽章:
- 0
|
就是lisp用的s表达式,可以向json一样用来读取保存的数据,也可以用来做DSL什么的。
代码的各种情况还考虑得不是很完全,等用到一种测试用例再来补充对应的实现吧。
这个实现对S表达式的格式以及这个解析函数在各方面都暂且以简单能用首要目的来着。
[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}
复制代码 |
|