1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin LICENSE 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver[The "BSD licence"] 6324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverCopyright (c) 2009-2010 Kyle Yetter 7324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverAll rights reserved. 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 9324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverRedistribution and use in source and binary forms, with or without 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodification, are permitted provided that the following conditions 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverare met: 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 1. Redistributions of source code must retain the above copyright 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver notice, this list of conditions and the following disclaimer. 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 2. Redistributions in binary form must reproduce the above copyright 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver notice, this list of conditions and the following disclaimer in the 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver documentation and/or other materials provided with the distribution. 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 3. The name of the author may not be used to endorse or promote products 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver derived from this software without specific prior written permission. 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 21324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverTHIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'optparse' 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3' 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule ANTLR3 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Main 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 41324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverNamespace module for the quick script Main classes. 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule Main 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Main::Options 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 50324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDefines command-line options and attribute mappings shared by all types of 51324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverMain classes. 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule Options 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # the input encoding type; defaults to +nil+ (currently, not used) 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :encoding 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # the input stream used by the Main script; defaults to <tt>$stdin</tt> 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :input 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # a boolean flag indicating whether or not to run the Main 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # script in interactive mode; defaults to +false+ 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :interactive 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :no_output 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :profile 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :debug_socket 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :ruby_prof 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( options = {} ) 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @no_output = options.fetch( :no_output, false ) 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @profile = options.fetch( :profile, false ) 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @debug_socket = options.fetch( :debug_socket, false ) 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @ruby_prof = options.fetch( :ruby_prof, false ) 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @encoding = options.fetch( :encoding, nil ) 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @interactive = options.fetch( :interactive, false ) 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @input = options.fetch( :input, $stdin ) 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # constructs an OptionParser and parses the argument list provided by +argv+ 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def parse_options( argv = ARGV ) 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver oparser = OptionParser.new do | o | 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver o.separator 'Input Options:' 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver o.on( '-i', '--input "text to process"', doc( <<-END ) ) { |val| @input = val } 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | a string to use as direct input to the recognizer 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver o.on( '-I', '--interactive', doc( <<-END ) ) { @interactive = true } 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | run an interactive session with the recognizer 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver setup_options( oparser ) 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return oparser.parse( argv ) 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprivate 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def setup_options( oparser ) 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # overridable hook to modify / append options 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def doc( description_string ) 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver description_string.chomp! 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver description_string.gsub!( /^ *\| ?/, '' ) 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver description_string.gsub!( /\s+/, ' ' ) 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return description_string 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Main::Main 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 113324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverThe base-class for the three primary Main script-runner classes. 114324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverIt defines the skeletal structure shared by all main 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverscripts, but isn't particularly useful on its own. 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass Main 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include Options 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include Util 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :output, :error 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( options = {} ) 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @input = options.fetch( :input, $stdin ) 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @output = options.fetch( :output, $stdout ) 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @error = options.fetch( :error, $stderr ) 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @name = options.fetch( :name, File.basename( $0, '.rb' ) ) 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? and yield( self ) 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # runs the script 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def execute( argv = ARGV ) 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver args = parse_options( argv ) 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver setup 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @interactive and return execute_interactive 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver in_stream = 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when @input.is_a?( ::String ) then StringStream.new( @input ) 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when args.length == 1 && args.first != '-' 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3::FileStream.new( args[ 0 ] ) 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else ANTLR3::FileStream.new( @input ) 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when @ruby_prof 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver load_ruby_prof 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver profile = RubyProf.profile do 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver recognize( in_stream ) 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printer = RubyProf::FlatPrinter.new( profile ) 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printer.print( @output ) 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when @profile 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver require 'profiler' 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Profiler__.start_profile 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver recognize( in_stream ) 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Profiler__.print_profile 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver recognize( in_stream ) 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprivate 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def recognize( *args ) 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # overriden by subclasses 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def execute_interactive 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @output.puts( tidy( <<-END ) ) 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | =================================================================== 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | Ruby ANTLR Console for #{ $0 } 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | * Enter source code lines 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | * Enter EOF to finish up and exit 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | (control+D on Mac/Linux/Unix or control+Z on Windows) 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | =================================================================== 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver read_method = 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver require 'readline' 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line_number = 0 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver lambda do 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if line = Readline.readline( "#@name:#{ line_number += 1 }> ", true ) 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line << $/ 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @output.print( "\n" ) # ensures result output is on a new line after EOF is entered 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nil 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue Interrupt, EOFError 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver retry 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line << "\n" if line 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue LoadError 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver lambda do 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printf( "%s:%i> ", @name, @input.lineno ) 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver flush 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line = @input.gets or 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @output.print( "\n" ) # ensures result output is on a new line after EOF is entered 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue Interrupt, EOFError 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver retry 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stream = InteractiveStringStream.new( :name => @name, &read_method ) 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver recognize( stream ) 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def screen_width 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ( ENV[ 'COLUMNS' ] || 80 ).to_i 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def attempt( lib, message = nil, exit_status = nil ) 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver yield 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue LoadError => error 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message or raise 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @error.puts( message ) 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver report_error( error ) 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver report_load_path 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver exit( exit_status ) if exit_status 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue => error 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @error.puts( "received an error while attempting to load %p" % lib ) 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver report_error( error ) 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver exit( exit_status ) if exit_status 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def report_error( error ) 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver puts!( "~ error details:" ) 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver puts!( ' [ %s ]' % error.class.name ) 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver message = error.to_s.gsub( /\n/, "\n " ) 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver puts!( ' -> ' << message ) 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for call in error.backtrace 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver puts!( ' ' << call ) 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def report_load_path 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver puts!( "~ content of $LOAD_PATH: " ) 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for dir in $LOAD_PATH 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver puts!( " - #{ dir }" ) 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def setup 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # hook 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def fetch_class( name ) 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver name.nil? || name.empty? and return( nil ) 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver unless constant_exists?( name ) 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver try_to_load( name ) 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver constant_exists?( name ) or return( nil ) 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver name.split( /::/ ).inject( Object ) do |mod, name| 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # ::SomeModule splits to ['', 'SomeModule'] - so ignore empty strings 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver name.empty? and next( mod ) 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver mod.const_get( name ) 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def constant_exists?( name ) 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eval( "defined?(#{ name })" ) == 'constant' 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def try_to_load( name ) 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if name =~ /(\w+)::(Lexer|Parser|TreeParser)$/ 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver retry_ok = true 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver module_name, recognizer_type = $1, $2 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver script = name.gsub( /::/, '' ) 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( require( script ) ) 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue LoadError 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if retry_ok 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver script, retry_ok = module_name, false 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver retry 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( nil ) 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver %w(puts print printf flush).each do |method| 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver class_eval( <<-END, __FILE__, __LINE__ ) 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver private 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def #{ method }(*args) 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @output.#{ method }(*args) unless @no_output 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def #{ method }!( *args ) 305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @error.#{ method }(*args) unless @no_output 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Main::LexerMain 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 314324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA class which implements a handy test script which is executed whenever an ANTLR 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvergenerated lexer file is run directly from the command line. 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass LexerMain < Main 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( lexer_class, options = {} ) 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super( options ) 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @lexer_class = lexer_class 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def recognize( in_stream ) 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver lexer = @lexer_class.new( in_stream ) 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver loop do 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token = lexer.next_token 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if token.nil? || token.type == ANTLR3::EOF then break 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else display_token( token ) 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue ANTLR3::RecognitionError => error 334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver report_error( error ) 335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver break 336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def display_token( token ) 341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case token.channel 342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when ANTLR3::DEFAULT_CHANNEL 343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver prefix = '-->' 344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver suffix = '' 345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when ANTLR3::HIDDEN_CHANNEL 346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver prefix = '# ' 347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver suffix = ' (hidden)' 348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver prefix = '~~>' 350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver suffix = ' (channel %p)' % token.channel 351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printf( "%s %-15s %-15p @ line %-3i col %-3i%s\n", 354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver prefix, token.name, token.text, 355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token.line, token.column, suffix ) 356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Main::ParserMain 361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 362324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA class which implements a handy test script which is executed whenever an ANTLR 363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvergenerated parser file is run directly from the command line. 364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass ParserMain < Main 367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :lexer_class_name, 368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :lexer_class, 369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :parser_class, 370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :parser_rule, 371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :port, 372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver :log 373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( parser_class, options = {} ) 375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super( options ) 376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @lexer_class_name = options[ :lexer_class_name ] 377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @lexer_class = options[ :lexer_class ] 378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parser_class = parser_class 379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parser_rule = options[ :parser_rule ] 380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @debug = ( @parser_class.debug? rescue false ) 381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @trace = options.fetch( :trace, nil ) 382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @port = options.fetch( :port, ANTLR3::Debug::DEFAULT_PORT ) 383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @log = options.fetch( :log, @error ) 384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @profile = ( @parser_class.profile? rescue false ) 386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def setup_options( opt ) 389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super 390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.separator "" 392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.separator( "Parser Configuration:" ) 393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( '--lexer-name CLASS_NAME', "name of the lexer class to use" ) { |val| 395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @lexer_class_name = val 396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @lexer_class = nil 397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( '--lexer-file PATH_TO_LIBRARY', "path to library defining the lexer class" ) { |val| 400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin 401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver test( ?f, val ) ? load( val ) : require( val ) 402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue LoadError 403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver warn( "unable to load the library specified by --lexer-file: #{ $! }" ) 404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( '--rule NAME', "name of the parser rule to execute" ) { |val| @parser_rule = val } 408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @debug 410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.separator '' 411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.separator "Debug Mode Options:" 412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( '--trace', '-t', "print rule trace instead of opening a debug socket" ) do 414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @trace = true 415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( '--port NUMBER', Integer, "port number to use for the debug socket" ) do |number| 418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @port = number 419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( '--log PATH', "path of file to use to record socket activity", 422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "(stderr by default)" ) do |path| 423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @log = open( path, 'w' ) 424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def setup 429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver unless @lexer_class ||= fetch_class( @lexer_class_name ) 430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @lexer_class_name 431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fail( "unable to locate the lexer class ``#@lexer_class_name''" ) 432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver unless @lexer_class = @parser_class.associated_lexer 434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fail( doc( <<-END ) ) 435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | no lexer class has been specified with the --lexer-name option 436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | and #@parser_class does not appear to have an associated 437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | lexer class 438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parser_rule ||= @parser_class.default_rule or 443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fail( "a parser rule name must be specified via --rule NAME" ) 444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def recognize( in_stream ) 447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parser_options = {} 448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @debug 449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @trace 450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parser_options[ :debug_listener ] = ANTLR3::Debug::RuleTracer.new 451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parser_options[ :port ] = @port 453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parser_options[ :log ] = @log 454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver lexer = @lexer_class.new( in_stream ) 457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # token_stream = CommonTokenStream.new( lexer ) 458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parser = @parser_class.new( lexer, parser_options ) 459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result = parser.send( @parser_rule ) and present( result ) 460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @profile and puts( parser.generate_report ) 461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def present( return_value ) 464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ASTBuilder > @parser_class and return_value = return_value.tree 465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if return_value 466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = 467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin 468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver require 'pp' 469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return_value.pretty_inspect 470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue LoadError, NoMethodError 471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return_value.inspect 472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver puts( text ) 474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=begin rdoc ANTLR3::Main::WalkerMain 480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 481324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverA class which implements a handy test script which is executed whenever an ANTLR 482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvergenerated tree walker (tree parser) file is run directly from the command line. 483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver=end 485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass WalkerMain < Main 487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :walker_class, :lexer_class, :parser_class 488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( walker_class, options = {} ) 490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super( options ) 491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @walker_class = walker_class 492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @lexer_class_name = options[ :lexer_class_name ] 493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @lexer_class = options[ :lexer_class ] 494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parser_class_name = options[ :parser_class_name ] 495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parser_class = options[ :parser_class ] 496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @debug = ( @parser_class.debug? rescue false ) 497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @port = options.fetch( :port, ANTLR3::Debug::DEFAULT_PORT ) 498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @log = options.fetch( :log, @error ) 499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def setup_options( opt ) 503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super 504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.separator '' 506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.separator "Tree Parser Configuration:" 507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( '--lexer-name CLASS_NAME', 'full name of the lexer class to use' ) { |val| @lexer_class_name = val } 509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( 510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver '--lexer-file PATH_TO_LIBRARY', 511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 'path to load to make the lexer class available' 512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ) { |val| 513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin 514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver test( ?f, val ) ? load( val ) : require( val ) 515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue LoadError 516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver warn( "unable to load the library `#{ val }' specified by --lexer-file: #{ $! }" ) 517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( 521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver '--parser-name CLASS_NAME', 522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 'full name of the parser class to use' 523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ) { |val| @parser_class_name = val } 524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( 525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver '--parser-file PATH_TO_LIBRARY', 526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 'path to load to make the parser class available' 527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ) { |val| 528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver begin 529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver test( ?f, val ) ? load( val ) : require( val ) 530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rescue LoadError 531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver warn( "unable to load the library specified by --parser-file: #{ $! }" ) 532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( '--parser-rule NAME', "name of the parser rule to use on the input" ) { |val| @parser_rule = val } 536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( '--rule NAME', "name of the rule to invoke in the tree parser" ) { |val| @walker_rule = val } 537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @debug 539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.separator '' 540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.separator "Debug Mode Options:" 541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( '--port NUMBER', Integer, "port number to use for the debug socket" ) do |number| 543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @port = number 544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opt.on( '--log PATH', "path of file to use to record socket activity", 546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "(stderr by default)" ) do |path| 547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @log = open( path, 'w' ) 548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # TODO: finish the Main modules 553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def setup 554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver unless @lexer_class ||= fetch_class( @lexer_class_name ) 555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fail( "unable to locate the lexer class #@lexer_class_name" ) 556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver unless @parser_class ||= fetch_class( @parser_class_name ) 558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver fail( "unable to locate the parser class #@parser_class_name" ) 559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def recognize( in_stream ) 563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver walker_options = {} 564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if @debug 565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver walker_options[ :port ] = @port 566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver walker_options[ :log ] = @log 567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @lexer = @lexer_class.new( in_stream ) 569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @token_stream = ANTLR3::CommonTokenStream.new( @lexer ) 570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parser = @parser_class.new( @token_stream ) 571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if result = @parser.send( @parser_rule ) 572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.respond_to?( :tree ) or fail( "Parser did not return an AST for rule #@parser_rule" ) 573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @node_stream = ANTLR3::CommonTreeNodeStream.new( result.tree ) 574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @node_stream.token_stream = @token_stream 575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @walker = @walker_class.new( @node_stream, walker_options ) 576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if result = @walker.send( @walker_rule ) 577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver out = result.tree.inspect rescue result.inspect 578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver puts( out ) 579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else puts!( "walker.#@walker_rule returned nil" ) 580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else puts!( "parser.#@parser_rule returned nil" ) 582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 587