1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3' 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'set' 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'rake' 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'rake/tasklib' 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'shellwords' 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule ANTLR3 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::CompileTask 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 14324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA rake task-generating utility concerning ANTLR grammar file 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvercompilation. This is a general utility -- the grammars do 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernot have to be targetted for Ruby output; it handles all 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverknown ANTLR language targets. 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver require 'antlr3/task' 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3::CompileTask.define( 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :name => 'grammars', :output_directory => 'lib/parsers' 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ) do | t | 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver t.grammar_set( 'antlr/MainParser.g', 'antlr/MainTree.g' ) 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver t.grammar_set( 'antlr/Template.g' ) do | gram | 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver gram.output_directory = 'lib/parsers/template' 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver gram.debug = true 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 33324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTODO: finish documentation 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass CompileTask < Rake::TaskLib 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_reader :grammar_sets, :options 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :name 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def self.define( *grammar_files ) 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver lib = new( *grammar_files ) 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? and yield( lib ) 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver lib.define 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( lib ) 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( *grammar_files ) 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar_files = [ grammar_files ].flatten! 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options = Hash === grammar_files.last ? grammar_files.pop : {} 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @grammar_sets = [] 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @name = options.fetch( :name, 'antlr-grammars' ) 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @options = options 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @namespace = Rake.application.current_scope 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar_files.empty? or grammar_set( grammar_files ) 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def target_files 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @grammar_sets.inject( [] ) do | list, set | 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list.concat( set.target_files ) 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def grammar_set( *grammar_files ) 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar_files = [ grammar_files ].flatten! 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options = @options.merge( 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Hash === grammar_files.last ? grammar_files.pop : {} 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ) 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set = GrammarSet.new( grammar_files, options ) 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? and yield( set ) 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @grammar_sets << set 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( set ) 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def compile_task 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver full_name = ( @namespace + [ @name, 'compile' ] ).join( ':' ) 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Rake::Task[ full_name ] 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def compile! 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver compile_task.invoke 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def clobber_task 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver full_name = ( @namespace + [ @name, 'clobber' ] ).join( ':' ) 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Rake::Task[ full_name ] 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def clobber! 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver clobber_task.invoke 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def define 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver namespace( @name ) do 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver desc( "trash all ANTLR-generated source code" ) 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver task( 'clobber' ) do 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for set in @grammar_sets 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set.clean 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for set in @grammar_sets 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver set.define_tasks 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver desc( "compile ANTLR grammars" ) 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver task( 'compile' => target_files ) 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#class CompileTask::GrammarSet 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass GrammarSet 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :antlr_jar, :debug, 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :trace, :profile, :compile_options, 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :java_options 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_reader :load_path, :grammars 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_writer :output_directory 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( grammar_files, options = {} ) 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @load_path = grammar_files.map { | f | File.dirname( f ) } 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @load_path.push( '.', @output_directory ) 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if extra_load = options[ :load_path ] 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver extra_load = [ extra_load ].flatten 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @load_path.unshift( extra_load ) 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @load_path.uniq! 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @grammars = grammar_files.map do | file | 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GrammarFile.new( self, file ) 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @output_directory = '.' 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver dir = options[ :output_directory ] and @output_directory = dir.to_s 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @antlr_jar = options.fetch( :antlr_jar, ANTLR3.antlr_jar ) 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @debug = options.fetch( :debug, false ) 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @trace = options.fetch( :trace, false ) 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @profile = options.fetch( :profile, false ) 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @compile_options = 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case opts = options[ :compile_options ] 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when Array then opts 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else Shellwords.shellwords( opts.to_s ) 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @java_options = 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case opts = options[ :java_options ] 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when Array then opts 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else Shellwords.shellwords( opts.to_s ) 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def target_files 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @grammars.map { | gram | gram.target_files }.flatten 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def output_directory 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @output_directory || '.' 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def define_tasks 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver file( @antlr_jar ) 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for grammar in @grammars 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver deps = [ @antlr_jar ] 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if vocab = grammar.token_vocab and 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tfile = find_tokens_file( vocab, grammar ) 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver file( tfile ) 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver deps << tfile 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar.define_tasks( deps ) 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def clean 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for grammar in @grammars 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar.clean 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if test( ?d, output_directory ) and ( Dir.entries( output_directory ) - %w( . .. ) ).empty? 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rmdir( output_directory ) 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def find_tokens_file( vocab, grammar ) 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver gram = @grammars.find { | gram | gram.name == vocab } and 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( gram.tokens_file ) 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver file = locate( "#{ vocab }.tokens" ) and return( file ) 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver warn( Util.tidy( <<-END, true ) ) 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | unable to locate .tokens file `#{ vocab }' referenced in #{ grammar.path } 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | -- ignoring dependency 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( nil ) 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def locate( file_name ) 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver dir = @load_path.find do | dir | 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver File.file?( File.join( dir, file_name ) ) 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver dir and return( File.join( dir, file_name ) ) 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def compile( grammar ) 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver dir = output_directory 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver test( ?d, dir ) or FileUtils.mkpath( dir ) 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver sh( build_command( grammar ) ) 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def build_command( grammar ) 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parts = [ 'java', '-cp', @antlr_jar ] 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parts.concat( @java_options ) 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parts << 'org.antlr.Tool' << '-fo' << output_directory 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parts << '-debug' if @debug 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parts << '-profile' if @profile 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parts << '-trace' if @trace 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parts.concat( @compile_options ) 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parts << grammar.path 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return parts.map! { | t | escape( t ) }.join( ' ' ) 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def escape( token ) 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token = token.to_s.dup 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token.empty? and return( %('') ) 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token.gsub!( /([^A-Za-z0-9_\-.,:\/@\n])/n, "\\\\\\1" ) 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token.gsub!( /\n/, "'\n'" ) 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( token ) 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass GrammarFile 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver LANGUAGES = { 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "ActionScript" => [ ".as" ], 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "CSharp2" => [ ".cs" ], 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "C" => [ ".c", ".h" ], 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "ObjC" => [ ".m", ".h" ], 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "CSharp3" => [ ".cs" ], 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Cpp" => [ ".cpp", ".h" ], 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Ruby" => [ ".rb" ], 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Java" => [ ".java" ], 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "JavaScript" => [ ".js" ], 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Python" => [ ".py" ], 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Delphi" => [ ".pas" ], 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Perl5" => [ ".pm" ] 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }.freeze 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GRAMMAR_TYPES = %w(lexer parser tree combined) 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ################################################################## 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ######## CONSTRUCTOR ############################################# 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ################################################################## 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( group, path, options = {} ) 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @group = group 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @path = path.to_s 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @imports = [] 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @language = 'Java' 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token_vocab = nil 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @tasks_defined = false 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @extra_dependencies = [] 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if extra = options[ :extra_dependencies ] 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver extra = [ extra ].flatten 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @extra_dependencies.concat( extra ) 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver study 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver yield( self ) if block_given? 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fetch_imports 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ################################################################## 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ######## ATTRIBUTES AND ATTRIBUTE-ISH METHODS #################### 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ################################################################## 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_reader :type, :name, :language, :source, 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :token_vocab, :imports, :imported_grammars, 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :path, :group 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for attr in [ :output_directory, :load_path, :antlr_jar ] 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver class_eval( <<-END ) 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def #{ attr } 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @group.#{ attr } 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def lexer_files 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if lexer? then base = @name 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver elsif combined? then base = @name + 'Lexer' 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else return( [] ) 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( file_names( base ) ) 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def parser_files 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if parser? then base = @name 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver elsif combined? then base = @name + 'Parser' 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else return( [] ) 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( file_names( base ) ) 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def tree_parser_files 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( tree? ? file_names( @name ) : [] ) 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def file_names( base ) 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver LANGUAGES.fetch( @language ).map do | ext | 305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver File.join( output_directory, base + ext ) 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for type in GRAMMAR_TYPES 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver class_eval( <<-END ) 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def #{ type }? 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @type == #{ type.inspect } 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def delegate_files( delegate_suffix ) 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver file_names( "#{ name }_#{ delegate_suffix }" ) 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def tokens_file 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver File.join( output_directory, name + '.tokens' ) 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def target_files( all = true ) 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver targets = [ tokens_file ] 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for target_type in %w( lexer parser tree_parser ) 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for file in self.send( :"#{ target_type }_files" ) 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver targets << file 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if all 335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for grammar in @imported_grammars 336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver targets.concat( grammar.target_files ) 337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return targets 341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def update 344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver touch( @path ) 345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def all_imported_files 348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver imported_files = [] 349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for grammar in @imported_grammars 350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver imported_files.push( grammar.path, *grammar.all_imported_files ) 351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return imported_files 353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def clean 356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver deleted = [] 357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for target in target_files 358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if test( ?f, target ) 359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rm( target ) 360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver deleted << target 361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for grammar in @imported_grammars 365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver deleted.concat( grammar.clean ) 366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return deleted 369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def define_tasks( shared_depends ) 372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver unless @tasks_defined 373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver depends = [ @path, *all_imported_files ] 374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for f in depends 375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver file( f ) 376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver depends = shared_depends + depends 378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver target_files.each do | target | 380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver file( target => ( depends - [ target ] ) ) do # prevents recursive .tokens file dependencies 381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @group.compile( self ) 382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @tasks_defined = true 386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprivate 390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def fetch_imports 392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @imported_grammars = @imports.map do | imp | 393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver file = group.locate( "#{ imp }.g" ) or raise( Util.tidy( <<-END ) ) 394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | #{ @path }: unable to locate imported grammar file #{ imp }.g 395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | search directories ( @load_path ): 396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | - #{ load_path.join( "\n - " ) } 397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Imported.new( self, file ) 399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def study 403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @source = File.read( @path ) 404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @source =~ /^\s*(lexer|parser|tree)?\s*grammar\s*(\S+)\s*;/ or 405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise Grammar::FormatError[ @source, @path ] 406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @name = $2 407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @type = $1 || 'combined' 408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @source =~ /^\s*options\s*\{(.*?)\}/m 409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver option_block = $1 410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if option_block =~ /\s*language\s*=\s*(\S+)\s*;/ 411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @language = $1 412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver LANGUAGES.has_key?( @language ) or 413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise( Grammar::FormatError, "Unknown ANTLR target language: %p" % @language ) 414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver option_block =~ /\s*tokenVocab\s*=\s*(\S+)\s*;/ and 416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token_vocab = $1 417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @source.scan( /^\s*import\s+(\w+\s*(?:,\s*\w+\s*)*);/ ) do 420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver list = $1.strip 421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @imports.concat( list.split( /\s*,\s*/ ) ) 422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # class Grammar 425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass GrammarFile::Imported < GrammarFile 427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( owner, path ) 428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @owner = owner 429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @path = path.to_s 430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @imports = [] 431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @language = 'Java' 432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token_vocab = nil 433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver study 434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fetch_imports 435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for attr in [ :load_path, :output_directory, :antlr_jar, :verbose, :group ] 438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver class_eval( <<-END ) 439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def #{ attr } 440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @owner.#{ attr } 441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def delegate_files( suffix ) 446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @owner.delegate_files( "#{ @name }_#{ suffix }" ) 447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def target_files 450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver targets = [ tokens_file ] 451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver targets.concat( @owner.delegate_files( @name ) ) 452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( targets ) 453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass GrammarFile::FormatError < StandardError 457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_reader :file, :source 458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def self.[]( *args ) 460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new( *args ) 461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( source, file = nil ) 464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @file = file 465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @source = source 466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message = '' 467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if file.nil? # inline 468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << "bad inline grammar source:\n" 469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << ( "-" * 80 ) << "\n" 470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << @source 471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message[ -1 ] == ?\n or message << "\n" 472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << ( "-" * 80 ) << "\n" 473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << "could not locate a grammar name and type declaration matching\n" 474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << "/^\s*(lexer|parser|tree)?\s*grammar\s*(\S+)\s*;/" 475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << 'bad grammar source in file %p\n' % @file 477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << ( "-" * 80 ) << "\n" 478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << @source 479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message[ -1 ] == ?\n or message << "\n" 480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << ( "-" * 80 ) << "\n" 481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << "could not locate a grammar name and type declaration matching\n" 482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message << "/^\s*(lexer|parser|tree)?\s*grammar\s*(\S+)\s*;/" 483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super( message ) 485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # error Grammar::FormatError 487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # class CompileTask 488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend # module ANTLR3 489