antlr3 1.6.0 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|