1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/ext/ripper/tools/dsl.rb
mame 9b7fe0a250 ext/ripper: Introduce a simple DSL for ripper.y code generation
Currently, parse.y actions are hard to read and write because the code
has double meaning (for core parser and for ripper).  I think that, if
it is easy to write ripper's code shortly and simply, the double meaning
trick is not needed.

For the sake, this change adds a simple DSL for ripper's code.  For
example, in parse.y, we can write:

    /*% ripper: stmts_add(stmts_new, void_stmt) %*/

instead of:

    $$ = dispatch2(stmts_add, dispatch0(stmts_new),
                   dispatch0(void_stmt));

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61952 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-19 10:48:08 +00:00

46 lines
952 B
Ruby

# Simple DSL implementation for Ripper code generation
#
# input: /*% ripper: stmts_add(stmts_new, void_stmt) %*/
# output: $$ = dispatch2(stmts_add, dispatch0(stmts_new), dispatch0(void_stmt))
class DSL
def initialize(code, options)
@events = {}
@error = options.include?("error")
@brace = options.include?("brace")
# create $1 == "$1", $2 == "$2", ...
re, s = "", ""
1.upto(9) do |n|
re << "(..)"
s << "$#{ n }"
end
/#{ re }/ =~ s
@code = eval(code)
end
attr_reader :events
undef lambda
undef hash
undef class
def generate
s = "$$"
s = "\t\t\t#{ s } = #@code;"
s << "ripper_error(p);" if @error
s = "{#{ s }}" if @brace
s
end
def method_missing(*args)
if args.first =~ /\A_/
"#{ $' }(#{ args.drop(1).join(", ") })"
else
@events[args.first.to_s] = args.size - 1
"dispatch#{ args.size - 1 }(#{ args.join(", ") })"
end
end
end