开发者

Use Ruby to parse a Tcl DSL

I would like to be able to parse some Tcl code where arguments are not surrounded by strings.

Consider this tcl code:

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

foo bar

For those unfamiliar with Tcl, foo is the method name and bar is the argument (quotes are optional in Tcl).

The previous code will output:

Foo --> bar

Is it possible to parse exactly the same input using ruby (bar remains unquoted)?

The equivalent ruby code is:

def foo(name)
  puts "Foo --> #{name}"
end

tcl = <<-TCL.gsub(/^\s+/, "").chop
  foo bar
TCL
instance_eval(tcl)

Of course that fails when it reaches bar since it's expected it to be quoted.

I've tried tinkering with method_missing

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

but it parses in reverse order:

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

Does anyone have a clean solution to this type of problem. I'd like to avoid tokeniz开发者_如何学Cing the strings since reading the data in by calling a method requires minimal work compared to lexical analysis. But if I'm trying to do something that's not possible, I'd like to know. Thanks.


It's doesn't work for you because .puts method returns nil instead of string:

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

I really don't know why to_hash appears in this method_missing but it works:

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


This is an implementation that try to make the syntax near to the TCL syntax.

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜