1#!/usr/bin/ruby
2# encoding: utf-8
3require 'antlr3/test/functional'
4
5class LexerTest001 < ANTLR3::Test::Functional
6  inline_grammar( <<-'END' )
7    lexer grammar Zero;
8    options {
9      language = Ruby;
10    }
11
12    @members { include ANTLR3::Test::RaiseErrors }
13
14    ZERO: '0';
15  END
16
17  example %(lexing '0') do
18    lexer = Zero::Lexer.new( '0' )
19
20    token = lexer.next_token
21    token.name.should == 'ZERO'
22
23    token = lexer.next_token
24    token.name.should == '<EOF>'
25  end
26
27  example %(iterating over tokens) do
28    lexer = Zero::Lexer.new( '0' )
29
30    token_types = lexer.map { |token| token.name }
31    token_types.should == %w(ZERO)
32  end
33
34  example "mismatched token" do
35    lexer = Zero::Lexer.new( '1' )
36
37    proc {
38      token = lexer.next_token
39    }.should raise_error( ANTLR3::Error::MismatchedToken ) do |e|
40      e.expecting.should == '0'
41      e.unexpected_type.should == '1'
42    end
43  end
44end
45
46class LexerTest002 < ANTLR3::Test::Functional
47  inline_grammar( <<-'END' )
48    lexer grammar Binary;
49    options {
50      language = Ruby;
51    }
52
53    @members { include ANTLR3::Test::RaiseErrors }
54
55    ZERO: '0';
56    ONE: '1';
57  END
58
59  example "lexing '01'" do
60    lexer = Binary::Lexer.new( '01' )
61
62    token = lexer.next_token
63    token.name.should == 'ZERO'
64
65    token = lexer.next_token
66    token.name.should == 'ONE'
67
68    token = lexer.next_token
69    token.name.should == '<EOF>'
70  end
71
72  example "no matching token rule" do
73    lexer = Binary::Lexer.new( '2' )
74
75    b = lambda { token = lexer.next_token }
76    b.should raise_error( ANTLR3::Error::NoViableAlternative ) do |exc|
77      exc.unexpected_type.should == '2'
78    end
79  end
80
81end
82
83class LexerTest003 < ANTLR3::Test::Functional
84  inline_grammar( <<-'END' )
85    lexer grammar BinaryFooze;
86    options {
87      language = Ruby;
88    }
89
90    @members { include ANTLR3::Test::RaiseErrors }
91
92    ZERO: '0';
93    ONE:  '1';
94    FOOZE: 'fooze';
95  END
96
97  example "lexing '0fooze1'" do
98    lexer = BinaryFooze::Lexer.new( '0fooze1' )
99
100    token = lexer.next_token
101    token.name.should == 'ZERO'
102
103    token = lexer.next_token
104    token.name.should == 'FOOZE'
105
106    token = lexer.next_token
107    token.name.should == 'ONE'
108
109    token = lexer.next_token
110    token.name.should == '<EOF>'
111  end
112
113  example "no token match" do
114    lexer = BinaryFooze::Lexer.new( '2' )
115
116    proc { lexer.next_token }.
117    should raise_error( ANTLR3::Error::NoViableAlternative ) do |exc|
118      exc.unexpected_type.should == '2'
119    end
120  end
121end
122
123
124class LexerTest004 < ANTLR3::Test::Functional
125  inline_grammar( <<-'END' )
126    lexer grammar FooStar;
127    options {
128      language = Ruby;
129    }
130
131    @members { include ANTLR3::Test::RaiseErrors }
132
133    FOO: 'f' 'o'*;
134  END
135
136  example "lexing 'ffofoofooo'" do
137    lexer = FooStar::Lexer.new( 'ffofoofooo' )
138
139    token = lexer.next_token
140    token.name.should == 'FOO'
141    token.start.should == 0
142    token.stop.should == 0
143    token.text.should == 'f'
144
145    token = lexer.next_token
146    token.name.should == 'FOO'
147    token.text.should == 'fo'
148    token.start.should == 1
149    token.stop.should == 2
150
151    token = lexer.next_token
152    token.name.should == 'FOO'
153    token.start.should == 3
154    token.stop.should == 5
155    token.text.should == 'foo'
156
157    token = lexer.next_token
158    token.name.should == 'FOO'
159    token.start.should == 6
160    token.stop.should == 9
161    token.text.should == 'fooo'
162
163    token = lexer.next_token
164    token.name.should == '<EOF>'
165  end
166
167  example "mismatched token" do
168    lexer = FooStar::Lexer.new( '2' )
169
170    proc { lexer.next_token }.
171    should raise_error( ANTLR3::Error::MismatchedToken ) do |exc|
172      exc.expecting.should == 'f'
173      exc.unexpected_type.should == '2'
174    end
175  end
176end
177
178class LexerTest005 < ANTLR3::Test::Functional
179  inline_grammar( <<-'END' )
180    lexer grammar FooPlus;
181    options {
182      language = Ruby;
183    }
184
185    @members { include ANTLR3::Test::RaiseErrors }
186
187    FOO: 'f' 'o'+;
188  END
189
190  example "lexing 'fofoofooo'" do
191    lexer = FooPlus::Lexer.new( 'fofoofooo' )
192
193    token = lexer.next_token
194    token.name.should == 'FOO'
195    token.start.should == 0
196    token.stop.should == 1
197    token.text.should == 'fo'
198
199    token = lexer.next_token
200    token.name.should == 'FOO'
201    token.text.should == 'foo'
202    token.start.should == 2
203    token.stop.should == 4
204
205    token = lexer.next_token
206    token.name.should == 'FOO'
207    token.start.should == 5
208    token.stop.should == 8
209    token.text.should == 'fooo'
210
211    token = lexer.next_token
212    token.name.should == '<EOF>'
213  end
214
215  example "mismatched token" do
216    lexer = FooPlus::Lexer.new( '2' )
217
218    proc { lexer.next_token }.
219    should raise_error( ANTLR3::Error::MismatchedToken ) do |exc|
220      exc.expecting.should == 'f'
221      exc.unexpected_type.should == '2'
222    end
223  end
224
225  example "early exit" do
226    lexer = FooPlus::Lexer.new( 'f' )
227
228    proc { token = lexer.next_token }.
229    should raise_error( ANTLR3::Error::EarlyExit ) { |exc|
230      exc.unexpected_type.should == ANTLR3::Constants::EOF
231    }
232  end
233
234end
235
236class LexerTest006 < ANTLR3::Test::Functional
237  inline_grammar( <<-'END' )
238    lexer grammar FoaStar;
239    options {
240      language = Ruby;
241    }
242
243    @members { include ANTLR3::Test::RaiseErrors }
244
245    FOO: 'f' ('o' | 'a')*;
246  END
247
248  example "lexing 'fofaaooa'" do
249    lexer = FoaStar::Lexer.new( 'fofaaooa' )
250
251    token = lexer.next_token
252    token.name.should == 'FOO'
253    token.start.should == 0
254    token.stop.should == 1
255    token.text.should == 'fo'
256
257    token = lexer.next_token
258    token.name.should == 'FOO'
259    token.text.should == 'faaooa'
260    token.start.should == 2
261    token.stop.should == 7
262
263    token = lexer.next_token
264    token.name.should == '<EOF>'
265  end
266
267  example "mismatched token" do
268    lexer = FoaStar::Lexer.new( 'fofoaooaoa2' )
269
270    lexer.next_token
271    lexer.next_token
272    proc { lexer.next_token }.
273    should raise_error( ANTLR3::Error::MismatchedToken ) do |exc|
274      exc.expecting.should == 'f'
275      exc.unexpected_type.should == '2'
276      exc.column.should == 10
277      exc.line.should == 1
278    end
279  end
280end
281
282class LexerTest007 < ANTLR3::Test::Functional
283  inline_grammar( <<-'END' )
284    lexer grammar Foab;
285    options {
286      language = Ruby;
287    }
288
289    @members { include ANTLR3::Test::RaiseErrors }
290
291    FOO: 'f' ('o' | 'a' 'b'+)*;
292  END
293
294  example "lexing 'fofababbooabb'" do
295    lexer = Foab::Lexer.new( 'fofababbooabb' )
296
297    token = lexer.next_token
298    token.name.should == 'FOO'
299    token.start.should == 0
300    token.stop.should == 1
301    token.text.should == 'fo'
302
303    token = lexer.next_token
304    token.name.should == 'FOO'
305    token.start.should == 2
306    token.stop.should == 12
307    token.text.should == 'fababbooabb'
308
309    token = lexer.next_token
310    token.name.should == '<EOF>'
311  end
312
313  example "early exit" do
314    lexer = Foab::Lexer.new( 'foaboao' )
315
316    proc { lexer.next_token }.
317    should raise_error( ANTLR3::Error::EarlyExit ) do |exc|
318      exc.unexpected_type.should == 'o'
319      exc.column.should == 6
320      exc.line.should == 1
321    end
322  end
323end
324
325class LexerTest008 < ANTLR3::Test::Functional
326  inline_grammar( <<-'END' )
327    lexer grammar Fa;
328    options {
329      language = Ruby;
330    }
331
332    @members { include ANTLR3::Test::RaiseErrors }
333
334    FOO: 'f' 'a'?;
335  END
336
337  example "lexing 'ffaf'" do
338    lexer = Fa::Lexer.new( 'ffaf' )
339
340    token = lexer.next_token
341    token.name.should == 'FOO'
342    token.start.should == 0
343    token.stop.should == 0
344    token.text.should == 'f'
345
346    token = lexer.next_token
347    token.name.should == 'FOO'
348    token.start.should == 1
349    token.stop.should == 2
350    token.text.should == 'fa'
351
352    token = lexer.next_token
353    token.name.should == 'FOO'
354    token.start.should == 3
355    token.stop.should == 3
356    token.text.should == 'f'
357
358    token = lexer.next_token
359    token.name.should == '<EOF>'
360  end
361
362  example "mismatched token" do
363    lexer = Fa::Lexer.new( 'fafb' )
364
365    lexer.next_token
366    lexer.next_token
367    proc { lexer.next_token }.
368    should raise_error( ANTLR3::Error::MismatchedToken ) do |exc|
369      exc.unexpected_type.should == 'b'
370      exc.column.should == 3
371      exc.line.should == 1
372    end
373  end
374end
375
376
377class LexerTest009 < ANTLR3::Test::Functional
378  inline_grammar( <<-'END' )
379    lexer grammar Digit;
380    options {
381      language = Ruby;
382    }
383
384    @members { include ANTLR3::Test::RaiseErrors }
385
386    DIGIT: '0' .. '9';
387  END
388
389  example "lexing '085'" do
390    lexer = Digit::Lexer.new( '085' )
391
392    token = lexer.next_token
393    token.name.should == 'DIGIT'
394    token.start.should == 0
395    token.stop.should == 0
396    token.text.should == '0'
397
398    token = lexer.next_token
399    token.name.should == 'DIGIT'
400    token.start.should == 1
401    token.stop.should == 1
402    token.text.should == '8'
403
404    token = lexer.next_token
405    token.name.should == 'DIGIT'
406    token.start.should == 2
407    token.stop.should == 2
408    token.text.should == '5'
409
410    token = lexer.next_token
411    token.name.should == '<EOF>'
412  end
413
414  example "mismatched range" do
415    lexer = Digit::Lexer.new( '2a' )
416
417    lexer.next_token
418    proc { lexer.next_token }.
419    should raise_error( ANTLR3::Error::MismatchedRange ) do |exc|
420      exc.min.should == '0'
421      exc.max.should == '9'
422      exc.unexpected_type.should == 'a'
423      exc.column.should == 1
424      exc.line.should == 1
425    end
426  end
427end
428
429class LexerTest010 < ANTLR3::Test::Functional
430  inline_grammar( <<-'END' )
431    lexer grammar IDsAndSpaces;
432    options {
433      language = Ruby;
434    }
435
436    @members { include ANTLR3::Test::RaiseErrors }
437
438    IDENTIFIER: ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
439    WS: (' ' | '\n')+;
440  END
441
442  example "lexing 'foobar _Ab98 \n A12sdf'" do
443    lexer = IDsAndSpaces::Lexer.new( "foobar _Ab98 \n A12sdf" )
444
445    token = lexer.next_token
446    token.name.should == 'IDENTIFIER'
447    token.start.should == 0
448    token.stop.should == 5
449    token.text.should == 'foobar'
450
451    token = lexer.next_token
452    token.name.should == 'WS'
453    token.start.should == 6
454    token.stop.should == 6
455    token.text.should == ' '
456
457    token = lexer.next_token
458    token.name.should == 'IDENTIFIER'
459    token.start.should == 7
460    token.stop.should == 11
461    token.text.should == '_Ab98'
462
463    token = lexer.next_token
464    token.name.should == 'WS'
465    token.start.should == 12
466    token.stop.should == 14
467    token.text.should == " \n "
468
469    token = lexer.next_token
470    token.name.should == 'IDENTIFIER'
471    token.start.should == 15
472    token.stop.should == 20
473    token.text.should == 'A12sdf'
474
475    token = lexer.next_token
476    token.name.should == '<EOF>'
477  end
478
479  example "contains characters without a matching token rule" do
480    lexer = IDsAndSpaces::Lexer.new( 'a-b' )
481
482    lexer.next_token
483    proc { lexer.next_token }.
484    should raise_error( ANTLR3::Error::NoViableAlternative ) do |exc|
485      exc.unexpected_type.should == '-'
486      exc.column.should == 1
487      exc.line.should == 1
488    end
489  end
490end
491
492class LexerTest011 < ANTLR3::Test::Functional
493  inline_grammar( <<-'END' )
494    lexer grammar IDsWithAction;
495    options {language = Ruby;}
496
497    @members { include ANTLR3::Test::RaiseErrors }
498
499    IDENTIFIER:
500            ('a'..'z'|'A'..'Z'|'_')
501            ('a'..'z'
502            |'A'..'Z'
503            |'0'..'9'
504            |'_' { \$action_var = '_' }
505            )*
506        ;
507
508    WS: (' ' | '\n')+;
509  END
510
511  example "lexing 'foobar _Ab98 \n A12sdf'" do
512    lexer = IDsWithAction::Lexer.new( "foobar _Ab98 \n A12sdf" )
513
514    token = lexer.next_token
515    token.name.should == 'IDENTIFIER'
516    token.start.should == 0
517    token.stop.should == 5
518    token.text.should == 'foobar'
519
520    token = lexer.next_token
521    token.name.should == 'WS'
522    token.start.should == 6
523    token.stop.should == 6
524    token.text.should == ' '
525
526    token = lexer.next_token
527    token.name.should == 'IDENTIFIER'
528    token.start.should == 7
529    token.stop.should == 11
530    token.text.should == '_Ab98'
531
532    token = lexer.next_token
533    token.name.should == 'WS'
534    token.start.should == 12
535    token.stop.should == 14
536    token.text.should == " \n "
537
538    token = lexer.next_token
539    token.name.should == 'IDENTIFIER'
540    token.start.should == 15
541    token.stop.should == 20
542    token.text.should == 'A12sdf'
543
544    token = lexer.next_token
545    token.name.should == '<EOF>'
546  end
547
548  example "contains characters without a matching token" do
549    lexer = IDsWithAction::Lexer.new( 'a-b' )
550
551    lexer.next_token
552    proc { lexer.next_token }.
553    should raise_error( ANTLR3::Error::NoViableAlternative ) do |exc|
554      exc.unexpected_type.should == '-'
555      exc.column.should == 1
556      exc.line.should == 1
557    end
558  end
559end
560