antlr3 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
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,689 @@
1
+ #!/usr/bin/ruby
2
+ # encoding: utf-8
3
+
4
+ require 'antlr3'
5
+ require 'fileutils'
6
+ require 'antlr3/test/functional'
7
+ require 'antlr3/test/diff'
8
+
9
+ class ANTLRDebugger < Thread
10
+ self.abort_on_exception = true
11
+ attr_accessor :events, :success, :port
12
+ include Timeout
13
+
14
+ def initialize(port)
15
+ @events = []
16
+ @success = false
17
+ @port = port
18
+
19
+ super do
20
+ timeout(2) do
21
+ begin
22
+ @socket = TCPSocket.open('localhost', @port)
23
+ #Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
24
+ #@socket.connect( Socket.pack_sockaddr_in(@port, '127.0.0.1') )
25
+ rescue Errno::ECONNREFUSED => error
26
+ if $VERBOSE
27
+ $stderr.printf(
28
+ "%s:%s received connection refuse error: %p\n",
29
+ __FILE__, __LINE__, error
30
+ )
31
+ $stderr.puts("sleeping for 0.1 seconds before retrying")
32
+ end
33
+ sleep(0.01)
34
+ retry
35
+ end
36
+ end
37
+
38
+ @socket.readline.strip.should == 'ANTLR 2'
39
+ @socket.readline.strip.start_with?('grammar "').should == true
40
+ ack
41
+ loop do
42
+ event = @socket.readline.strip
43
+ @events << event.split("\t")
44
+ ack
45
+ break if event == 'terminate'
46
+ end
47
+
48
+ @socket.close
49
+ @success = true
50
+ end
51
+
52
+ end
53
+
54
+ def ack
55
+ @socket.write("ACK\n")
56
+ @socket.flush
57
+ end
58
+
59
+ end # ANTLRDebugger
60
+
61
+ class TestDebugGrammars < ANTLR3::Test::Functional
62
+ compile_options :debug => true
63
+
64
+ include ANTLR3::Test::Diff
65
+
66
+ def parse(grammar, rule, input, options = {})
67
+ @grammar = inline_grammar(grammar)
68
+ @grammar.compile( self.class.compile_options )
69
+ @grammar_path = File.expand_path(@grammar.path)
70
+ for output_file in @grammar.target_files
71
+ self.class.import( output_file )
72
+ end
73
+ grammar_module = self.class.const_get(@grammar.name)
74
+ listener = options[:listener] or debugger = ANTLRDebugger.new(port = 49100)
75
+
76
+ begin
77
+ lexer = grammar_module::Lexer.new(input)
78
+ tokens = ANTLR3::CommonTokenStream.new(lexer)
79
+ options[:debug_listener] = listener
80
+ parser = grammar_module::Parser.new(tokens, options)
81
+ parser.send(rule)
82
+ ensure
83
+ if listener.nil?
84
+ debugger.join
85
+ return(debugger)
86
+ end
87
+ end
88
+ end
89
+
90
+ example 'basic debug-mode parser using a RecordEventListener' do
91
+ grammar = %q<
92
+ grammar BasicParser; // line 1
93
+ options {language=Ruby;} // line 2
94
+ a : ID EOF; // line 3
95
+ ID : 'a'..'z'+ ; // line 4
96
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
97
+ >
98
+ listener = ANTLR3::Debug::RecordEventListener.new
99
+ parse(grammar, :a, 'a', :listener => listener)
100
+ lt_events, found = listener.events.partition { |event| event.start_with?("(look): ") }
101
+ lt_events.should_not be_empty
102
+
103
+ expected = ["(enter_rule): rule=a",
104
+ "(location): line=3 position=1",
105
+ "(enter_alternative): number=1",
106
+ "(location): line=3 position=5",
107
+ "(location): line=3 position=8",
108
+ "(location): line=3 position=11",
109
+ "(exit_rule): rule=a"]
110
+ found.should == expected
111
+ end
112
+
113
+ example 'debug-mode parser using a socket proxy to transmit events' do
114
+ grammar = %q<
115
+ grammar SocketProxy; // line 1
116
+ options {language=Ruby;} // line 2
117
+ a : ID EOF; // line 3
118
+ ID : 'a'..'z'+ ; // line 4
119
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
120
+ >
121
+ debugger = parse(grammar, :a, 'a')
122
+ debugger.success.should be_true
123
+ expected = [
124
+ ['enter_rule', @grammar_path, 'a'],
125
+ ['location', '3', '1'],
126
+ ['enter_alternative', '1'],
127
+ ['location', '3', '5'],
128
+ ['look', '1', '0', '4', 'default', '1', '0', '"a"'],
129
+ ['look', '1', '0', '4', 'default', '1', '0', '"a"'],
130
+ ['consume_token', '0', '4', 'default', '1', '0', '"a"'],
131
+ ['location', '3', '8'],
132
+ ['look', '1', '-1', '-1', 'default', '0', '-1', 'nil'],
133
+ ['look', '1', '-1', '-1', 'default', '0', '-1', 'nil'],
134
+ ['consume_token', '-1', '-1', 'default', '0', '-1', 'nil'],
135
+ ['location', '3', '11'],
136
+ ['exit_rule', @grammar_path, 'a'],
137
+ ['terminate']
138
+ ]
139
+
140
+ debugger.events.should == expected
141
+ end
142
+
143
+ example 'debug-mode parser events triggered by recognition errors' do
144
+ grammar = %q<
145
+ grammar RecognitionError;
146
+ options { language=Ruby; }
147
+ a : ID EOF;
148
+ ID : 'a'..'z'+ ;
149
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
150
+ >
151
+ debugger = parse(grammar, :a, "a b")
152
+ debugger.success.should be_true
153
+
154
+ expected = [
155
+ ["enter_rule", @grammar_path, "a"],
156
+ ["location", "3", "1"],
157
+ ["enter_alternative", "1"],
158
+ ["location", "3", "5"],
159
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
160
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
161
+ ["consume_token", "0", "4", "default", "1", "0", "\"a\""],
162
+ ["consume_hidden_token", "1", "5", "hidden", "1", "1", '" "'],
163
+ ["location", "3", "8"],
164
+ ["look", "1", "2", "4", "default", "1", "2", "\"b\""],
165
+ ["look", "1", "2", "4", "default", "1", "2", "\"b\""],
166
+ ["look", "2", "-1", "-1", "default", "0", "-1", "nil"],
167
+ ["look", "1", "2", "4", "default", "1", "2", "\"b\""],
168
+ ["begin_resync"],
169
+ ["consume_token", "2", "4", "default", "1", "2", "\"b\""],
170
+ ["end_resync"],
171
+ ["recognition_exception", "ANTLR3::Error::UnwantedToken", "2", "1", "2"],
172
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
173
+ ["consume_token", "-1", "-1", "default", "0", "-1", "nil"],
174
+ ["location", "3", "11"],
175
+ ["exit_rule", @grammar_path, "a"],
176
+ ["terminate"]
177
+ ]
178
+ debugger.events.should == expected
179
+ end
180
+
181
+ example 'debug-mode parser events triggered by semantic predicate evaluation' do
182
+ grammar = %q<
183
+ grammar SemPred;
184
+ options { language=Ruby; }
185
+ a : {true}? ID EOF;
186
+ ID : 'a'..'z'+ ;
187
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
188
+ >
189
+
190
+ debugger = parse(grammar, :a, "a")
191
+ debugger.success.should be_true
192
+
193
+ expected = [
194
+ ["enter_rule", @grammar_path, "a"],
195
+ ["location", "3", "1"],
196
+ ["enter_alternative", "1"],
197
+ ["location", "3", "5"],
198
+ ["semantic_predicate", "true", '"true"'],
199
+ ["location", "3", "13"],
200
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
201
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
202
+ ["consume_token", "0", "4", "default", "1", "0", "\"a\""],
203
+ ["location", "3", "16"],
204
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
205
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
206
+ ["consume_token", "-1", "-1", "default", "0", "-1", "nil"],
207
+ ["location", "3", "19"],
208
+ ["exit_rule", @grammar_path, "a"],
209
+ ["terminate"]
210
+ ]
211
+ debugger.events.should == expected
212
+ end
213
+
214
+ example 'debug-mode parser events triggered by recognizing a (...)+ block' do
215
+ grammar = %q<
216
+ grammar PositiveClosureBlock;
217
+ options { language=Ruby; }
218
+ a : ID ( ID | INT )+ EOF;
219
+ ID : 'a'..'z'+ ;
220
+ INT : '0'..'9'+ ;
221
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
222
+ >
223
+
224
+ debugger = parse(grammar, :a, "a 1 b c 3")
225
+ debugger.success.should be_true
226
+
227
+ expected = [
228
+ ["enter_rule", @grammar_path, "a"],
229
+ ["location", "3", "1"],
230
+ ["enter_alternative", "1"],
231
+ ["location", "3", "5"],
232
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
233
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
234
+ ["consume_token", "0", "4", "default", "1", "0", "\"a\""],
235
+ ["consume_hidden_token", "1", "6", "hidden", "1", "1", '" "'],
236
+ ["location", "3", "8"],
237
+ ["enter_subrule", "1"],
238
+ ["enter_decision", "1"],
239
+ ["look", "1", "2", "5", "default", "1", "2", "\"1\""],
240
+ ["exit_decision", "1"],
241
+ ["enter_alternative", "1"],
242
+ ["location", "3", "8"],
243
+ ["look", "1", "2", "5", "default", "1", "2", "\"1\""],
244
+ ["consume_token", "2", "5", "default", "1", "2", "\"1\""],
245
+ ["consume_hidden_token", "3", "6", "hidden", "1", "3", '" "'],
246
+ ["enter_decision", "1"],
247
+ ["look", "1", "4", "4", "default", "1", "4", "\"b\""],
248
+ ["exit_decision", "1"],
249
+ ["enter_alternative", "1"],
250
+ ["location", "3", "8"],
251
+ ["look", "1", "4", "4", "default", "1", "4", "\"b\""],
252
+ ["consume_token", "4", "4", "default", "1", "4", "\"b\""],
253
+ ["consume_hidden_token", "5", "6", "hidden", "1", "5", '" "'],
254
+ ["enter_decision", "1"],
255
+ ["look", "1", "6", "4", "default", "1", "6", "\"c\""],
256
+ ["exit_decision", "1"],
257
+ ["enter_alternative", "1"],
258
+ ["location", "3", "8"],
259
+ ["look", "1", "6", "4", "default", "1", "6", "\"c\""],
260
+ ["consume_token", "6", "4", "default", "1", "6", "\"c\""],
261
+ ["consume_hidden_token", "7", "6", "hidden", "1", "7", '" "'],
262
+ ["enter_decision", "1"],
263
+ ["look", "1", "8", "5", "default", "1", "8", "\"3\""],
264
+ ["exit_decision", "1"],
265
+ ["enter_alternative", "1"],
266
+ ["location", "3", "8"],
267
+ ["look", "1", "8", "5", "default", "1", "8", "\"3\""],
268
+ ["consume_token", "8", "5", "default", "1", "8", "\"3\""],
269
+ ["enter_decision", "1"],
270
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
271
+ ["exit_decision", "1"],
272
+ ["exit_subrule", "1"],
273
+ ["location", "3", "22"],
274
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
275
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
276
+ ["consume_token", "-1", "-1", "default", "0", "-1", "nil"],
277
+ ["location", "3", "25"],
278
+ ["exit_rule", @grammar_path, "a"],
279
+ ["terminate"]
280
+ ]
281
+
282
+ debugger.events.should == expected
283
+ end
284
+
285
+ example 'debug-mode parser events triggered by recognizing a (...)* block' do
286
+ grammar = %q<
287
+ grammar ClosureBlock;
288
+ options { language=Ruby; }
289
+ a : ID ( ID | INT )* EOF;
290
+ ID : 'a'..'z'+ ;
291
+ INT : '0'..'9'+ ;
292
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
293
+ >
294
+
295
+ debugger = parse(grammar, :a, "a 1 b c 3")
296
+ debugger.success.should be_true
297
+
298
+ expected = [
299
+ ["enter_rule", @grammar_path, "a"],
300
+ ["location", "3", "1"],
301
+ ["enter_alternative", "1"],
302
+ ["location", "3", "5"],
303
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
304
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
305
+ ["consume_token", "0", "4", "default", "1", "0", "\"a\""],
306
+ ["consume_hidden_token", "1", "6", "hidden", "1", "1", '" "'],
307
+ ["location", "3", "8"],
308
+ ["enter_subrule", "1"],
309
+ ["enter_decision", "1"],
310
+ ["look", "1", "2", "5", "default", "1", "2", "\"1\""],
311
+ ["exit_decision", "1"],
312
+ ["enter_alternative", "1"],
313
+ ["location", "3", "8"],
314
+ ["look", "1", "2", "5", "default", "1", "2", "\"1\""],
315
+ ["consume_token", "2", "5", "default", "1", "2", "\"1\""],
316
+ ["consume_hidden_token", "3", "6", "hidden", "1", "3", '" "'],
317
+ ["enter_decision", "1"],
318
+ ["look", "1", "4", "4", "default", "1", "4", "\"b\""],
319
+ ["exit_decision", "1"],
320
+ ["enter_alternative", "1"],
321
+ ["location", "3", "8"],
322
+ ["look", "1", "4", "4", "default", "1", "4", "\"b\""],
323
+ ["consume_token", "4", "4", "default", "1", "4", "\"b\""],
324
+ ["consume_hidden_token", "5", "6", "hidden", "1", "5", '" "'],
325
+ ["enter_decision", "1"],
326
+ ["look", "1", "6", "4", "default", "1", "6", "\"c\""],
327
+ ["exit_decision", "1"],
328
+ ["enter_alternative", "1"],
329
+ ["location", "3", "8"],
330
+ ["look", "1", "6", "4", "default", "1", "6", "\"c\""],
331
+ ["consume_token", "6", "4", "default", "1", "6", "\"c\""],
332
+ ["consume_hidden_token", "7", "6", "hidden", "1", "7", '" "'],
333
+ ["enter_decision", "1"],
334
+ ["look", "1", "8", "5", "default", "1", "8", "\"3\""],
335
+ ["exit_decision", "1"],
336
+ ["enter_alternative", "1"],
337
+ ["location", "3", "8"],
338
+ ["look", "1", "8", "5", "default", "1", "8", "\"3\""],
339
+ ["consume_token", "8", "5", "default", "1", "8", "\"3\""],
340
+ ["enter_decision", "1"],
341
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
342
+ ["exit_decision", "1"],
343
+ ["exit_subrule", "1"],
344
+ ["location", "3", "22"],
345
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
346
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
347
+ ["consume_token", "-1", "-1", "default", "0", "-1", "nil"],
348
+ ["location", "3", "25"],
349
+ ["exit_rule", @grammar_path, "a"],
350
+ ["terminate"]
351
+ ]
352
+ debugger.events.should == expected
353
+ end
354
+
355
+ example 'debug-mode parser events triggered by a mismatched set error' do
356
+ grammar = %q<
357
+ grammar MismatchedSetError;
358
+ options { language=Ruby; }
359
+ a : ID ( ID | INT ) EOF;
360
+ ID : 'a'..'z'+ ;
361
+ INT : '0'..'9'+ ;
362
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
363
+ >
364
+
365
+ debugger = parse(grammar, :a, "a")
366
+ debugger.success.should be_true
367
+
368
+ expected = [
369
+ ["enter_rule", @grammar_path, "a"],
370
+ ["location", "3", "1"],
371
+ ["enter_alternative", "1"],
372
+ ["location", "3", "5"],
373
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
374
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
375
+ ["consume_token", "0", "4", "default", "1", "0", "\"a\""],
376
+ ["location", "3", "8"],
377
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
378
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
379
+ ["recognition_exception", "ANTLR3::Error::MismatchedSet", "1", "0", "-1"],
380
+ ["recognition_exception", "ANTLR3::Error::MismatchedSet", "1", "0", "-1"],
381
+ ["begin_resync"],
382
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
383
+ ["end_resync"],
384
+ ["location", "3", "24"],
385
+ ["exit_rule", @grammar_path, "a"],
386
+ ["terminate"]
387
+ ]
388
+
389
+ debugger.events.should == expected
390
+ end
391
+
392
+ example 'debug-mode parser block-location events for subrules' do
393
+ grammar = %q<
394
+ grammar Block;
395
+ options { language=Ruby; }
396
+ a : ID ( b | c ) EOF;
397
+ b : ID;
398
+ c : INT;
399
+ ID : 'a'..'z'+ ;
400
+ INT : '0'..'9'+ ;
401
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
402
+ >
403
+
404
+ debugger = parse(grammar, :a, "a 1")
405
+ debugger.success.should be_true
406
+
407
+ expected = [
408
+ ["enter_rule", @grammar_path, "a"],
409
+ ["location", "3", "1"],
410
+ ["enter_alternative", "1"],
411
+ ["location", "3", "5"],
412
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
413
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
414
+ ["consume_token", "0", "4", "default", "1", "0", "\"a\""],
415
+ ["consume_hidden_token", "1", "6", "hidden", "1", "1", '" "'],
416
+ ["location", "3", "8"],
417
+ ["enter_subrule", "1"],
418
+ ["enter_decision", "1"],
419
+ ["look", "1", "2", "5", "default", "1", "2", "\"1\""],
420
+ ["exit_decision", "1"],
421
+ ["enter_alternative", "2"],
422
+ ["location", "3", "14"],
423
+ ["enter_rule", @grammar_path, "c"],
424
+ ["location", "5", "1"],
425
+ ["enter_alternative", "1"],
426
+ ["location", "5", "5"],
427
+ ["look", "1", "2", "5", "default", "1", "2", "\"1\""],
428
+ ["look", "1", "2", "5", "default", "1", "2", "\"1\""],
429
+ ["consume_token", "2", "5", "default", "1", "2", "\"1\""],
430
+ ["location", "5", "8"],
431
+ ["exit_rule", @grammar_path, "c"],
432
+ ["exit_subrule", "1"],
433
+ ["location", "3", "18"],
434
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
435
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
436
+ ["consume_token", "-1", "-1", "default", "0", "-1", "nil"],
437
+ ["location", "3", "21"],
438
+ ["exit_rule", @grammar_path, "a"],
439
+ ["terminate"]
440
+ ]
441
+ debugger.events.should == expected
442
+ end
443
+
444
+ example 'debug-mode parser events triggered by a no viable alternative error' do
445
+ grammar = %q<
446
+ grammar NoViableAlt;
447
+ options { language=Ruby; }
448
+ a : ID ( b | c ) EOF;
449
+ b : ID;
450
+ c : INT;
451
+ ID : 'a'..'z'+ ;
452
+ INT : '0'..'9'+ ;
453
+ BANG : '!' ;
454
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
455
+ >
456
+
457
+ debugger = parse(grammar, :a, "a !")
458
+ debugger.success.should be_true
459
+
460
+ expected = [
461
+ ["enter_rule", @grammar_path, "a"],
462
+ ["location", "3", "1"],
463
+ ["enter_alternative", "1"],
464
+ ["location", "3", "5"],
465
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
466
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
467
+ ["consume_token", "0", "4", "default", "1", "0", "\"a\""],
468
+ ["consume_hidden_token", "1", "7", "hidden", "1", "1", '" "'],
469
+ ["location", "3", "8"],
470
+ ["enter_subrule", "1"],
471
+ ["enter_decision", "1"],
472
+ ["look", "1", "2", "6", "default", "1", "2", "\"!\""],
473
+ ["look", "1", "2", "6", "default", "1", "2", "\"!\""],
474
+ ["recognition_exception", "ANTLR3::Error::NoViableAlternative", "2", "1", "2"],
475
+ ["exit_decision", "1"],
476
+ ["exit_subrule", "1"],
477
+ ["recognition_exception", "ANTLR3::Error::NoViableAlternative", "2", "1", "2"],
478
+ ["begin_resync"],
479
+ ["look", "1", "2", "6", "default", "1", "2", "\"!\""],
480
+ ["consume_token", "2", "6", "default", "1", "2", "\"!\""],
481
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
482
+ ["end_resync"],
483
+ ["location", "3", "21"],
484
+ ["exit_rule", @grammar_path, "a"],
485
+ ["terminate"]
486
+ ]
487
+ debugger.events.should == expected
488
+ end
489
+
490
+ example 'debug-mode parser block-location events triggered by rules' do
491
+ grammar = %q<
492
+ grammar RuleBlock;
493
+ options { language=Ruby; }
494
+ a : b | c;
495
+ b : ID;
496
+ c : INT;
497
+ ID : 'a'..'z'+ ;
498
+ INT : '0'..'9'+ ;
499
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
500
+ >
501
+
502
+ debugger = parse(grammar, :a, "1")
503
+ debugger.success.should be_true
504
+
505
+ expected = [
506
+ ["enter_rule", @grammar_path, "a"],
507
+ ["location", "3", "1"],
508
+ ["enter_decision", "1"],
509
+ ["look", "1", "0", "5", "default", "1", "0", "\"1\""],
510
+ ["exit_decision", "1"],
511
+ ["enter_alternative", "2"],
512
+ ["location", "3", "9"],
513
+ ["enter_rule", @grammar_path, "c"],
514
+ ["location", "5", "1"],
515
+ ["enter_alternative", "1"],
516
+ ["location", "5", "5"],
517
+ ["look", "1", "0", "5", "default", "1", "0", "\"1\""],
518
+ ["look", "1", "0", "5", "default", "1", "0", "\"1\""],
519
+ ["consume_token", "0", "5", "default", "1", "0", "\"1\""],
520
+ ["location", "5", "8"],
521
+ ["exit_rule", @grammar_path, "c"],
522
+ ["location", "3", "10"],
523
+ ["exit_rule", @grammar_path, "a"],
524
+ ["terminate"]
525
+ ]
526
+
527
+ debugger.events.should == expected
528
+ end
529
+
530
+ example 'debug-mode parser block-location events triggered by single-alternative rules' do
531
+ grammar = %q<
532
+ grammar RuleBlockSingleAlt;
533
+ options { language=Ruby; }
534
+ a : b;
535
+ b : ID;
536
+ ID : 'a'..'z'+ ;
537
+ INT : '0'..'9'+ ;
538
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
539
+ >
540
+
541
+ debugger = parse(grammar, :a, "a")
542
+ debugger.success.should be_true
543
+
544
+ expected = [
545
+ ["enter_rule", @grammar_path, "a"],
546
+ ["location", "3", "1"],
547
+ ["enter_alternative", "1"],
548
+ ["location", "3", "5"],
549
+ ["enter_rule", @grammar_path, "b"],
550
+ ["location", "4", "1"],
551
+ ["enter_alternative", "1"],
552
+ ["location", "4", "5"],
553
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
554
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
555
+ ["consume_token", "0", "4", "default", "1", "0", "\"a\""],
556
+ ["location", "4", "7"],
557
+ ["exit_rule", @grammar_path, "b"],
558
+ ["location", "3", "6"],
559
+ ["exit_rule", @grammar_path, "a"],
560
+ ["terminate"]
561
+ ]
562
+
563
+ debugger.events.should == expected
564
+ end
565
+
566
+ example 'debug-mode parser block-location events triggered by single-alternative subrules' do
567
+ grammar = %q<
568
+ grammar BlockSingleAlt;
569
+ options { language=Ruby; }
570
+ a : ( b );
571
+ b : ID;
572
+ ID : 'a'..'z'+ ;
573
+ INT : '0'..'9'+ ;
574
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
575
+ >
576
+
577
+ debugger = parse(grammar, :a, "a")
578
+ debugger.success.should be_true
579
+
580
+ expected = [
581
+ ["enter_rule", @grammar_path, "a"],
582
+ ["location", "3", "1"],
583
+ ["enter_alternative", "1"],
584
+ ["location", "3", "5"],
585
+ ["enter_alternative", "1"],
586
+ ["location", "3", "7"],
587
+ ["enter_rule", @grammar_path, "b"],
588
+ ["location", "4", "1"],
589
+ ["enter_alternative", "1"],
590
+ ["location", "4", "5"],
591
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
592
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
593
+ ["consume_token", "0", "4", "default", "1", "0", "\"a\""],
594
+ ["location", "4", "7"],
595
+ ["exit_rule", @grammar_path, "b"],
596
+ ["location", "3", "10"],
597
+ ["exit_rule", @grammar_path, "a"],
598
+ ["terminate"]
599
+ ]
600
+ debugger.events.should == expected
601
+ end
602
+
603
+ example 'debug-mode parser block-location events triggered by invoking a cyclic DFA for prediction' do
604
+ grammar = %q<
605
+ grammar DFA;
606
+ options { language=Ruby; }
607
+ a : ( b | c ) EOF;
608
+ b : ID* INT;
609
+ c : ID+ BANG;
610
+ ID : 'a'..'z'+ ;
611
+ INT : '0'..'9'+ ;
612
+ BANG : '!';
613
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
614
+ >
615
+
616
+ debugger = parse(grammar, :a, "a!")
617
+ debugger.success.should be_true
618
+
619
+ expected = [
620
+ ["enter_rule", @grammar_path, "a"],
621
+ ["location", "3", "1"],
622
+ ["enter_alternative", "1"],
623
+ ["location", "3", "5"],
624
+ ["enter_subrule", "1"],
625
+ ["enter_decision", "1"],
626
+ ["mark", "0"],
627
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
628
+ ["consume_token", "0", "4", "default", "1", "0", "\"a\""],
629
+ ["look", "1", "1", "6", "default", "1", "1", "\"!\""],
630
+ ["consume_token", "1", "6", "default", "1", "1", "\"!\""],
631
+ ["rewind", "0"],
632
+ ["exit_decision", "1"],
633
+ ["enter_alternative", "2"],
634
+ ["location", "3", "11"],
635
+ ["enter_rule", @grammar_path, "c"],
636
+ ["location", "5", "1"],
637
+ ["enter_alternative", "1"],
638
+ ["location", "5", "5"],
639
+ ["enter_subrule", "3"],
640
+ ["enter_decision", "3"],
641
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
642
+ ["exit_decision", "3"],
643
+ ["enter_alternative", "1"],
644
+ ["location", "5", "5"],
645
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
646
+ ["look", "1", "0", "4", "default", "1", "0", "\"a\""],
647
+ ["consume_token", "0", "4", "default", "1", "0", "\"a\""],
648
+ ["enter_decision", "3"],
649
+ ["look", "1", "1", "6", "default", "1", "1", "\"!\""],
650
+ ["exit_decision", "3"],
651
+ ["exit_subrule", "3"],
652
+ ["location", "5", "9"],
653
+ ["look", "1", "1", "6", "default", "1", "1", "\"!\""],
654
+ ["look", "1", "1", "6", "default", "1", "1", "\"!\""],
655
+ ["consume_token", "1", "6", "default", "1", "1", "\"!\""],
656
+ ["location", "5", "13"],
657
+ ["exit_rule", @grammar_path, "c"],
658
+ ["exit_subrule", "1"],
659
+ ["location", "3", "15"],
660
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
661
+ ["look", "1", "-1", "-1", "default", "0", "-1", "nil"],
662
+ ["consume_token", "-1", "-1", "default", "0", "-1", "nil"],
663
+ ["location", "3", "18"],
664
+ ["exit_rule", @grammar_path, "a"],
665
+ ["terminate"]
666
+ ]
667
+ debugger.events.should == expected
668
+ end
669
+
670
+ example 'debug-mode AST-building parser events' do
671
+ grammar = %q/
672
+ grammar BasicAST;
673
+ options {
674
+ language=Ruby;
675
+ output=AST;
676
+ }
677
+ a : ( b | c ) EOF!;
678
+ b : ID* INT -> ^(INT ID*);
679
+ c : ID+ BANG -> ^(BANG ID+);
680
+ ID : 'a'..'z'+ ;
681
+ INT : '0'..'9'+ ;
682
+ BANG : '!';
683
+ WS : (' '|'\n') {$channel=HIDDEN;} ;
684
+ /
685
+ listener = ANTLR3::Debug::RecordEventListener.new
686
+ parse(grammar, :a, "a!", :listener => listener)
687
+ end
688
+
689
+ end