diff --git a/ext/ripper/tools/dsl.rb b/ext/ripper/tools/dsl.rb index 3e368813e5..d0002d1ec3 100644 --- a/ext/ripper/tools/dsl.rb +++ b/ext/ripper/tools/dsl.rb @@ -20,6 +20,12 @@ class DSL NAME_PATTERN = /(?>\$|\d+|[a-zA-Z_][a-zA-Z0-9_]*|\[[a-zA-Z_.][-a-zA-Z0-9_.]*\])(?>(?:\.|->)[a-zA-Z_][a-zA-Z0-9_]*)*/.source NOT_REF_PATTERN = /(?>\#.*|[^\"$@]*|"(?>\\.|[^\"])*")/.source + def self.line?(line, lineno = nil) + if %r =~ line + new($2, $1&.split(",") || [], lineno) + end + end + def initialize(code, options, lineno = nil) @lineno = lineno @events = {} diff --git a/ext/ripper/tools/generate.rb b/ext/ripper/tools/generate.rb index 27aa53bce0..92ced37f04 100644 --- a/ext/ripper/tools/generate.rb +++ b/ext/ripper/tools/generate.rb @@ -167,15 +167,13 @@ require_relative "dsl" def read_ids1_with_locations(path) h = {} File.open(path) {|f| - f.each.with_index(1) do |line, i| + f.each do |line| next if /\A\#\s*define\s+dispatch/ =~ line next if /ripper_dispatch/ =~ line line.scan(/\bdispatch(\d)\((\w+)/) do |arity, event| (h[event] ||= []).push [f.lineno, arity.to_i] end - if line =~ %r - gen = DSL.new($2, ($1 || "").split(","), i) - gen.generate + if gen = DSL.line?(line, f.lineno) gen.events.each do |event, arity| (h[event] ||= []).push [f.lineno, arity.to_i] end diff --git a/ext/ripper/tools/preproc.rb b/ext/ripper/tools/preproc.rb index 25cd46e1be..a92be93d5b 100644 --- a/ext/ripper/tools/preproc.rb +++ b/ext/ripper/tools/preproc.rb @@ -53,50 +53,48 @@ end require_relative 'dsl' -RIPPER_CODE_PATTERN = %r +def generate_line(f, out) + while line = f.gets + case + when gen = DSL.line?(line) + out << gen.generate << "\n" + when line.start_with?("%%") + out << "%%\n" + break + else + out << yield(line) + end + end +end def prelude(f, out) @exprs = {} - while line = f.gets - case line - when /\A%%/ - out << "%%\n" - return - when RIPPER_CODE_PATTERN # %rule actions may contain /*% ripper: ... %*/ DSL - out << DSL.new($2, ($1 || "").split(",")).generate << "\n" - next - else - if (/^enum lex_state_(?:bits|e) \{/ =~ line)..(/^\}/ =~ line) - case line - when /^\s*(EXPR_\w+),\s+\/\*(.+)\*\// - @exprs[$1.chomp("_bit")] = $2.strip - when /^\s*(EXPR_\w+)\s+=\s+(.+)$/ - name = $1 - val = $2.chomp(",") - @exprs[name] = "equals to " + (val.start_with?("(") ? "#{val}" : "+#{val}+") - end + generate_line(f, out) do |line| + if (/^enum lex_state_(?:bits|e) \{/ =~ line)..(/^\}/ =~ line) + case line + when /^\s*(EXPR_\w+),\s+\/\*(.+)\*\// + @exprs[$1.chomp("_bit")] = $2.strip + when /^\s*(EXPR_\w+)\s+=\s+(.+)$/ + name = $1 + val = $2.chomp(",") + @exprs[name] = "equals to " + (val.start_with?("(") ? "#{val}" : "+#{val}+") end end - out << line + line end end def grammar(f, out) - while line = f.gets + generate_line(f, out) do |line| case line - when RIPPER_CODE_PATTERN - out << DSL.new($2, ($1 || "").split(",")).generate << "\n" when %r - out << "#if 0\n" + "#if 0\n" when %r - out << "#endif\n" + "#endif\n" when %r<%\*/> - out << "\n" - when /\A%%/ - out << "%%\n" - return + "\n" else - out << line + line end end end