antlr3 1.6.0 → 1.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +8 -0
- data/Manifest.txt +94 -0
- data/README.txt +1 -1
- data/Rakefile +58 -0
- data/bin/antlr4ruby +101 -7
- data/java/antlr-full-3.2.1.jar +0 -0
- data/lib/antlr3.rb +38 -10
- data/lib/antlr3/constants.rb +13 -5
- data/lib/antlr3/debug.rb +57 -57
- data/lib/antlr3/dfa.rb +138 -68
- data/lib/antlr3/dot.rb +32 -32
- data/lib/antlr3/error.rb +85 -78
- data/lib/antlr3/main.rb +191 -187
- data/lib/antlr3/profile.rb +71 -70
- data/lib/antlr3/recognizers.rb +261 -226
- data/lib/antlr3/streams.rb +85 -84
- data/lib/antlr3/streams/interactive.rb +20 -27
- data/lib/antlr3/streams/rewrite.rb +89 -89
- data/lib/antlr3/task.rb +42 -33
- data/lib/antlr3/template.rb +2 -2
- data/lib/antlr3/template/group-lexer.rb +1 -1
- data/lib/antlr3/token.rb +76 -68
- data/lib/antlr3/tree.rb +125 -121
- data/lib/antlr3/tree/visitor.rb +1 -1
- data/lib/antlr3/tree/wizard.rb +1 -1
- data/lib/antlr3/util.rb +32 -33
- data/lib/antlr3/version.rb +3 -3
- data/templates/Ruby.stg +1 -1
- data/test/unit/test-streams.rb +11 -10
- data/test/unit/test-template.rb +206 -204
- metadata +4 -2
data/lib/antlr3/main.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
=begin LICENSE
|
5
5
|
[The "BSD licence"]
|
6
|
-
Copyright (c) 2009 Kyle Yetter
|
6
|
+
Copyright (c) 2009-2010 Kyle Yetter
|
7
7
|
All rights reserved.
|
8
8
|
|
9
9
|
Redistribution and use in source and binary forms, with or without
|
@@ -65,58 +65,49 @@ module Options
|
|
65
65
|
attr_accessor :debug_socket
|
66
66
|
attr_accessor :ruby_prof
|
67
67
|
|
68
|
-
def initialize(options = {})
|
69
|
-
@no_output = options.fetch(:no_output, false)
|
70
|
-
@profile = options.fetch(:profile, false)
|
71
|
-
@debug_socket = options.fetch(:debug_socket, false)
|
72
|
-
@ruby_prof = options.fetch(:ruby_prof, false)
|
73
|
-
@encoding = options.fetch(:encoding, nil)
|
74
|
-
@interactive = options.fetch(:interactive, false)
|
75
|
-
@input = options.fetch(:input, $stdin)
|
68
|
+
def initialize( options = {} )
|
69
|
+
@no_output = options.fetch( :no_output, false )
|
70
|
+
@profile = options.fetch( :profile, false )
|
71
|
+
@debug_socket = options.fetch( :debug_socket, false )
|
72
|
+
@ruby_prof = options.fetch( :ruby_prof, false )
|
73
|
+
@encoding = options.fetch( :encoding, nil )
|
74
|
+
@interactive = options.fetch( :interactive, false )
|
75
|
+
@input = options.fetch( :input, $stdin )
|
76
76
|
end
|
77
77
|
|
78
78
|
# constructs an OptionParser and parses the argument list provided by +argv+
|
79
|
-
def parse_options(argv = ARGV)
|
80
|
-
oparser = OptionParser.new do |o|
|
81
|
-
o.
|
79
|
+
def parse_options( argv = ARGV )
|
80
|
+
oparser = OptionParser.new do | o |
|
81
|
+
o.separator 'Input Options:'
|
82
|
+
|
83
|
+
o.on( '-i', '--input "text to process"', doc( <<-END ) ) { |val| @input = val }
|
82
84
|
| a string to use as direct input to the recognizer
|
83
85
|
END
|
84
86
|
|
85
87
|
o.on( '-I', '--interactive', doc( <<-END ) ) { @interactive = true }
|
86
88
|
| run an interactive session with the recognizer
|
87
89
|
END
|
88
|
-
|
89
|
-
o.on( '--profile', doc( <<-END.chomp! ) ) { @profile = true }
|
90
|
-
| profile code execution using the standard profiler library
|
91
|
-
END
|
92
|
-
|
93
|
-
#o.on('--ruby-prof', doc(<<-END1), doc(<<-END2)) { @ruby_prof = true }
|
94
|
-
#| profile code execution using the faster ruby-prof
|
95
|
-
#END1
|
96
|
-
#| (requires rubygems with the ruby-prof gem)
|
97
|
-
#END2
|
98
90
|
end
|
99
91
|
|
100
92
|
setup_options( oparser )
|
101
|
-
return oparser.parse(argv)
|
93
|
+
return oparser.parse( argv )
|
102
94
|
end
|
103
95
|
|
104
|
-
|
105
|
-
|
96
|
+
private
|
97
|
+
|
98
|
+
def setup_options( oparser )
|
106
99
|
# overridable hook to modify / append options
|
107
100
|
end
|
108
101
|
|
109
102
|
def doc( description_string )
|
110
103
|
description_string.chomp!
|
111
|
-
description_string.gsub!(/^ *\| ?/,'')
|
112
|
-
description_string.gsub!(/\s+/,' ')
|
104
|
+
description_string.gsub!( /^ *\| ?/, '' )
|
105
|
+
description_string.gsub!( /\s+/, ' ' )
|
113
106
|
return description_string
|
114
107
|
end
|
115
108
|
|
116
109
|
end
|
117
110
|
|
118
|
-
|
119
|
-
|
120
111
|
=begin rdoc ANTLR3::Main::Main
|
121
112
|
|
122
113
|
The base-class for the three primary Main script-runner classes.
|
@@ -127,55 +118,61 @@ scripts, but isn't particularly useful on its own.
|
|
127
118
|
|
128
119
|
class Main
|
129
120
|
include Options
|
121
|
+
include Util
|
130
122
|
attr_accessor :output, :error
|
131
123
|
|
132
|
-
def initialize(options = {})
|
124
|
+
def initialize( options = {} )
|
133
125
|
@input = options.fetch( :input, $stdin )
|
134
126
|
@output = options.fetch( :output, $stdout )
|
135
127
|
@error = options.fetch( :error, $stderr )
|
136
|
-
@name = options.fetch( :name, File.basename($0, '.rb') )
|
128
|
+
@name = options.fetch( :name, File.basename( $0, '.rb' ) )
|
137
129
|
super
|
138
|
-
block_given? and yield(self)
|
130
|
+
block_given? and yield( self )
|
139
131
|
end
|
140
132
|
|
133
|
+
|
141
134
|
# runs the script
|
142
|
-
def execute(argv = ARGV)
|
143
|
-
args = parse_options(argv)
|
135
|
+
def execute( argv = ARGV )
|
136
|
+
args = parse_options( argv )
|
144
137
|
setup
|
145
138
|
|
146
139
|
@interactive and return execute_interactive
|
147
140
|
|
148
141
|
in_stream =
|
149
142
|
case
|
150
|
-
when @input.is_a?(::String) then StringStream.new(@input)
|
143
|
+
when @input.is_a?( ::String ) then StringStream.new( @input )
|
151
144
|
when args.length == 1 && args.first != '-'
|
152
|
-
ANTLR3::FileStream.new(args[0])
|
153
|
-
else ANTLR3::FileStream.new(@input)
|
145
|
+
ANTLR3::FileStream.new( args[ 0 ] )
|
146
|
+
else ANTLR3::FileStream.new( @input )
|
154
147
|
end
|
155
148
|
case
|
156
149
|
when @ruby_prof
|
157
150
|
load_ruby_prof
|
158
151
|
profile = RubyProf.profile do
|
159
|
-
recognize(in_stream)
|
152
|
+
recognize( in_stream )
|
160
153
|
end
|
161
|
-
printer = RubyProf::FlatPrinter.new(profile)
|
162
|
-
printer.print(@output)
|
154
|
+
printer = RubyProf::FlatPrinter.new( profile )
|
155
|
+
printer.print( @output )
|
163
156
|
when @profile
|
164
157
|
require 'profiler'
|
165
158
|
Profiler__.start_profile
|
166
|
-
recognize(in_stream)
|
159
|
+
recognize( in_stream )
|
167
160
|
Profiler__.print_profile
|
168
161
|
else
|
169
|
-
recognize(in_stream)
|
162
|
+
recognize( in_stream )
|
170
163
|
end
|
171
164
|
end
|
172
165
|
|
173
166
|
private
|
174
167
|
|
168
|
+
def recognize( *args )
|
169
|
+
# overriden by subclasses
|
170
|
+
end
|
171
|
+
|
175
172
|
def execute_interactive
|
176
|
-
@output.puts(
|
173
|
+
@output.puts( tidy( <<-END ) )
|
177
174
|
| ===================================================================
|
178
|
-
| Ruby ANTLR Console for #{$0}
|
175
|
+
| Ruby ANTLR Console for #{ $0 }
|
179
176
|
| ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
|
180
177
|
| * Enter source code lines
|
181
178
|
| * Enter EOF to finish up and exit
|
@@ -190,8 +187,12 @@ private
|
|
190
187
|
line_number = 0
|
191
188
|
lambda do
|
192
189
|
begin
|
193
|
-
line = Readline.readline("#@name:#{line_number += 1}> "
|
194
|
-
|
190
|
+
if line = Readline.readline( "#@name:#{ line_number += 1 }> ", true )
|
191
|
+
line << $/
|
192
|
+
else
|
193
|
+
@output.print( "\n" ) # ensures result output is on a new line after EOF is entered
|
194
|
+
nil
|
195
|
+
end
|
195
196
|
rescue Interrupt, EOFError
|
196
197
|
retry
|
197
198
|
end
|
@@ -201,9 +202,11 @@ private
|
|
201
202
|
rescue LoadError
|
202
203
|
lambda do
|
203
204
|
begin
|
204
|
-
printf("%s:%i> ", @name, @input.lineno)
|
205
|
+
printf( "%s:%i> ", @name, @input.lineno )
|
205
206
|
flush
|
206
|
-
line = @input.gets or
|
207
|
+
line = @input.gets or
|
208
|
+
@output.print( "\n" ) # ensures result output is on a new line after EOF is entered
|
209
|
+
line
|
207
210
|
rescue Interrupt, EOFError
|
208
211
|
retry
|
209
212
|
end
|
@@ -211,120 +214,95 @@ private
|
|
211
214
|
end
|
212
215
|
end
|
213
216
|
|
214
|
-
stream = InteractiveStringStream.new(:name => @name, &read_method)
|
215
|
-
recognize(stream)
|
217
|
+
stream = InteractiveStringStream.new( :name => @name, &read_method )
|
218
|
+
recognize( stream )
|
219
|
+
end
|
220
|
+
|
221
|
+
def screen_width
|
222
|
+
( ENV[ 'COLUMNS' ] || 80 ).to_i
|
216
223
|
end
|
217
224
|
|
218
|
-
|
219
|
-
# require 'ruby-prof'
|
220
|
-
#rescue LoadError
|
221
|
-
# attempt('rubygems', doc(<<-END)) { require 'rubygems' }
|
222
|
-
# | * failed to load the rubygems library:
|
223
|
-
# | - ensure rubygems is in installed
|
224
|
-
# | - make sure it is in this script's load path
|
225
|
-
# END
|
226
|
-
# attempt('ruby-prof', doc(<<-END)) { gem 'ruby-prof' }
|
227
|
-
# | * could not active the ruby-prof gem via ``gem "ruby-prof"''
|
228
|
-
# | - ensure the ruby-prof gem is installed
|
229
|
-
# | - it can be installed using the shell command
|
230
|
-
# | ``sudo gem install ruby-prof''
|
231
|
-
# END
|
232
|
-
# attempt('ruby-prof', doc(<<-END)) { require 'ruby-prof' }
|
233
|
-
# | * activated the ruby-prof gem, but subsequently failed to
|
234
|
-
# | load the ruby-prof library
|
235
|
-
# | - check for problems with the gem
|
236
|
-
# | - try restoring it to its initial install condition
|
237
|
-
# | using the shell command
|
238
|
-
# | ``sudo gem pristine ruby-prof''
|
239
|
-
# END
|
240
|
-
#end
|
241
|
-
|
242
|
-
#def load_prof
|
243
|
-
# attempt('profiler', doc(<<-END), 1) { require 'profiler' }
|
244
|
-
# | * failed to load the profiler library from the
|
245
|
-
# | ruby standard library
|
246
|
-
# | - ensure it is installed
|
247
|
-
# | - check that it is in this script's load path
|
248
|
-
# END
|
249
|
-
#end
|
250
|
-
|
251
|
-
def attempt(lib, message = nil, exit_status = nil)
|
225
|
+
def attempt( lib, message = nil, exit_status = nil )
|
252
226
|
yield
|
253
227
|
rescue LoadError => error
|
254
228
|
message or raise
|
255
|
-
@error.puts(message)
|
256
|
-
report_error(error)
|
229
|
+
@error.puts( message )
|
230
|
+
report_error( error )
|
257
231
|
report_load_path
|
258
|
-
exit(exit_status) if exit_status
|
232
|
+
exit( exit_status ) if exit_status
|
259
233
|
rescue => error
|
260
|
-
@error.puts("received an error while attempting to load %p" % lib)
|
261
|
-
report_error(error)
|
262
|
-
exit(exit_status) if exit_status
|
234
|
+
@error.puts( "received an error while attempting to load %p" % lib )
|
235
|
+
report_error( error )
|
236
|
+
exit( exit_status ) if exit_status
|
263
237
|
end
|
264
238
|
|
265
|
-
def report_error(error)
|
266
|
-
puts!("~ error details:")
|
267
|
-
puts!(' [ %s ]' % error.class.name)
|
268
|
-
message = error.to_s.gsub(/\n/, "\n ")
|
269
|
-
puts!(' -> ' << message)
|
239
|
+
def report_error( error )
|
240
|
+
puts!( "~ error details:" )
|
241
|
+
puts!( ' [ %s ]' % error.class.name )
|
242
|
+
message = error.to_s.gsub( /\n/, "\n " )
|
243
|
+
puts!( ' -> ' << message )
|
270
244
|
for call in error.backtrace
|
271
|
-
puts!(' ' << call)
|
245
|
+
puts!( ' ' << call )
|
272
246
|
end
|
273
247
|
end
|
274
248
|
|
275
249
|
def report_load_path
|
276
|
-
puts!("~ content of $LOAD_PATH: ")
|
250
|
+
puts!( "~ content of $LOAD_PATH: " )
|
277
251
|
for dir in $LOAD_PATH
|
278
|
-
puts!(" - #{dir}")
|
252
|
+
puts!( " - #{ dir }" )
|
279
253
|
end
|
280
254
|
end
|
281
255
|
|
282
256
|
def setup
|
257
|
+
# hook
|
283
258
|
end
|
284
259
|
|
285
|
-
def fetch_class(name)
|
286
|
-
name.nil? || name.empty? and return(nil)
|
287
|
-
unless constant_exists?(name)
|
288
|
-
try_to_load(name)
|
289
|
-
constant_exists?(name) or return(nil)
|
260
|
+
def fetch_class( name )
|
261
|
+
name.nil? || name.empty? and return( nil )
|
262
|
+
unless constant_exists?( name )
|
263
|
+
try_to_load( name )
|
264
|
+
constant_exists?( name ) or return( nil )
|
290
265
|
end
|
291
266
|
|
292
|
-
name.split(/::/).inject(Object) do |mod, name|
|
267
|
+
name.split( /::/ ).inject( Object ) do |mod, name|
|
293
268
|
# ::SomeModule splits to ['', 'SomeModule'] - so ignore empty strings
|
294
|
-
name.empty? and next(mod)
|
295
|
-
mod.const_get(name)
|
269
|
+
name.empty? and next( mod )
|
270
|
+
mod.const_get( name )
|
296
271
|
end
|
297
272
|
end
|
298
273
|
|
299
|
-
def constant_exists?(name)
|
300
|
-
eval("defined?(#{name})") == 'constant'
|
274
|
+
def constant_exists?( name )
|
275
|
+
eval( "defined?(#{ name })" ) == 'constant'
|
301
276
|
end
|
302
277
|
|
303
|
-
def try_to_load(name)
|
278
|
+
def try_to_load( name )
|
304
279
|
if name =~ /(\w+)::(Lexer|Parser|TreeParser)$/
|
305
280
|
retry_ok = true
|
306
|
-
|
281
|
+
module_name, recognizer_type = $1, $2
|
282
|
+
script = name.gsub( /::/, '' )
|
307
283
|
begin
|
308
|
-
return(require(script))
|
284
|
+
return( require( script ) )
|
309
285
|
rescue LoadError
|
310
286
|
if retry_ok
|
311
|
-
script, retry_ok =
|
287
|
+
script, retry_ok = module_name, false
|
312
288
|
retry
|
313
289
|
else
|
314
|
-
return(nil)
|
290
|
+
return( nil )
|
315
291
|
end
|
316
292
|
end
|
317
293
|
end
|
318
294
|
end
|
319
295
|
|
320
296
|
%w(puts print printf flush).each do |method|
|
321
|
-
class_eval(<<-END, __FILE__, __LINE__)
|
297
|
+
class_eval( <<-END, __FILE__, __LINE__ )
|
322
298
|
private
|
323
|
-
|
324
|
-
|
299
|
+
|
300
|
+
def #{ method }(*args)
|
301
|
+
@output.#{ method }(*args) unless @no_output
|
325
302
|
end
|
326
|
-
|
327
|
-
|
303
|
+
|
304
|
+
def #{ method }!( *args )
|
305
|
+
@error.#{ method }(*args) unless @no_output
|
328
306
|
end
|
329
307
|
END
|
330
308
|
end
|
@@ -350,7 +328,7 @@ class LexerMain < Main
|
|
350
328
|
begin
|
351
329
|
token = lexer.next_token
|
352
330
|
if token.nil? || token.type == ANTLR3::EOF then break
|
353
|
-
else display_token(token)
|
331
|
+
else display_token( token )
|
354
332
|
end
|
355
333
|
rescue ANTLR3::RecognitionError => error
|
356
334
|
report_error( error )
|
@@ -359,7 +337,7 @@ class LexerMain < Main
|
|
359
337
|
end
|
360
338
|
end
|
361
339
|
|
362
|
-
def display_token(token)
|
340
|
+
def display_token( token )
|
363
341
|
case token.channel
|
364
342
|
when ANTLR3::DEFAULT_CHANNEL
|
365
343
|
prefix = '-->'
|
@@ -372,9 +350,9 @@ class LexerMain < Main
|
|
372
350
|
suffix = ' (channel %p)' % token.channel
|
373
351
|
end
|
374
352
|
|
375
|
-
printf("%s %-15s %-15p @ line %-3i col %-3i%s\n",
|
353
|
+
printf( "%s %-15s %-15p @ line %-3i col %-3i%s\n",
|
376
354
|
prefix, token.name, token.text,
|
377
|
-
token.line, token.column, suffix)
|
355
|
+
token.line, token.column, suffix )
|
378
356
|
end
|
379
357
|
|
380
358
|
end
|
@@ -386,39 +364,57 @@ generated parser file is run directly from the command line.
|
|
386
364
|
|
387
365
|
=end
|
388
366
|
class ParserMain < Main
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
367
|
+
attr_accessor :lexer_class_name,
|
368
|
+
:lexer_class,
|
369
|
+
:parser_class,
|
370
|
+
:parser_rule,
|
371
|
+
:port,
|
372
|
+
:log
|
373
|
+
|
374
|
+
def initialize( parser_class, options = {} )
|
375
|
+
super( options )
|
376
|
+
@lexer_class_name = options[ :lexer_class_name ]
|
377
|
+
@lexer_class = options[ :lexer_class ]
|
393
378
|
@parser_class = parser_class
|
394
|
-
@parser_rule = options[:parser_rule]
|
395
|
-
if @debug = (@parser_class.debug? rescue false)
|
396
|
-
@port = options.fetch(:port, ANTLR3::Debug::DEFAULT_PORT)
|
397
|
-
@log = options.fetch(:log, @error)
|
379
|
+
@parser_rule = options[ :parser_rule ]
|
380
|
+
if @debug = ( @parser_class.debug? rescue false )
|
381
|
+
@port = options.fetch( :port, ANTLR3::Debug::DEFAULT_PORT )
|
382
|
+
@log = options.fetch( :log, @error )
|
398
383
|
end
|
399
384
|
end
|
400
385
|
|
401
|
-
def setup_options(opt)
|
386
|
+
def setup_options( opt )
|
402
387
|
super
|
403
|
-
|
388
|
+
|
389
|
+
opt.separator ""
|
390
|
+
opt.separator( "Parser Configuration:" )
|
391
|
+
|
392
|
+
opt.on( '--lexer-name CLASS_NAME', "name of the lexer class to use" ) { |val|
|
404
393
|
@lexer_class_name = val
|
405
394
|
@lexer_class = nil
|
406
395
|
}
|
407
|
-
|
396
|
+
|
397
|
+
opt.on( '--lexer-file PATH_TO_LIBRARY', "path to library defining the lexer class" ) { |val|
|
408
398
|
begin
|
409
|
-
test(?f, val) ? load(val) : require(val)
|
399
|
+
test( ?f, val ) ? load( val ) : require( val )
|
410
400
|
rescue LoadError
|
411
|
-
warn("unable to load the library specified by --lexer-file: #{$!}")
|
401
|
+
warn( "unable to load the library specified by --lexer-file: #{ $! }" )
|
412
402
|
end
|
413
403
|
}
|
414
|
-
|
404
|
+
|
405
|
+
opt.on( '--rule NAME', "name of the parser rule to execute" ) { |val| @parser_rule = val }
|
406
|
+
|
415
407
|
if @debug
|
416
|
-
opt.
|
408
|
+
opt.separator ''
|
409
|
+
opt.separator "Debug Mode Options:"
|
410
|
+
|
411
|
+
opt.on( '--port NUMBER', Integer, "port number to use for the debug socket" ) do |number|
|
417
412
|
@port = number
|
418
413
|
end
|
419
|
-
|
414
|
+
|
415
|
+
opt.on( '--log PATH', "path of file to use to record socket activity",
|
420
416
|
"(stderr by default)" ) do |path|
|
421
|
-
@log = open(path, 'w')
|
417
|
+
@log = open( path, 'w' )
|
422
418
|
end
|
423
419
|
end
|
424
420
|
end
|
@@ -426,10 +422,10 @@ class ParserMain < Main
|
|
426
422
|
def setup
|
427
423
|
unless @lexer_class ||= fetch_class( @lexer_class_name )
|
428
424
|
if @lexer_class_name
|
429
|
-
fail("unable to locate the lexer class ``#@lexer_class_name''")
|
425
|
+
fail( "unable to locate the lexer class ``#@lexer_class_name''" )
|
430
426
|
else
|
431
427
|
unless @lexer_class = @parser_class.associated_lexer
|
432
|
-
fail(doc(<<-END))
|
428
|
+
fail( doc( <<-END ) )
|
433
429
|
| no lexer class has been specified with the --lexer-name option
|
434
430
|
| and #@parser_class does not appear to have an associated
|
435
431
|
| lexer class
|
@@ -438,14 +434,14 @@ class ParserMain < Main
|
|
438
434
|
end
|
439
435
|
end
|
440
436
|
@parser_rule ||= @parser_class.default_rule or
|
441
|
-
fail("a parser rule name must be specified via --rule NAME")
|
437
|
+
fail( "a parser rule name must be specified via --rule NAME" )
|
442
438
|
end
|
443
439
|
|
444
|
-
def recognize(in_stream)
|
440
|
+
def recognize( in_stream )
|
445
441
|
parser_options = {}
|
446
442
|
if @debug
|
447
|
-
parser_options[:port] = @port
|
448
|
-
parser_options[:log]
|
443
|
+
parser_options[ :port ] = @port
|
444
|
+
parser_options[ :log ] = @log
|
449
445
|
end
|
450
446
|
lexer = @lexer_class.new( in_stream )
|
451
447
|
token_stream = CommonTokenStream.new( lexer )
|
@@ -462,7 +458,7 @@ class ParserMain < Main
|
|
462
458
|
rescue LoadError, NoMethodError
|
463
459
|
return_value.inspect
|
464
460
|
end
|
465
|
-
puts(text)
|
461
|
+
puts( text )
|
466
462
|
end
|
467
463
|
|
468
464
|
end
|
@@ -476,81 +472,89 @@ generated tree walker (tree parser) file is run directly from the command line.
|
|
476
472
|
|
477
473
|
class WalkerMain < Main
|
478
474
|
attr_accessor :walker_class, :lexer_class, :parser_class
|
479
|
-
|
480
|
-
|
475
|
+
|
476
|
+
def initialize( walker_class, options = {} )
|
477
|
+
super( options )
|
481
478
|
@walker_class = walker_class
|
482
|
-
@lexer_class_name = options[:lexer_class_name]
|
483
|
-
@lexer_class = options[:lexer_class]
|
484
|
-
@parser_class_name = options[:parser_class_name]
|
485
|
-
@parser_class = options[:parser_class]
|
486
|
-
if @debug = (@parser_class.debug? rescue false)
|
487
|
-
@port = options.fetch(:port, ANTLR3::Debug::DEFAULT_PORT)
|
488
|
-
@log = options.fetch(:log, @error)
|
479
|
+
@lexer_class_name = options[ :lexer_class_name ]
|
480
|
+
@lexer_class = options[ :lexer_class ]
|
481
|
+
@parser_class_name = options[ :parser_class_name ]
|
482
|
+
@parser_class = options[ :parser_class ]
|
483
|
+
if @debug = ( @parser_class.debug? rescue false )
|
484
|
+
@port = options.fetch( :port, ANTLR3::Debug::DEFAULT_PORT )
|
485
|
+
@log = options.fetch( :log, @error )
|
489
486
|
end
|
490
487
|
end
|
491
488
|
|
492
|
-
def setup_options(opt)
|
489
|
+
def setup_options( opt )
|
493
490
|
super
|
494
|
-
|
495
|
-
opt.
|
491
|
+
|
492
|
+
opt.separator ''
|
493
|
+
opt.separator "Tree Parser Configuration:"
|
494
|
+
|
495
|
+
opt.on( '--lexer-name CLASS_NAME' ) { |val| @lexer_class_name = val }
|
496
|
+
opt.on( '--lexer-file PATH_TO_LIBRARY' ) { |val|
|
496
497
|
begin
|
497
|
-
test(?f, val) ? load(val) : require(val)
|
498
|
+
test( ?f, val ) ? load( val ) : require( val )
|
498
499
|
rescue LoadError
|
499
|
-
warn("unable to load the library specified by --lexer-file: #{$!}")
|
500
|
+
warn( "unable to load the library specified by --lexer-file: #{ $! }" )
|
500
501
|
end
|
501
502
|
}
|
502
|
-
opt.on('--parser-name CLASS_NAME') { |val| @parser_class_name = val }
|
503
|
-
opt.on('--parser-file PATH_TO_LIBRARY') { |val|
|
503
|
+
opt.on( '--parser-name CLASS_NAME' ) { |val| @parser_class_name = val }
|
504
|
+
opt.on( '--parser-file PATH_TO_LIBRARY' ) { |val|
|
504
505
|
begin
|
505
|
-
test(?f, val) ? load(val) : require(val)
|
506
|
+
test( ?f, val ) ? load( val ) : require( val )
|
506
507
|
rescue LoadError
|
507
|
-
warn("unable to load the library specified by --parser-file: #{$!}")
|
508
|
+
warn( "unable to load the library specified by --parser-file: #{ $! }" )
|
508
509
|
end
|
509
510
|
}
|
510
|
-
opt.on('--parser-rule NAME') { |val| @parser_rule = val }
|
511
|
-
opt.on('--rule NAME') { |val| @walker_rule = val }
|
511
|
+
opt.on( '--parser-rule NAME' ) { |val| @parser_rule = val }
|
512
|
+
opt.on( '--rule NAME' ) { |val| @walker_rule = val }
|
512
513
|
|
513
514
|
if @debug
|
514
|
-
opt.
|
515
|
+
opt.separator ''
|
516
|
+
opt.separator "Debug Mode Options:"
|
517
|
+
|
518
|
+
opt.on( '--port NUMBER', Integer, "port number to use for the debug socket" ) do |number|
|
515
519
|
@port = number
|
516
520
|
end
|
517
|
-
opt.on('--log PATH', "path of file to use to record socket activity",
|
521
|
+
opt.on( '--log PATH', "path of file to use to record socket activity",
|
518
522
|
"(stderr by default)" ) do |path|
|
519
|
-
@log = open(path, 'w')
|
523
|
+
@log = open( path, 'w' )
|
520
524
|
end
|
521
525
|
end
|
522
526
|
end
|
523
527
|
|
524
528
|
# TODO: finish the Main modules
|
525
529
|
def setup
|
526
|
-
unless @lexer_class ||= fetch_class(@lexer_class_name)
|
527
|
-
fail("unable to locate the lexer class #@lexer_class_name")
|
530
|
+
unless @lexer_class ||= fetch_class( @lexer_class_name )
|
531
|
+
fail( "unable to locate the lexer class #@lexer_class_name" )
|
528
532
|
end
|
529
|
-
unless @parser_class ||= fetch_class(@parser_class_name)
|
530
|
-
fail("unable to locate the parser class #@parser_class_name")
|
533
|
+
unless @parser_class ||= fetch_class( @parser_class_name )
|
534
|
+
fail( "unable to locate the parser class #@parser_class_name" )
|
531
535
|
end
|
532
536
|
end
|
533
537
|
|
534
|
-
def recognize(in_stream)
|
538
|
+
def recognize( in_stream )
|
535
539
|
walker_options = {}
|
536
540
|
if @debug
|
537
|
-
walker_options[:port] = @port
|
538
|
-
walker_options[:log] = @log
|
541
|
+
walker_options[ :port ] = @port
|
542
|
+
walker_options[ :log ] = @log
|
539
543
|
end
|
540
|
-
@lexer = @lexer_class.new(in_stream)
|
541
|
-
@token_stream = ANTLR3::CommonTokenStream.new(@lexer)
|
542
|
-
@parser = @parser_class.new(@token_stream)
|
543
|
-
if result = @parser.send(@parser_rule)
|
544
|
-
result.respond_to?(:tree) or fail("Parser did not return an AST for rule #@parser_rule")
|
545
|
-
@node_stream = ANTLR3::CommonTreeNodeStream.new(result.tree)
|
544
|
+
@lexer = @lexer_class.new( in_stream )
|
545
|
+
@token_stream = ANTLR3::CommonTokenStream.new( @lexer )
|
546
|
+
@parser = @parser_class.new( @token_stream )
|
547
|
+
if result = @parser.send( @parser_rule )
|
548
|
+
result.respond_to?( :tree ) or fail( "Parser did not return an AST for rule #@parser_rule" )
|
549
|
+
@node_stream = ANTLR3::CommonTreeNodeStream.new( result.tree )
|
546
550
|
@node_stream.token_stream = @token_stream
|
547
|
-
@walker = @walker_class.new(@node_stream, walker_options)
|
548
|
-
if result = @walker.send(@walker_rule)
|
551
|
+
@walker = @walker_class.new( @node_stream, walker_options )
|
552
|
+
if result = @walker.send( @walker_rule )
|
549
553
|
out = result.tree.inspect rescue result.inspect
|
550
|
-
puts(out)
|
551
|
-
else puts!("walker.#@walker_rule returned nil")
|
554
|
+
puts( out )
|
555
|
+
else puts!( "walker.#@walker_rule returned nil" )
|
552
556
|
end
|
553
|
-
else puts!("parser.#@parser_rule returned nil")
|
557
|
+
else puts!( "parser.#@parser_rule returned nil" )
|
554
558
|
end
|
555
559
|
end
|
556
560
|
end
|