lib/antelope/generator/ruby.rb in antelope-0.3.2 vs lib/antelope/generator/ruby.rb in antelope-0.4.0

- old
+ new

@@ -1,79 +1,112 @@ -# encoding: utf-8 - -require "pp" - -module Antelope - module Generator - - # Generates a ruby parser. - class Ruby < Base - - register_as "ruby", "rubby" - - has_directive "panic-mode", Boolean - has_directive "ruby.error-class", String - - # Creates an action table for the parser. - # - # @return [String] - def generate_action_table - out = "" - PP.pp(table, out) - out - end - - # Outputs an array of all of the productions. - # - # @return [String] - def generate_productions_list - out = "[" - - productions.each do |(label, size, block)| - out << - "[" << - label.name.inspect << - ", " << - size.inspect << - ", " - - block = if block.empty? - "DEFAULT_PROC" - else - "proc { |match| #{block[1..-2]} }" - end - - out << block << "],\n" - end - - out.chomp!( ",\n") - - out << "]" - end - - def define_own_handler? - directives.ruby.error_class? or - panic_mode? - end - - def panic_mode? - directives.panic_mode && - directives.ruby.error_class? && - grammar.contains_error_token? - end - - def error_class - directives.ruby.error_class - end - - # Actually performs the generation. Takes the template from - # ruby.ant and outputs it to `<file>.rb`. - # - # @return [void] - def generate - template "ruby", "#{file}.rb" do |body| - sprintf(grammar.compiler.body, write: body) - end - end - end - end -end +# encoding: utf-8 + +require 'pp' + +module Antelope + module Generator + # Generates a ruby parser. + class Ruby < Base + register_as 'ruby', 'rubby' + + has_directive 'output.panic-mode', Boolean + has_directive 'ruby.error-class', String + directive 'ruby.indent', Integer + + # Creates an action table for the parser. + # + # @return [String] + def generate_action_table + parts = [] + table.each do |state| + out = '' + state.each do |token, action| + inspect = %(:"#{token}" =>) + out << "#{basic_indent}#{inspect} #{action.inspect},\n" + end + parts << "{\n#{out.chomp(",\n")}\n}" + end + + "[#{parts.join(', ')}]" + end + + def indent + basic_indent * (directives.ruby.indent || 2) + end + + def basic_indent + @_indent ||= case indent_type + when 'space' + ' ' + when 'tab' + "\t" + else + indent_type + end * indent_size + end + + def indent_type + directives.ruby.indent_type || 'space' + end + + def indent_size + directives.ruby.indent_size || + case indent_type + when 'tab' + 1 + else + 2 + end + end + + # Outputs an array of all of the productions. + # + # @return [String] + def generate_productions_list + out = "[\n" + + productions.each do |(label, size, block)| + out << '[' << label.name.inspect << ', ' << + size.inspect << ', ' + + block = if block.empty? + 'DEFAULT_PROC' + else + "proc { |match| #{block[1..-2]} }" + end + + out << block << "],\n" + end + out.chomp!(",\n") + out << ']' + end + + def define_own_handler? + directives.ruby.error_class? || + panic_mode? + end + + def panic_mode? + directives.panic_mode && + directives.ruby.error_class? && + grammar.contains_error_token? + end + + def error_class + directives.ruby.error_class + end + + # Actually performs the generation. Takes the template from + # ruby.ant and outputs it to `<file>.rb`. + # + # @return [void] + def generate + template 'ruby', "#{file}.rb" do |body| + body + .gsub!("\n", "\n#{indent}") + .gsub!(/^[ \t]*\n/, "\n") + format(grammar.compiler.body, write: body) + end + end + end + end +end