summaryrefslogtreecommitdiff
path: root/ext/ripper/tools
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ripper/tools')
-rw-r--r--ext/ripper/tools/dsl.rb46
-rwxr-xr-xext/ripper/tools/generate.rb9
-rwxr-xr-xext/ripper/tools/preproc.rb4
3 files changed, 59 insertions, 0 deletions
diff --git a/ext/ripper/tools/dsl.rb b/ext/ripper/tools/dsl.rb
new file mode 100644
index 0000000000..e321019d7e
--- /dev/null
+++ b/ext/ripper/tools/dsl.rb
@@ -0,0 +1,46 @@
+# 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
+
diff --git a/ext/ripper/tools/generate.rb b/ext/ripper/tools/generate.rb
index cf24f1398d..883e6ef2df 100755
--- a/ext/ripper/tools/generate.rb
+++ b/ext/ripper/tools/generate.rb
@@ -135,6 +135,8 @@ def check_arity(h)
abort if invalid
end
+require_relative "dsl"
+
def read_ids1_with_locations(path)
h = {}
File.open(path) {|f|
@@ -144,6 +146,13 @@ def read_ids1_with_locations(path)
line.scan(/\bdispatch(\d)\((\w+)/) do |arity, event|
(h[event] ||= []).push [f.lineno, arity.to_i]
end
+ if line =~ %r</\*% *ripper(?:\[(.*?)\])?: *(.*?) *%\*/>
+ gen = DSL.new($2, ($1 || "").split(","))
+ gen.generate
+ gen.events.each do |event, arity|
+ (h[event] ||= []).push [f.lineno, arity.to_i]
+ end
+ end
end
}
h
diff --git a/ext/ripper/tools/preproc.rb b/ext/ripper/tools/preproc.rb
index 8b68579164..560a82e54f 100755
--- a/ext/ripper/tools/preproc.rb
+++ b/ext/ripper/tools/preproc.rb
@@ -72,9 +72,13 @@ def prelude(f, out)
end
end
+require_relative "dsl"
+
def grammar(f, out)
while line = f.gets
case line
+ when %r</\*% *ripper(?:\[(.*?)\])?: *(.*?) *%\*/>
+ out << DSL.new($2, ($1 || "").split(",")).generate << $/
when %r</\*%%%\*/>
out << '#if 0' << $/
when %r</\*%c%\*/>