antlr3 1.2.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.
Files changed (85) hide show
  1. data/ANTLR-LICENSE.txt +26 -0
  2. data/History.txt +66 -0
  3. data/README.txt +139 -0
  4. data/bin/antlr4ruby +33 -0
  5. data/java/RubyTarget.java +524 -0
  6. data/java/antlr-full-3.2.1.jar +0 -0
  7. data/lib/antlr3.rb +176 -0
  8. data/lib/antlr3/constants.rb +88 -0
  9. data/lib/antlr3/debug.rb +701 -0
  10. data/lib/antlr3/debug/event-hub.rb +210 -0
  11. data/lib/antlr3/debug/record-event-listener.rb +25 -0
  12. data/lib/antlr3/debug/rule-tracer.rb +55 -0
  13. data/lib/antlr3/debug/socket.rb +360 -0
  14. data/lib/antlr3/debug/trace-event-listener.rb +92 -0
  15. data/lib/antlr3/dfa.rb +247 -0
  16. data/lib/antlr3/dot.rb +174 -0
  17. data/lib/antlr3/error.rb +657 -0
  18. data/lib/antlr3/main.rb +561 -0
  19. data/lib/antlr3/modes/ast-builder.rb +41 -0
  20. data/lib/antlr3/modes/filter.rb +56 -0
  21. data/lib/antlr3/profile.rb +322 -0
  22. data/lib/antlr3/recognizers.rb +1280 -0
  23. data/lib/antlr3/streams.rb +985 -0
  24. data/lib/antlr3/streams/interactive.rb +91 -0
  25. data/lib/antlr3/streams/rewrite.rb +412 -0
  26. data/lib/antlr3/test/call-stack.rb +57 -0
  27. data/lib/antlr3/test/config.rb +23 -0
  28. data/lib/antlr3/test/core-extensions.rb +269 -0
  29. data/lib/antlr3/test/diff.rb +165 -0
  30. data/lib/antlr3/test/functional.rb +207 -0
  31. data/lib/antlr3/test/grammar.rb +371 -0
  32. data/lib/antlr3/token.rb +592 -0
  33. data/lib/antlr3/tree.rb +1415 -0
  34. data/lib/antlr3/tree/debug.rb +163 -0
  35. data/lib/antlr3/tree/visitor.rb +84 -0
  36. data/lib/antlr3/tree/wizard.rb +481 -0
  37. data/lib/antlr3/util.rb +149 -0
  38. data/lib/antlr3/version.rb +27 -0
  39. data/samples/ANTLRv3Grammar.g +621 -0
  40. data/samples/Cpp.g +749 -0
  41. data/templates/AST.stg +335 -0
  42. data/templates/ASTDbg.stg +40 -0
  43. data/templates/ASTParser.stg +153 -0
  44. data/templates/ASTTreeParser.stg +272 -0
  45. data/templates/Dbg.stg +192 -0
  46. data/templates/Ruby.stg +1514 -0
  47. data/test/functional/ast-output/auto-ast.rb +797 -0
  48. data/test/functional/ast-output/construction.rb +555 -0
  49. data/test/functional/ast-output/hetero-nodes.rb +753 -0
  50. data/test/functional/ast-output/rewrites.rb +1327 -0
  51. data/test/functional/ast-output/tree-rewrite.rb +1662 -0
  52. data/test/functional/debugging/debug-mode.rb +689 -0
  53. data/test/functional/debugging/profile-mode.rb +165 -0
  54. data/test/functional/debugging/rule-tracing.rb +74 -0
  55. data/test/functional/delegation/import.rb +379 -0
  56. data/test/functional/lexer/basic.rb +559 -0
  57. data/test/functional/lexer/filter-mode.rb +245 -0
  58. data/test/functional/lexer/nuances.rb +47 -0
  59. data/test/functional/lexer/properties.rb +104 -0
  60. data/test/functional/lexer/syn-pred.rb +32 -0
  61. data/test/functional/lexer/xml.rb +206 -0
  62. data/test/functional/main/main-scripts.rb +245 -0
  63. data/test/functional/parser/actions.rb +224 -0
  64. data/test/functional/parser/backtracking.rb +244 -0
  65. data/test/functional/parser/basic.rb +282 -0
  66. data/test/functional/parser/calc.rb +98 -0
  67. data/test/functional/parser/ll-star.rb +143 -0
  68. data/test/functional/parser/nuances.rb +165 -0
  69. data/test/functional/parser/predicates.rb +103 -0
  70. data/test/functional/parser/properties.rb +242 -0
  71. data/test/functional/parser/rule-methods.rb +132 -0
  72. data/test/functional/parser/scopes.rb +274 -0
  73. data/test/functional/token-rewrite/basic.rb +318 -0
  74. data/test/functional/token-rewrite/via-parser.rb +100 -0
  75. data/test/functional/tree-parser/basic.rb +750 -0
  76. data/test/unit/sample-input/file-stream-1 +2 -0
  77. data/test/unit/sample-input/teststreams.input2 +2 -0
  78. data/test/unit/test-dfa.rb +52 -0
  79. data/test/unit/test-exceptions.rb +44 -0
  80. data/test/unit/test-recognizers.rb +55 -0
  81. data/test/unit/test-scheme.rb +62 -0
  82. data/test/unit/test-streams.rb +459 -0
  83. data/test/unit/test-tree-wizard.rb +535 -0
  84. data/test/unit/test-trees.rb +854 -0
  85. metadata +205 -0
@@ -0,0 +1,561 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ =begin LICENSE
5
+
6
+ [The "BSD licence"]
7
+ Copyright (c) 2009 Kyle Yetter
8
+ All rights reserved.
9
+
10
+ Redistribution and use in source and binary forms, with or without
11
+ modification, are permitted provided that the following conditions
12
+ are met:
13
+
14
+ 1. Redistributions of source code must retain the above copyright
15
+ notice, this list of conditions and the following disclaimer.
16
+ 2. Redistributions in binary form must reproduce the above copyright
17
+ notice, this list of conditions and the following disclaimer in the
18
+ documentation and/or other materials provided with the distribution.
19
+ 3. The name of the author may not be used to endorse or promote products
20
+ derived from this software without specific prior written permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+
33
+ =end
34
+
35
+ require 'optparse'
36
+ require 'antlr3'
37
+
38
+ module ANTLR3
39
+
40
+ =begin rdoc ANTLR3::Main
41
+
42
+ Namespace module for the quick script Main classes.
43
+
44
+ =end
45
+
46
+ module Main
47
+
48
+
49
+ =begin rdoc ANTLR3::Main::Options
50
+
51
+ Defines command-line options and attribute mappings shared by all types of
52
+ Main classes.
53
+
54
+ =end
55
+
56
+ module Options
57
+ # the input encoding type; defaults to +nil+ (currently, not used)
58
+ attr_accessor :encoding
59
+ # the input stream used by the Main script; defaults to <tt>$stdin</tt>
60
+ attr_accessor :input
61
+ # a boolean flag indicating whether or not to run the Main
62
+ # script in interactive mode; defaults to +false+
63
+ attr_accessor :interactive
64
+ attr_accessor :no_output
65
+ attr_accessor :profile
66
+ attr_accessor :debug_socket
67
+ attr_accessor :ruby_prof
68
+
69
+ def initialize(options = {})
70
+ @no_output = options.fetch(:no_output, false)
71
+ @profile = options.fetch(:profile, false)
72
+ @debug_socket = options.fetch(:debug_socket, false)
73
+ @ruby_prof = options.fetch(:ruby_prof, false)
74
+ @encoding = options.fetch(:encoding, nil)
75
+ @interactive = options.fetch(:interactive, false)
76
+ @input = options.fetch(:input, $stdin)
77
+ end
78
+
79
+ # constructs an OptionParser and parses the argument list provided by +argv+
80
+ def parse_options(argv = ARGV)
81
+ oparser = OptionParser.new do |o|
82
+ o.on('-i', '--input "text to process"', doc(<<-END)) { |val| @input = val }
83
+ | a string to use as direct input to the recognizer
84
+ END
85
+
86
+ o.on( '-I', '--interactive', doc( <<-END ) ) { @interactive = true }
87
+ | run an interactive session with the recognizer
88
+ END
89
+
90
+ o.on( '--profile', doc( <<-END.chomp! ) ) { @profile = true }
91
+ | profile code execution using the standard profiler library
92
+ END
93
+
94
+ #o.on('--ruby-prof', doc(<<-END1), doc(<<-END2)) { @ruby_prof = true }
95
+ #| profile code execution using the faster ruby-prof
96
+ #END1
97
+ #| (requires rubygems with the ruby-prof gem)
98
+ #END2
99
+ end
100
+
101
+ setup_options( oparser )
102
+ return oparser.parse(argv)
103
+ end
104
+
105
+ private
106
+ def setup_options(oparser)
107
+ # overridable hook to modify / append options
108
+ end
109
+
110
+ def doc( description_string )
111
+ description_string.chomp!
112
+ description_string.gsub!(/^ *\| ?/,'')
113
+ description_string.gsub!(/\s+/,' ')
114
+ return description_string
115
+ end
116
+
117
+ end
118
+
119
+
120
+
121
+ =begin rdoc ANTLR3::Main::Main
122
+
123
+ The base-class for the three primary Main script-runner classes.
124
+ It defines the skeletal structure shared by all main
125
+ scripts, but isn't particularly useful on its own.
126
+
127
+ =end
128
+
129
+ class Main
130
+ include Options
131
+ attr_accessor :output, :error
132
+
133
+ def initialize(options = {})
134
+ @input = options.fetch( :input, $stdin )
135
+ @output = options.fetch( :output, $stdout )
136
+ @error = options.fetch( :error, $stderr )
137
+ @name = options.fetch( :name, File.basename($0, '.rb') )
138
+ super
139
+ block_given? and yield(self)
140
+ end
141
+
142
+ # runs the script
143
+ def execute(argv = ARGV)
144
+ args = parse_options(argv)
145
+ setup
146
+
147
+ @interactive and return execute_interactive
148
+
149
+ in_stream =
150
+ case
151
+ when @input.is_a?(::String) then StringStream.new(@input)
152
+ when args.length == 1 && args.first != '-'
153
+ ANTLR3::FileStream.new(args[0])
154
+ else ANTLR3::FileStream.new(@input)
155
+ end
156
+ case
157
+ when @ruby_prof
158
+ load_ruby_prof
159
+ profile = RubyProf.profile do
160
+ recognize(in_stream)
161
+ end
162
+ printer = RubyProf::FlatPrinter.new(profile)
163
+ printer.print(@output)
164
+ when @profile
165
+ require 'profiler'
166
+ Profiler__.start_profile
167
+ recognize(in_stream)
168
+ Profiler__.print_profile
169
+ else
170
+ recognize(in_stream)
171
+ end
172
+ end
173
+
174
+ private
175
+ def execute_interactive
176
+ @output.puts( Util.tidy(<<-END) )
177
+ | ===================================================================
178
+ | Ruby ANTLR Console for #{$0}
179
+ | ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
180
+ | * Enter source code lines
181
+ | * Enter EOF to finish up and exit
182
+ | (control+D on Mac/Linux/Unix or control+Z on Windows)
183
+ | ===================================================================
184
+ |
185
+ END
186
+
187
+ read_method =
188
+ begin
189
+ require 'readline'
190
+ line_number = 0
191
+ lambda do
192
+ begin
193
+ line = Readline.readline("#@name:#{line_number += 1}> ") or
194
+ @output.print("\n") # ensures result output is on a new line after EOF is entered
195
+ rescue Interrupt, EOFError
196
+ retry
197
+ end
198
+ line << "\n" if line
199
+ end
200
+
201
+ rescue LoadError
202
+ lambda do
203
+ begin
204
+ printf("%s:%i> ", @name, @input.lineno)
205
+ flush
206
+ line = @input.gets or @output.print("\n") # ensures result output is on a new line after EOF is entered
207
+ rescue Interrupt, EOFError
208
+ retry
209
+ end
210
+ line
211
+ end
212
+ end
213
+
214
+ stream = InteractiveStringStream.new(:name => @name, &read_method)
215
+ recognize(stream)
216
+ end
217
+
218
+ #def load_ruby_prof
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)
252
+ yield
253
+ rescue LoadError => error
254
+ message or raise
255
+ @error.puts(message)
256
+ report_error(error)
257
+ report_load_path
258
+ exit(exit_status) if exit_status
259
+ 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
263
+ end
264
+
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)
270
+ for call in error.backtrace
271
+ puts!(' ' << call)
272
+ end
273
+ end
274
+
275
+ def report_load_path
276
+ puts!("~ content of $LOAD_PATH: ")
277
+ for dir in $LOAD_PATH
278
+ puts!(" - #{dir}")
279
+ end
280
+ end
281
+
282
+ def setup
283
+ end
284
+
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)
290
+ end
291
+
292
+ name.split(/::/).inject(Object) do |mod, name|
293
+ # ::SomeModule splits to ['', 'SomeModule'] - so ignore empty strings
294
+ name.empty? and next(mod)
295
+ mod.const_get(name)
296
+ end
297
+ end
298
+
299
+ def constant_exists?(name)
300
+ eval("defined?(#{name})") == 'constant'
301
+ end
302
+
303
+ def try_to_load(name)
304
+ if name =~ /(\w+)::(Lexer|Parser|TreeParser)$/
305
+ retry_ok = true
306
+ script = name.gsub(/::/, '')
307
+ begin
308
+ return(require(script))
309
+ rescue LoadError
310
+ if retry_ok
311
+ script, retry_ok = $1, false
312
+ retry
313
+ else
314
+ return(nil)
315
+ end
316
+ end
317
+ end
318
+ end
319
+
320
+ %w(puts print printf flush).each do |method|
321
+ class_eval(<<-END, __FILE__, __LINE__)
322
+ private
323
+ def #{method}(*args)
324
+ @output.#{method}(*args) unless @no_output
325
+ end
326
+ def #{method}!(*args)
327
+ @error.#{method}(*args) unless @no_output
328
+ end
329
+ END
330
+ end
331
+ end
332
+
333
+
334
+ =begin rdoc ANTLR3::Main::LexerMain
335
+
336
+ A class which implements a handy test script which is executed whenever an ANTLR
337
+ generated lexer file is run directly from the command line.
338
+
339
+ =end
340
+ class LexerMain < Main
341
+ def initialize(lexer_class, options = {})
342
+ super(options)
343
+ @lexer_class = lexer_class
344
+ end
345
+
346
+ def recognize(in_stream)
347
+ lexer = @lexer_class.new(in_stream)
348
+
349
+ loop do
350
+ begin
351
+ token = lexer.next_token
352
+ if token.nil? || token.type == ANTLR3::EOF then break
353
+ else display_token(token)
354
+ end
355
+ rescue ANTLR3::RecognitionError => error
356
+ report_error(error)
357
+ break
358
+ end
359
+ end
360
+ end
361
+
362
+ def display_token(token)
363
+ case token.channel
364
+ when ANTLR3::DEFAULT_CHANNEL
365
+ prefix = '-->'
366
+ suffix = ''
367
+ when ANTLR3::HIDDEN_CHANNEL
368
+ prefix = '// '
369
+ suffix = ' (hidden) '
370
+ else
371
+ prefix = '~~>'
372
+ suffix = ' (channel %p) ' % token.channel
373
+ end
374
+
375
+ printf("%s %-15s %-15p @ line %-3i col %-3i%s\n",
376
+ prefix, token.name, token.text,
377
+ token.line, token.column, suffix)
378
+ end
379
+
380
+ end
381
+
382
+
383
+ =begin rdoc ANTLR3::Main::ParserMain
384
+
385
+ A class which implements a handy test script which is executed whenever an ANTLR
386
+ generated parser file is run directly from the command line.
387
+
388
+ =end
389
+ class ParserMain < Main
390
+ def initialize(parser_class, options = {})
391
+ super(options)
392
+ @lexer_class_name = options[:lexer_class_name]
393
+ @lexer_class = options[:lexer_class]
394
+ @parser_class = parser_class
395
+ @parser_rule = options[:parser_rule]
396
+ if @debug = (@parser_class.debug? rescue false)
397
+ @port = options.fetch(:port, ANTLR3::Debug::DEFAULT_PORT)
398
+ @log = options.fetch(:log, @error)
399
+ end
400
+ end
401
+
402
+ def setup_options(opt)
403
+ super
404
+ opt.on('--lexer-name CLASS_NAME', "name of the lexer class to use") { |val|
405
+ @lexer_class_name = val
406
+ @lexer_class = nil
407
+ }
408
+ opt.on('--lexer-file PATH_TO_LIBRARY', "path to library defining the lexer class") { |val|
409
+ begin
410
+ test(?f, val) ? load(val) : require(val)
411
+ rescue LoadError
412
+ warn("unable to load the library specified by --lexer-file: #{$!}")
413
+ end
414
+ }
415
+ opt.on('--rule NAME', "name of the parser rule to execute") { |val| @parser_rule = val }
416
+ if @debug
417
+ opt.on('--port NUMBER', Integer, "port number to use for the debug socket") do |number|
418
+ @port = number
419
+ end
420
+ opt.on('--log PATH', "path of file to use to record socket activity",
421
+ "(stderr by default)" ) do |path|
422
+ @log = open(path, 'w')
423
+ end
424
+ end
425
+ end
426
+
427
+ def setup
428
+ unless @lexer_class ||= fetch_class(@lexer_class_name)
429
+ if @lexer_class_name
430
+ fail("unable to locate the lexer class ``#@lexer_class_name''")
431
+ else
432
+ unless @lexer_class = @parser_class.associated_lexer
433
+ fail(doc(<<-END))
434
+ | no lexer class has been specified with the --lexer-name option
435
+ | and #@parser_class does not appear to have an associated
436
+ | lexer class
437
+ END
438
+ end
439
+ end
440
+ end
441
+ @parser_rule ||= @parser_class.default_rule or
442
+ fail("a parser rule name must be specified via --rule NAME")
443
+ end
444
+
445
+ def recognize(in_stream)
446
+ parser_options = {}
447
+ if @debug
448
+ parser_options[:port] = @port
449
+ parser_options[:log] = @log
450
+ end
451
+ lexer = @lexer_class.new( in_stream )
452
+ token_stream = CommonTokenStream.new( lexer )
453
+ parser = @parser_class.new( token_stream, parser_options )
454
+ result = parser.send( @parser_rule ) and present( result )
455
+ end
456
+
457
+ def present( return_value )
458
+ ASTBuilder > @parser_class and return_value = return_value.tree
459
+ text =
460
+ begin
461
+ require 'pp'
462
+ return_value.pretty_inspect
463
+ rescue LoadError, NoMethodError
464
+ return_value.inspect
465
+ end
466
+ puts(text)
467
+ end
468
+
469
+ end
470
+
471
+
472
+ =begin rdoc ANTLR3::Main::WalkerMain
473
+
474
+ A class which implements a handy test script which is executed whenever an ANTLR
475
+ generated tree walker (tree parser) file is run directly from the command line.
476
+
477
+ =end
478
+
479
+ class WalkerMain < Main
480
+ attr_accessor :walker_class, :lexer_class, :parser_class
481
+ def initialize(walker_class, options = {})
482
+ super(options)
483
+ @walker_class = walker_class
484
+ @lexer_class_name = options[:lexer_class_name]
485
+ @lexer_class = options[:lexer_class]
486
+ @parser_class_name = options[:parser_class_name]
487
+ @parser_class = options[:parser_class]
488
+ if @debug = (@parser_class.debug? rescue false)
489
+ @port = options.fetch(:port, ANTLR3::Debug::DEFAULT_PORT)
490
+ @log = options.fetch(:log, @error)
491
+ end
492
+ end
493
+
494
+ def setup_options(opt)
495
+ super
496
+ opt.on('--lexer-name CLASS_NAME') { |val| @lexer_class_name = val }
497
+ opt.on('--lexer-file PATH_TO_LIBRARY') { |val|
498
+ begin
499
+ test(?f, val) ? load(val) : require(val)
500
+ rescue LoadError
501
+ warn("unable to load the library specified by --lexer-file: #{$!}")
502
+ end
503
+ }
504
+ opt.on('--parser-name CLASS_NAME') { |val| @parser_class_name = val }
505
+ opt.on('--parser-file PATH_TO_LIBRARY') { |val|
506
+ begin
507
+ test(?f, val) ? load(val) : require(val)
508
+ rescue LoadError
509
+ warn("unable to load the library specified by --parser-file: #{$!}")
510
+ end
511
+ }
512
+ opt.on('--parser-rule NAME') { |val| @parser_rule = val }
513
+ opt.on('--rule NAME') { |val| @walker_rule = val }
514
+
515
+ if @debug
516
+ opt.on('--port NUMBER', Integer, "port number to use for the debug socket") do |number|
517
+ @port = number
518
+ end
519
+ opt.on('--log PATH', "path of file to use to record socket activity",
520
+ "(stderr by default)" ) do |path|
521
+ @log = open(path, 'w')
522
+ end
523
+ end
524
+ end
525
+
526
+ # TODO: finish the Main modules
527
+ def setup
528
+ unless @lexer_class ||= fetch_class(@lexer_class_name)
529
+ fail("unable to locate the lexer class #@lexer_class_name")
530
+ end
531
+ unless @parser_class ||= fetch_class(@parser_class_name)
532
+ fail("unable to locate the parser class #@parser_class_name")
533
+ end
534
+ end
535
+
536
+ def recognize(in_stream)
537
+ walker_options = {}
538
+ if @debug
539
+ walker_options[:port] = @port
540
+ walker_options[:log] = @log
541
+ end
542
+ @lexer = @lexer_class.new(in_stream)
543
+ @token_stream = ANTLR3::CommonTokenStream.new(@lexer)
544
+ @parser = @parser_class.new(@token_stream)
545
+ if result = @parser.send(@parser_rule)
546
+ result.respond_to?(:tree) or fail("Parser did not return an AST for rule #@parser_rule")
547
+ @node_stream = ANTLR3::CommonTreeNodeStream.new(result.tree)
548
+ @node_stream.token_stream = @token_stream
549
+ @walker = @walker_class.new(@node_stream, walker_options)
550
+ if result = @walker.send(@walker_rule)
551
+ out = result.tree.inspect rescue result.inspect
552
+ puts(out)
553
+ else puts!("walker.#@walker_rule returned nil")
554
+ end
555
+ else puts!("parser.#@parser_rule returned nil")
556
+ end
557
+ end
558
+ end
559
+ end
560
+
561
+ end