使用Ruby来解析Tcl DSL

我希望能够解析一些Tcl代码,其中参数不被字符串包围。

考虑一下这个tcl代码:

proc foo {name} { puts "Foo --> $name" } foo bar 

对于那些不熟悉Tcl的人来说, foo是方法名称, bar是参数(引号在Tcl中是可选的)。

以前的代码将输出:

 Foo --> bar 

是否有可能使用ruby解析完全相同的输入( bar仍未加引号)?

等效的ruby代码是:

 def foo(name) puts "Foo --> #{name}" end tcl = <<-TCL.gsub(/^\s+/, "").chop foo bar TCL instance_eval(tcl) 

当然,当它到达bar时会失败,因为它预计会被引用。

我尝试过修改method_missing

 def method_missing(meth, *args) puts meth.to_s + " --> args.to_s end 

但它以相反的顺序解析:

 to_hash --> [] bar --> [] foo --> [nil] 

有没有人对这类问题有一个干净的解决方案。 我想避免对字符串进行标记,因为通过调用方法读取数据需要与词法分析相比最少的工作。 但如果我想做一些不可能的事情,我想知道。 谢谢。

这对你不起作用,因为.puts方法返回nil而不是string:

 irb(main):003:0> puts "42" 42 => nil 

我真的不知道为什么to_hash出现在这个method_missing但它有效:

 def foo(name) puts "Foo --> #{name}" end def method_missing(meth, *args) meth.to_s unless meth.to_s == "to_hash" end tcl = <<-TCL.gsub(/^\s+/, "").chop foo bar TCL instance_eval(tcl) => Foo --> bar 

这是一种尝试使语法接近TCL语法的实现。

 class TCL class << self alias run instance_eval def proc(n, &b) self.class.__send__(:define_method, n, &b) end def method_missing(n, *a, &b) n.to_s end end end TCL.run do proc(:foo) { |name| puts "Foo --> #{name}" } foo bar end # prints Foo --> bar