1#!/usr/bin/ruby
2# encoding: utf-8
3
4require 'antlr3/test/functional'
5
6class TestASTViaRewriteRules < ANTLR3::Test::Functional
7
8  def parse( grammar, rule, input, expect_errors = false )
9    @grammar = inline_grammar( grammar )
10    compile_and_load @grammar
11    grammar_module = self.class.const_get( @grammar.name )
12    
13    grammar_module::Lexer.send( :include, ANTLR3::Test::CollectErrors )
14    grammar_module::Lexer.send( :include, ANTLR3::Test::CaptureOutput )
15    grammar_module::Parser.send( :include, ANTLR3::Test::CollectErrors )
16    grammar_module::Parser.send( :include, ANTLR3::Test::CaptureOutput )
17    
18    lexer  = grammar_module::Lexer.new( input )
19    parser = grammar_module::Parser.new( lexer )
20    
21    r = parser.send( rule )
22    parser.reported_errors.should be_empty unless expect_errors
23    result = ''
24    
25    unless r.nil?
26      result += r.result if r.respond_to?( :result )
27      result += r.tree.inspect if r.tree
28    end
29    return( expect_errors ? [ result, parser.reported_errors ] : result )
30  end
31  
32  def tree_parse( grammar, tree_grammar, rule, tree_rule, input )
33    @grammar = inline_grammar( grammar )
34    @tree_grammar = inline_grammar( tree_grammar )
35    compile_and_load @grammar
36    compile_and_load @tree_grammar
37    
38    grammar_module = self.class.const_get( @grammar.name )
39    tree_grammar_module = self.class.const_get( @tree_grammar.name )
40    
41    grammar_module::Lexer.send( :include, ANTLR3::Test::CollectErrors )
42    grammar_module::Lexer.send( :include, ANTLR3::Test::CaptureOutput )
43    grammar_module::Parser.send( :include, ANTLR3::Test::CollectErrors )
44    grammar_module::Parser.send( :include, ANTLR3::Test::CaptureOutput )
45    tree_grammar_module::TreeParser.send( :include, ANTLR3::Test::CollectErrors )
46    tree_grammar_module::TreeParser.send( :include, ANTLR3::Test::CaptureOutput )
47    
48    lexer  = grammar_module::Lexer.new( input )
49    parser = grammar.module::Parser.new( lexer )
50    r = parser.send( rule )
51    nodes = ANTLR3::CommonTreeNodeStream( r.tree )
52    nodes.token_stream = parser.input
53    walker = tree_grammar_module::TreeParser.new( nodes )
54    r = walker.send( tree_rule )
55    
56    return( r ? r.tree.inspect : '' )
57  end
58  
59  example "delete" do
60    result = parse( <<-'END', :a, 'abc 34' )
61      grammar Delete;
62      options {language=Ruby;output=AST;}
63      a : ID INT -> ;
64      ID : 'a'..'z'+ ;
65      INT : '0'..'9'+;
66      WS : (' '|'\n') {$channel=HIDDEN;} ;
67    END
68    result.should == ''
69  end
70  
71  
72  example "single token" do
73    result = parse( <<-'END', :a, 'abc' )
74      grammar SingleToken;
75      options {language=Ruby;output=AST;}
76      a : ID -> ID;
77      ID : 'a'..'z'+ ;
78      INT : '0'..'9'+;
79      WS : (' '|'\n') {$channel=HIDDEN;} ;
80  
81    END
82    result.should == 'abc'
83  end
84  
85  
86  example "single token to new node" do
87    result = parse( <<-'END', :a, 'abc' )
88      grammar SingleTokenToNewNode;
89      options {language=Ruby;output=AST;}
90      a : ID -> ID["x"];
91      ID : 'a'..'z'+ ;
92      INT : '0'..'9'+;
93      WS : (' '|'\n') {$channel=HIDDEN;} ;
94  
95    END
96    result.should == 'x'
97  end
98  
99  
100  example "single token to new node root" do
101    result = parse( <<-'END', :a, 'abc' )
102      grammar SingleTokenToNewNodeRoot;
103      options {language=Ruby;output=AST;}
104      a : ID -> ^(ID["x"] INT);
105      ID : 'a'..'z'+ ;
106      INT : '0'..'9'+;
107      WS : (' '|'\n') {$channel=HIDDEN;} ;
108  
109    END
110    result.should == '(x INT)'
111  end
112  
113  
114  example "single token to new node2" do
115    result = parse( <<-'END', :a, 'abc' )
116      grammar SingleTokenToNewNode2;
117      options {language=Ruby;output=AST;}
118      a : ID -> ID[ ];
119      ID : 'a'..'z'+ ;
120      INT : '0'..'9'+;
121      WS : (' '|'\n') {$channel=HIDDEN;} ;
122    END
123    result.should == 'ID'
124  end
125  
126  
127  example "single char literal" do
128    result = parse( <<-'END', :a, 'c' )
129      grammar SingleCharLiteral;
130      options {language=Ruby;output=AST;}
131      a : 'c' -> 'c';
132      ID : 'a'..'z'+ ;
133      INT : '0'..'9'+;
134      WS : (' '|'\n') {$channel=HIDDEN;} ;
135  
136    END
137    result.should == 'c'
138  end
139  
140  
141  example "single string literal" do
142    result = parse( <<-'END', :a, 'ick' )
143      grammar SingleStringLiteral;
144      options {language=Ruby;output=AST;}
145      a : 'ick' -> 'ick';
146      ID : 'a'..'z'+ ;
147      INT : '0'..'9'+;
148      WS : (' '|'\n') {$channel=HIDDEN;} ;
149  
150    END
151    result.should == 'ick'
152  end
153  
154  
155  example "single rule" do
156    result = parse( <<-'END', :a, 'abc' )
157      grammar SingleRule;
158      options {language=Ruby;output=AST;}
159      a : b -> b;
160      b : ID ;
161      ID : 'a'..'z'+ ;
162      INT : '0'..'9'+;
163      WS : (' '|'\n') {$channel=HIDDEN;} ;
164  
165    END
166    result.should == 'abc'
167  end
168  
169  
170  example "reorder tokens" do
171    result = parse( <<-'END', :a, 'abc 34' )
172      grammar ReorderTokens;
173      options {language=Ruby;output=AST;}
174      a : ID INT -> INT ID;
175      ID : 'a'..'z'+ ;
176      INT : '0'..'9'+;
177      WS : (' '|'\n') {$channel=HIDDEN;} ;
178  
179    END
180    result.should == '34 abc'
181  end
182  
183  
184  example "reorder token and rule" do
185    result = parse( <<-'END', :a, 'abc 34' )
186      grammar ReorderTokenAndRule;
187      options {language=Ruby;output=AST;}
188      a : b INT -> INT b;
189      b : ID ;
190      ID : 'a'..'z'+ ;
191      INT : '0'..'9'+;
192      WS : (' '|'\n') {$channel=HIDDEN;} ;
193  
194    END
195    result.should == '34 abc'
196  end
197  
198  
199  example "token tree" do
200    result = parse( <<-'END', :a, 'abc 34' )
201      grammar TokenTree;
202      options {language=Ruby;output=AST;}
203      a : ID INT -> ^(INT ID);
204      ID : 'a'..'z'+ ;
205      INT : '0'..'9'+;
206      WS : (' '|'\n') {$channel=HIDDEN;} ;
207  
208    END
209    result.should == '(34 abc)'
210  end
211  
212  
213  example "token tree after other stuff" do
214    result = parse( <<-'END', :a, 'void abc 34' )
215      grammar TokenTreeAfterOtherStuff;
216      options {language=Ruby;output=AST;}
217      a : 'void' ID INT -> 'void' ^(INT ID);
218      ID : 'a'..'z'+ ;
219      INT : '0'..'9'+;
220      WS : (' '|'\n') {$channel=HIDDEN;} ;
221  
222    END
223    result.should == 'void (34 abc)'
224  end
225  
226  
227  example "nested token tree with outer loop" do
228    result = parse( <<-'END', :a, 'a 1 b 2' )
229      grammar NestedTokenTreeWithOuterLoop;
230      options {language=Ruby;output=AST;}
231      tokens {DUH;}
232      a : ID INT ID INT -> ^( DUH ID ^( DUH INT) )+ ;
233      ID : 'a'..'z'+ ;
234      INT : '0'..'9'+;
235      WS : (' '|'\n') {$channel=HIDDEN;} ;
236  
237    END
238    result.should == '(DUH a (DUH 1)) (DUH b (DUH 2))'
239  end
240  
241  
242  example "optional single token" do
243    result = parse( <<-'END', :a, 'abc' )
244      grammar OptionalSingleToken;
245      options {language=Ruby;output=AST;}
246      a : ID -> ID? ;
247      ID : 'a'..'z'+ ;
248      INT : '0'..'9'+;
249      WS : (' '|'\n') {$channel=HIDDEN;} ;
250  
251    END
252    result.should == 'abc'
253  end
254  
255  
256  example "closure single token" do
257    result = parse( <<-'END', :a, 'a b' )
258      grammar ClosureSingleToken;
259      options {language=Ruby;output=AST;}
260      a : ID ID -> ID* ;
261      ID : 'a'..'z'+ ;
262      INT : '0'..'9'+;
263      WS : (' '|'\n') {$channel=HIDDEN;} ;
264  
265    END
266    result.should == 'a b'
267  end
268  
269  
270  example "positive closure single token" do
271    result = parse( <<-'END', :a, 'a b' )
272      grammar PositiveClosureSingleToken;
273      options {language=Ruby;output=AST;}
274      a : ID ID -> ID+ ;
275      ID : 'a'..'z'+ ;
276      INT : '0'..'9'+;
277      WS : (' '|'\n') {$channel=HIDDEN;} ;
278  
279    END
280    result.should == 'a b'
281  end
282  
283  
284  example "optional single rule" do
285    result = parse( <<-'END', :a, 'abc' )
286      grammar OptionalSingleRule;
287      options {language=Ruby;output=AST;}
288      a : b -> b?;
289      b : ID ;
290      ID : 'a'..'z'+ ;
291      INT : '0'..'9'+;
292      WS : (' '|'\n') {$channel=HIDDEN;} ;
293  
294    END
295    result.should == 'abc'
296  end
297  
298  
299  example "closure single rule" do
300    result = parse( <<-'END', :a, 'a b' )
301      grammar ClosureSingleRule;
302      options {language=Ruby;output=AST;}
303      a : b b -> b*;
304      b : ID ;
305      ID : 'a'..'z'+ ;
306      INT : '0'..'9'+;
307      WS : (' '|'\n') {$channel=HIDDEN;} ;
308  
309    END
310    result.should == 'a b'
311  end
312  
313  
314  example "closure of label" do
315    result = parse( <<-'END', :a, 'a b' )
316      grammar ClosureOfLabel;
317      options {language=Ruby;output=AST;}
318      a : x+=b x+=b -> $x*;
319      b : ID ;
320      ID : 'a'..'z'+ ;
321      INT : '0'..'9'+;
322      WS : (' '|'\n') {$channel=HIDDEN;} ;
323  
324    END
325    result.should == 'a b'
326  end
327  
328  
329  example "optional label no list label" do
330    result = parse( <<-'END', :a, 'a' )
331      grammar OptionalLabelNoListLabel;
332      options {language=Ruby;output=AST;}
333      a : (x=ID)? -> $x?;
334      ID : 'a'..'z'+ ;
335      INT : '0'..'9'+;
336      WS : (' '|'\n') {$channel=HIDDEN;} ;
337  
338    END
339    result.should == 'a'
340  end
341  
342  
343  example "positive closure single rule" do
344    result = parse( <<-'END', :a, 'a b' )
345      grammar PositiveClosureSingleRule;
346      options {language=Ruby;output=AST;}
347      a : b b -> b+;
348      b : ID ;
349      ID : 'a'..'z'+ ;
350      INT : '0'..'9'+;
351      WS : (' '|'\n') {$channel=HIDDEN;} ;
352  
353    END
354    result.should == 'a b'
355  end
356  
357  
358  example "single predicate t" do
359    result = parse( <<-'END', :a, 'abc' )
360      grammar SinglePredicateT;
361      options {language=Ruby;output=AST;}
362      a : ID -> {true}? ID -> ;
363      ID : 'a'..'z'+ ;
364      INT : '0'..'9'+;
365      WS : (' '|'\n') {$channel=HIDDEN;} ;
366  
367    END
368    result.should == 'abc'
369  end
370  
371  
372  example "single predicate f" do
373    result = parse( <<-'END', :a, 'abc' )
374      grammar SinglePredicateF;
375      options {language=Ruby;output=AST;}
376      a : ID -> {false}? ID -> ;
377      ID : 'a'..'z'+ ;
378      INT : '0'..'9'+;
379      WS : (' '|'\n') {$channel=HIDDEN;} ;
380  
381    END
382    result.should == ''
383  end
384  
385  
386  example "multiple predicate" do
387    result = parse( <<-'END', :a, 'a 2' )
388      grammar MultiplePredicate;
389      options {language=Ruby;output=AST;}
390      a : ID INT -> {false}? ID
391                 -> {true}? INT
392                 -> 
393        ;
394      ID : 'a'..'z'+ ;
395      INT : '0'..'9'+;
396      WS : (' '|'\n') {$channel=HIDDEN;} ;
397  
398    END
399    result.should == '2'
400  end
401  
402  
403  example "multiple predicate trees" do
404    result = parse( <<-'END', :a, 'a 2' )
405      grammar MultiplePredicateTrees;
406      options {language=Ruby;output=AST;}
407      a : ID INT -> {false}? ^(ID INT)
408                 -> {true}? ^(INT ID)
409                 -> ID
410        ;
411      ID : 'a'..'z'+ ;
412      INT : '0'..'9'+;
413      WS : (' '|'\n') {$channel=HIDDEN;} ;
414  
415    END
416    result.should == '(2 a)'
417  end
418  
419  
420  example "simple tree" do
421    result = parse( <<-'END', :a, '-34' )
422      grammar SimpleTree;
423      options {language=Ruby;output=AST;}
424      a : op INT -> ^(op INT);
425      op : '+'|'-' ;
426      ID : 'a'..'z'+ ;
427      INT : '0'..'9'+;
428      WS : (' '|'\n') {$channel=HIDDEN;} ;
429  
430    END
431    result.should == '(- 34)'
432  end
433  
434  
435  example "simple tree2" do
436    result = parse( <<-'END', :a, '+ 34' )
437      grammar SimpleTree2;
438      options {language=Ruby;output=AST;}
439      a : op INT -> ^(INT op);
440      op : '+'|'-' ;
441      ID : 'a'..'z'+ ;
442      INT : '0'..'9'+;
443      WS : (' '|'\n') {$channel=HIDDEN;} ;
444  
445    END
446    result.should == '(34 +)'
447  end
448  
449  
450  example "nested trees" do
451    result = parse( <<-'END', :a, 'var a:int; b:float;' )
452      grammar NestedTrees;
453      options {language=Ruby;output=AST;}
454      a : 'var' (ID ':' type ';')+ -> ^('var' ^(':' ID type)+) ;
455      type : 'int' | 'float' ;
456      ID : 'a'..'z'+ ;
457      INT : '0'..'9'+;
458      WS : (' '|'\n') {$channel=HIDDEN;} ;
459  
460    END
461    result.should == '(var (: a int) (: b float))'
462  end
463  
464  
465  example "imaginary token copy" do
466    result = parse( <<-'END', :a, 'a,b,c' )
467      grammar ImaginaryTokenCopy;
468      options {language=Ruby;output=AST;}
469      tokens {VAR;}
470      a : ID (',' ID)*-> ^(VAR ID)+ ;
471      type : 'int' | 'float' ;
472      ID : 'a'..'z'+ ;
473      INT : '0'..'9'+;
474      WS : (' '|'\n') {$channel=HIDDEN;} ;
475  
476    END
477    result.should == '(VAR a) (VAR b) (VAR c)'
478  end
479  
480  
481  example "token unreferenced on left but defined" do
482    result = parse( <<-'END', :a, 'a' )
483      grammar TokenUnreferencedOnLeftButDefined;
484      options {language=Ruby;output=AST;}
485      tokens {VAR;}
486      a : b -> ID ;
487      b : ID ;
488      ID : 'a'..'z'+ ;
489      INT : '0'..'9'+;
490      WS : (' '|'\n') {$channel=HIDDEN;} ;
491  
492    END
493    result.should == 'ID'
494  end
495  
496  
497  example "imaginary token copy set text" do
498    result = parse( <<-'END', :a, 'a,b,c' )
499      grammar ImaginaryTokenCopySetText;
500      options {language=Ruby;output=AST;}
501      tokens {VAR;}
502      a : ID (',' ID)*-> ^(VAR["var"] ID)+ ;
503      type : 'int' | 'float' ;
504      ID : 'a'..'z'+ ;
505      INT : '0'..'9'+;
506      WS : (' '|'\n') {$channel=HIDDEN;} ;
507  
508    END
509    result.should == '(var a) (var b) (var c)'
510  end
511  
512  
513  example "imaginary token no copy from token" do
514    result = parse( <<-'END', :a, '{a b c}' )
515      grammar ImaginaryTokenNoCopyFromToken;
516      options {language=Ruby;output=AST;}
517      tokens {BLOCK;}
518      a : lc='{' ID+ '}' -> ^(BLOCK[$lc] ID+) ;
519      type : 'int' | 'float' ;
520      ID : 'a'..'z'+ ;
521      INT : '0'..'9'+;
522      WS : (' '|'\n') {$channel=HIDDEN;} ;
523  
524    END
525    result.should == '({ a b c)'
526  end
527  
528  
529  example "imaginary token no copy from token set text" do
530    result = parse( <<-'END', :a, '{a b c}' )
531      grammar ImaginaryTokenNoCopyFromTokenSetText;
532      options {language=Ruby;output=AST;}
533      tokens {BLOCK;}
534      a : lc='{' ID+ '}' -> ^(BLOCK[$lc,"block"] ID+) ;
535      type : 'int' | 'float' ;
536      ID : 'a'..'z'+ ;
537      INT : '0'..'9'+;
538      WS : (' '|'\n') {$channel=HIDDEN;} ;
539  
540    END
541    result.should == '(block a b c)'
542  end
543  
544  
545  example "mixed rewrite and auto ast" do
546    result = parse( <<-'END', :a, 'a 1 2' )
547      grammar MixedRewriteAndAutoAST;
548      options {language=Ruby;output=AST;}
549      tokens {BLOCK;}
550      a : b b^ ; // 2nd b matches only an INT; can make it root
551      b : ID INT -> INT ID
552        | INT
553        ;
554      ID : 'a'..'z'+ ;
555      INT : '0'..'9'+;
556      WS : (' '|'\n') {$channel=HIDDEN;} ;
557    END
558    result.should == '(2 1 a)'
559  end
560  
561  
562  example "subrule with rewrite" do
563    result = parse( <<-'END', :a, 'a 1 2 3' )
564      grammar SubruleWithRewrite;
565      options {language=Ruby;output=AST;}
566      tokens {BLOCK;}
567      a : b b ;
568      b : (ID INT -> INT ID | INT INT -> INT+ )
569        ;
570      ID : 'a'..'z'+ ;
571      INT : '0'..'9'+;
572      WS : (' '|'\n') {$channel=HIDDEN;} ;
573  
574    END
575    result.should == '1 a 2 3'
576  end
577  
578  
579  example "subrule with rewrite2" do
580    result = parse( <<-'END', :a, 'int a; int b=3;' )
581      grammar SubruleWithRewrite2;
582      options {language=Ruby;output=AST;}
583      tokens {TYPE;}
584      a : b b ;
585      b : 'int'
586          ( ID -> ^(TYPE 'int' ID)
587          | ID '=' INT -> ^(TYPE 'int' ID INT)
588          )
589          ';'
590        ;
591      ID : 'a'..'z'+ ;
592      INT : '0'..'9'+;
593      WS : (' '|'\n') {$channel=HIDDEN;} ;
594  
595    END
596    result.should == '(TYPE int a) (TYPE int b 3)'
597  end
598  
599  
600  example "nested rewrite shuts off auto ast" do
601    result = parse( <<-'END', :a, 'a b c d; 42' )
602      grammar NestedRewriteShutsOffAutoAST;
603      options {language=Ruby;output=AST;}
604      tokens {BLOCK;}
605      a : b b ;
606      b : ID ( ID (last=ID -> $last)+ ) ';' // get last ID
607        | INT // should still get auto AST construction
608        ;
609      ID : 'a'..'z'+ ;
610      INT : '0'..'9'+;
611      WS : (' '|'\n') {$channel=HIDDEN;} ;
612  
613    END
614    result.should == 'd 42'
615  end
616  
617  
618  example "rewrite actions" do
619    result = parse( <<-'END', :a, '3' )
620      grammar RewriteActions;
621      options {language=Ruby;output=AST;}
622      a : atom -> ^({ @adaptor.create( INT, "9" ) } atom) ;
623      atom : INT ;
624      ID : 'a'..'z'+ ;
625      INT : '0'..'9'+;
626      WS : (' '|'\n') {$channel=HIDDEN;} ;
627  
628    END
629    result.should == '(9 3)'
630  end
631  
632  
633  example "rewrite actions2" do
634    result = parse( <<-'END', :a, '3' )
635      grammar RewriteActions2;
636      options {language=Ruby;output=AST;}
637      a : atom -> { @adaptor.create( INT, "9" ) } atom ;
638      atom : INT ;
639      ID : 'a'..'z'+ ;
640      INT : '0'..'9'+;
641      WS : (' '|'\n') { $channel = HIDDEN } ;
642  
643    END
644    result.should == '9 3'
645  end
646  
647  
648  example "ref to old value" do
649    result = parse( <<-'END', :a, '3+4+5' )
650      grammar RefToOldValue;
651      options {language=Ruby;output=AST;}
652      tokens {BLOCK;}
653      a : (atom -> atom) (op='+' r=atom -> ^($op $a $r) )* ;
654      atom : INT ;
655      ID : 'a'..'z'+ ;
656      INT : '0'..'9'+;
657      WS : (' '|'\n') {$channel=HIDDEN;} ;
658  
659    END
660    result.should == '(+ (+ 3 4) 5)'
661  end
662  
663  
664  example "copy semantics for rules" do
665    result = parse( <<-'END', :a, '3' )
666      grammar CopySemanticsForRules;
667      options {language=Ruby;output=AST;}
668      tokens {BLOCK;}
669      a : atom -> ^(atom atom) ; // NOT CYCLE! (dup atom)
670      atom : INT ;
671      ID : 'a'..'z'+ ;
672      INT : '0'..'9'+;
673      WS : (' '|'\n') {$channel=HIDDEN;} ;
674  
675    END
676    result.should == '(3 3)'
677  end
678  
679  
680  example "copy semantics for rules2" do
681    result = parse( <<-'END', :a, 'int a,b,c;' )
682      grammar CopySemanticsForRules2;
683      options {language=Ruby;output=AST;}
684      a : type ID (',' ID)* ';' -> ^(type ID)+ ;
685      type : 'int' ;
686      ID : 'a'..'z'+ ;
687      WS : (' '|'\n') {$channel=HIDDEN;} ;
688  
689    END
690    result.should == '(int a) (int b) (int c)'
691  end
692  
693  
694  example "copy semantics for rules3" do
695    result = parse( <<-'END', :a, 'public int a,b,c;' )
696      grammar CopySemanticsForRules3;
697      options {language=Ruby;output=AST;}
698      a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ;
699      type : 'int' ;
700      modifier : 'public' ;
701      ID : 'a'..'z'+ ;
702      WS : (' '|'\n') {$channel=HIDDEN;} ;
703  
704    END
705    result.should == '(int public a) (int public b) (int public c)'
706  end
707  
708  
709  example "copy semantics for rules3 double" do
710    result = parse( <<-'END', :a, 'public int a,b,c;' )
711      grammar CopySemanticsForRules3Double;
712      options {language=Ruby;output=AST;}
713      a : modifier? type ID (',' ID)* ';' -> ^(type modifier? ID)+ ^(type modifier? ID)+ ;
714      type : 'int' ;
715      modifier : 'public' ;
716      ID : 'a'..'z'+ ;
717      WS : (' '|'\n') {$channel=HIDDEN;} ;
718  
719    END
720    result.should == '(int public a) (int public b) (int public c) (int public a) (int public b) (int public c)'
721  end
722  
723  
724  example "copy semantics for rules4" do
725    result = parse( <<-'END', :a, 'public int a,b,c;' )
726      grammar CopySemanticsForRules4;
727      options {language=Ruby;output=AST;}
728      tokens {MOD;}
729      a : modifier? type ID (',' ID)* ';' -> ^(type ^(MOD modifier)? ID)+ ;
730      type : 'int' ;
731      modifier : 'public' ;
732      ID : 'a'..'z'+ ;
733      WS : (' '|'\n') {$channel=HIDDEN;} ;
734  
735    END
736    result.should == '(int (MOD public) a) (int (MOD public) b) (int (MOD public) c)'
737  end
738  
739  
740  example "copy semantics lists" do
741    result = parse( <<-'END', :a, 'a,b,c;' )
742      grammar CopySemanticsLists;
743      options {language=Ruby;output=AST;}
744      tokens {MOD;}
745      a : ID (',' ID)* ';' -> ID+ ID+ ;
746      ID : 'a'..'z'+ ;
747      WS : (' '|'\n') {$channel=HIDDEN;} ;
748  
749    END
750    result.should == 'a b c a b c'
751  end
752  
753  
754  example "copy rule label" do
755    result = parse( <<-'END', :a, 'a' )
756      grammar CopyRuleLabel;
757      options {language=Ruby;output=AST;}
758      tokens {BLOCK;}
759      a : x=b -> $x $x;
760      b : ID ;
761      ID : 'a'..'z'+ ;
762      WS : (' '|'\n') {$channel=HIDDEN;} ;
763  
764    END
765    result.should == 'a a'
766  end
767  
768  
769  example "copy rule label2" do
770    result = parse( <<-'END', :a, 'a' )
771      grammar CopyRuleLabel2;
772      options {language=Ruby;output=AST;}
773      tokens {BLOCK;}
774      a : x=b -> ^($x $x);
775      b : ID ;
776      ID : 'a'..'z'+ ;
777      WS : (' '|'\n') {$channel=HIDDEN;} ;
778  
779    END
780    result.should == '(a a)'
781  end
782  
783  
784  example "queueing of tokens" do
785    result = parse( <<-'END', :a, 'int a,b,c;' )
786      grammar QueueingOfTokens;
787      options {language=Ruby;output=AST;}
788      a : 'int' ID (',' ID)* ';' -> ^('int' ID+) ;
789      op : '+'|'-' ;
790      ID : 'a'..'z'+ ;
791      INT : '0'..'9'+;
792      WS : (' '|'\n') {$channel=HIDDEN;} ;
793  
794    END
795    result.should == '(int a b c)'
796  end
797  
798  
799  example "copy of tokens" do
800    result = parse( <<-'END', :a, 'int a;' )
801      grammar CopyOfTokens;
802      options {language=Ruby;output=AST;}
803      a : 'int' ID ';' -> 'int' ID 'int' ID ;
804      op : '+'|'-' ;
805      ID : 'a'..'z'+ ;
806      INT : '0'..'9'+;
807      WS : (' '|'\n') {$channel=HIDDEN;} ;
808  
809    END
810    result.should == 'int a int a'
811  end
812  
813  
814  example "token copy in loop" do
815    result = parse( <<-'END', :a, 'int a,b,c;' )
816      grammar TokenCopyInLoop;
817      options {language=Ruby;output=AST;}
818      a : 'int' ID (',' ID)* ';' -> ^('int' ID)+ ;
819      op : '+'|'-' ;
820      ID : 'a'..'z'+ ;
821      INT : '0'..'9'+;
822      WS : (' '|'\n') {$channel=HIDDEN;} ;
823  
824    END
825    result.should == '(int a) (int b) (int c)'
826  end
827  
828  
829  example "token copy in loop against two others" do
830    result = parse( <<-'END', :a, 'int a:1,b:2,c:3;' )
831      grammar TokenCopyInLoopAgainstTwoOthers;
832      options {language=Ruby;output=AST;}
833      a : 'int' ID ':' INT (',' ID ':' INT)* ';' -> ^('int' ID INT)+ ;
834      op : '+'|'-' ;
835      ID : 'a'..'z'+ ;
836      INT : '0'..'9'+;
837      WS : (' '|'\n') {$channel=HIDDEN;} ;
838  
839    END
840    result.should == '(int a 1) (int b 2) (int c 3)'
841  end
842  
843  
844  example "list refd one at a time" do
845    result = parse( <<-'END', :a, 'a b c' )
846      grammar ListRefdOneAtATime;
847      options {language=Ruby;output=AST;}
848      a : ID+ -> ID ID ID ; // works if 3 input IDs
849      op : '+'|'-' ;
850      ID : 'a'..'z'+ ;
851      INT : '0'..'9'+;
852      WS : (' '|'\n') {$channel=HIDDEN;} ;
853  
854    END
855    result.should == 'a b c'
856  end
857  
858  
859  example "split list with labels" do
860    result = parse( <<-'END', :a, 'a b c' )
861      grammar SplitListWithLabels;
862      options {language=Ruby;output=AST;}
863      tokens {VAR;}
864      a : first=ID others+=ID* -> $first VAR $others+ ;
865      op : '+'|'-' ;
866      ID : 'a'..'z'+ ;
867      INT : '0'..'9'+;
868      WS : (' '|'\n') {$channel=HIDDEN;} ;
869  
870    END
871    result.should == 'a VAR b c'
872  end
873  
874  
875  example "complicated melange" do
876    result = parse( <<-'END', :a, 'a a b b b c c c d' )
877      grammar ComplicatedMelange;
878      options {language=Ruby;output=AST;}
879      tokens {BLOCK;}
880      a : A A b=B B b=B c+=C C c+=C D {s=$D.text} -> A+ B+ C+ D ;
881      type : 'int' | 'float' ;
882      A : 'a' ;
883      B : 'b' ;
884      C : 'c' ;
885      D : 'd' ;
886      WS : (' '|'\n') {$channel=HIDDEN;} ;
887  
888    END
889    result.should == 'a a b b b c c c d'
890  end
891  
892  
893  example "rule label" do
894    result = parse( <<-'END', :a, 'a' )
895      grammar RuleLabel;
896      options {language=Ruby;output=AST;}
897      tokens {BLOCK;}
898      a : x=b -> $x;
899      b : ID ;
900      ID : 'a'..'z'+ ;
901      WS : (' '|'\n') {$channel=HIDDEN;} ;
902  
903    END
904    result.should == 'a'
905  end
906  
907  
908  example "ambiguous rule" do
909    result = parse( <<-'END', :a, 'abc 34' )
910      grammar AmbiguousRule;
911      options {language=Ruby;output=AST;}
912      a : ID a -> a | INT ;
913      ID : 'a'..'z'+ ;
914      INT: '0'..'9'+ ;
915      WS : (' '|'\n') {$channel=HIDDEN;} ;
916  
917    END
918    result.should == '34'
919  end
920  
921  
922  example "rule list label" do
923    result = parse( <<-'END', :a, 'a b' )
924      grammar RuleListLabel;
925      options {language=Ruby;output=AST;}
926      tokens {BLOCK;}
927      a : x+=b x+=b -> $x+;
928      b : ID ;
929      ID : 'a'..'z'+ ;
930      WS : (' '|'\n') {$channel=HIDDEN;} ;
931  
932    END
933    result.should == 'a b'
934  end
935  
936  
937  example "rule list label2" do
938    result = parse( <<-'END', :a, 'a b' )
939      grammar RuleListLabel2;
940      options {language=Ruby;output=AST;}
941      tokens {BLOCK;}
942      a : x+=b x+=b -> $x $x*;
943      b : ID ;
944      ID : 'a'..'z'+ ;
945      WS : (' '|'\n') {$channel=HIDDEN;} ;
946  
947    END
948    result.should == 'a b'
949  end
950  
951  
952  example "optional" do
953    result = parse( <<-'END', :a, 'a' )
954      grammar Optional;
955      options {language=Ruby;output=AST;}
956      tokens {BLOCK;}
957      a : x=b (y=b)? -> $x $y?;
958      b : ID ;
959      ID : 'a'..'z'+ ;
960      WS : (' '|'\n') {$channel=HIDDEN;} ;
961  
962    END
963    result.should == 'a'
964  end
965  
966  
967  example "optional2" do
968    result = parse( <<-'END', :a, 'a b' )
969      grammar Optional2;
970      options {language=Ruby;output=AST;}
971      tokens {BLOCK;}
972      a : x=ID (y=b)? -> $x $y?;
973      b : ID ;
974      ID : 'a'..'z'+ ;
975      WS : (' '|'\n') {$channel=HIDDEN;} ;
976  
977    END
978    result.should == 'a b'
979  end
980  
981  
982  example "optional3" do
983    result = parse( <<-'END', :a, 'a b' )
984      grammar Optional3;
985      options {language=Ruby;output=AST;}
986      tokens {BLOCK;}
987      a : x=ID (y=b)? -> ($x $y)?;
988      b : ID ;
989      ID : 'a'..'z'+ ;
990      WS : (' '|'\n') {$channel=HIDDEN;} ;
991  
992    END
993    result.should == 'a b'
994  end
995  
996  
997  example "optional4" do
998    result = parse( <<-'END', :a, 'a b' )
999      grammar Optional4;
1000      options {language=Ruby;output=AST;}
1001      tokens {BLOCK;}
1002      a : x+=ID (y=b)? -> ($x $y)?;
1003      b : ID ;
1004      ID : 'a'..'z'+ ;
1005      WS : (' '|'\n') {$channel=HIDDEN;} ;
1006    END
1007    result.should == 'a b'
1008  end
1009  
1010  
1011  example "optional5" do
1012    result = parse( <<-'END', :a, 'a' )
1013      grammar Optional5;
1014      options {language=Ruby;output=AST;}
1015      tokens {BLOCK;}
1016      a : ID -> ID? ; // match an ID to optional ID
1017      b : ID ;
1018      ID : 'a'..'z'+ ;
1019      WS : (' '|'\n') {$channel=HIDDEN;} ;
1020  
1021    END
1022    result.should == 'a'
1023  end
1024  
1025  
1026  example "arbitrary expr type" do
1027    result = parse( <<-'END', :a, 'a b' )
1028      grammar ArbitraryExprType;
1029      options {language=Ruby;output=AST;}
1030      tokens {BLOCK;}
1031      a : x+=b x+=b -> {ANTLR3::CommonTree.new(nil)};
1032      b : ID ;
1033      ID : 'a'..'z'+ ;
1034      WS : (' '|'\n') {$channel=HIDDEN;} ;
1035  
1036    END
1037    result.should == ''
1038  end
1039  
1040  
1041  example "set" do
1042    result = parse( <<-'END', :a, '2 a 34 de' )
1043      grammar SetT;
1044      options {language=Ruby;output=AST;} 
1045      a: (INT|ID)+ -> INT+ ID+ ;
1046      INT: '0'..'9'+;
1047      ID : 'a'..'z'+;
1048      WS : (' '|'\n') {$channel=HIDDEN;} ;
1049  
1050    END
1051    result.should == '2 34 a de'
1052  end
1053  
1054  
1055  example "set2" do
1056    result = parse( <<-'END', :a, '2' )
1057      grammar Set2;
1058      options {language=Ruby;output=AST;} 
1059      a: (INT|ID) -> INT? ID? ;
1060      INT: '0'..'9'+;
1061      ID : 'a'..'z'+;
1062      WS : (' '|'\n') {$channel=HIDDEN;} ;
1063  
1064    END
1065    result.should == '2'
1066  end
1067  
1068  
1069  example "set with label" do
1070    warn( 'test SetWithLabel officially broken' )
1071    #result = parse(<<-'END', :a, '2')
1072    #  grammar SetWithLabel;
1073    #  options {language=Ruby;output=AST;} 
1074    #  a : x=(INT|ID) -> $x ;
1075    #  INT: '0'..'9'+;
1076    #  ID : 'a'..'z'+;
1077    #  WS : (' '|'\n') {$channel=HIDDEN;} ;
1078    #
1079    #END
1080    #result.should == '2'
1081  end
1082  
1083  
1084  example "rewrite action" do
1085    result = parse( <<-'END', :r, '25' )
1086      grammar RewriteAction; 
1087      options {language=Ruby;output=AST;}
1088      tokens { FLOAT; }
1089      r
1090          : INT -> { ANTLR3::CommonTree.new( create_token( FLOAT, nil, "#{$INT.text}.0" ) ) }
1091          ; 
1092      INT : '0'..'9'+; 
1093      WS: (' ' | '\n' | '\t')+ {$channel = HIDDEN;};
1094  
1095    END
1096    result.should == '25.0'
1097  end
1098  
1099  
1100  example "optional subrule without real elements" do
1101    result = parse( <<-'END', :modulo, 'modulo abc (x y #)' )
1102      grammar OptionalSubruleWithoutRealElements;
1103      options {language=Ruby;output=AST;} 
1104      tokens {PARMS;} 
1105      
1106      modulo 
1107       : 'modulo' ID ('(' parms+ ')')? -> ^('modulo' ID ^(PARMS parms+)?) 
1108       ; 
1109      parms : '#'|ID; 
1110      ID : ('a'..'z' | 'A'..'Z')+;
1111      WS : (' '|'\n') {$channel=HIDDEN;} ;
1112  
1113    END
1114    result.should == '(modulo abc (PARMS x y #))'
1115  end
1116  
1117  
1118  example "wildcard" do
1119    result = parse( <<-'END', :a, 'abc 34' )
1120      grammar Wildcard;
1121      options {language=Ruby;output=AST;}
1122      a : ID c=. -> $c;
1123      ID : 'a'..'z'+ ;
1124      INT : '0'..'9'+;
1125      WS : (' '|'\n') {$channel=HIDDEN;} ;
1126  
1127    END
1128    result.should == '34'
1129  end
1130  
1131  
1132  example "extra token in simple decl" do
1133    result, errors = parse( <<-'END', :decl, 'int 34 x=1;', true )
1134      grammar ExtraTokenInSimpleDecl;
1135      options {language=Ruby;output=AST;}
1136      tokens {EXPR;}
1137      decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ;
1138      type : 'int' | 'float' ;
1139      ID : 'a'..'z'+ ;
1140      INT : '0'..'9'+;
1141      WS : (' '|'\n') {$channel=HIDDEN;} ;
1142  
1143    END
1144    errors.should == [ 'line 1:4 extraneous input "34" expecting ID' ]
1145    result.should == '(EXPR int x 1)'
1146  end
1147  
1148  
1149  example "missing id in simple decl" do
1150    result, errors = parse( <<-'END', :decl, 'int =1;', true )
1151      grammar MissingIDInSimpleDecl;
1152      options {language=Ruby;output=AST;}
1153      tokens {EXPR;}
1154      decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ;
1155      type : 'int' | 'float' ;
1156      ID : 'a'..'z'+ ;
1157      INT : '0'..'9'+;
1158      WS : (' '|'\n') {$channel=HIDDEN;} ;
1159  
1160    END
1161    errors.should == [ 'line 1:4 missing ID at "="' ]
1162    result.should == '(EXPR int <missing ID> 1)'
1163  end
1164  
1165  
1166  example "missing set in simple decl" do
1167    result, errors = parse( <<-'END', :decl, 'x=1;', true )
1168      grammar MissingSetInSimpleDecl;
1169      options {language=Ruby;output=AST;}
1170      tokens {EXPR;}
1171      decl : type ID '=' INT ';' -> ^(EXPR type ID INT) ;
1172      type : 'int' | 'float' ;
1173      ID : 'a'..'z'+ ;
1174      INT : '0'..'9'+;
1175      WS : (' '|'\n') {$channel=HIDDEN;} ;
1176  
1177    END
1178    errors.should == [ 'line 1:0 mismatched input "x" expecting set nil' ]
1179    result.should == '(EXPR <error: x> x 1)'
1180  end
1181  
1182  
1183  example "missing token gives error node" do
1184    result, errors = parse( <<-'END', :a, 'abc', true )
1185      grammar MissingTokenGivesErrorNode;
1186      options {language=Ruby;output=AST;}
1187      a : ID INT -> ID INT ;
1188      ID : 'a'..'z'+ ;
1189      INT : '0'..'9'+;
1190      WS : (' '|'\n') {$channel=HIDDEN;} ;
1191  
1192    END
1193    errors.should == [ "line 0:-1 missing INT at \"<EOF>\"" ]
1194    result.should == 'abc <missing INT>'
1195    #end
1196  end
1197  
1198  
1199  example "extra token gives error node" do
1200    result, errors = parse( <<-'END', :a, 'abc ick 34', true )
1201      grammar ExtraTokenGivesErrorNode;
1202      options {language=Ruby;output=AST;}
1203      a : b c -> b c;
1204      b : ID -> ID ;
1205      c : INT -> INT ;
1206      ID : 'a'..'z'+ ;
1207      INT : '0'..'9'+;
1208      WS : (' '|'\n') {$channel=HIDDEN;} ;
1209  
1210    END
1211    errors.should == [ 'line 1:4 extraneous input "ick" expecting INT' ]
1212    result.should == 'abc 34'
1213  end
1214  
1215  
1216  example "missing first token gives error node" do
1217    result, errors = parse( <<-'END', :a, '34', true )
1218      grammar MissingFirstTokenGivesErrorNode;
1219      options {language=Ruby;output=AST;}
1220      a : ID INT -> ID INT ;
1221      ID : 'a'..'z'+ ;
1222      INT : '0'..'9'+;
1223      WS : (' '|'\n') {$channel=HIDDEN;} ;
1224  
1225    END
1226    errors.should == [ 'line 1:0 missing ID at "34"' ]
1227    result.should == '<missing ID> 34'
1228  end
1229  
1230  
1231  example "missing first token gives error node2" do
1232    result, errors = parse( <<-'END', :a, '34', true )
1233      grammar MissingFirstTokenGivesErrorNode2;
1234      options {language=Ruby;output=AST;}
1235      a : b c -> b c;
1236      b : ID -> ID ;
1237      c : INT -> INT ;
1238      ID : 'a'..'z'+ ;
1239      INT : '0'..'9'+;
1240      WS : (' '|'\n') {$channel=HIDDEN;} ;
1241  
1242    END
1243    errors.should == [ 'line 1:0 missing ID at "34"' ]
1244    result.should == '<missing ID> 34'
1245  end
1246  
1247  
1248  example "no viable alt gives error node" do
1249    result, errors = parse( <<-'END', :a, '*', true )
1250      grammar NoViableAltGivesErrorNode;
1251      options {language=Ruby;output=AST;}
1252      a : b -> b | c -> c;
1253      b : ID -> ID ;
1254      c : INT -> INT ;
1255      ID : 'a'..'z'+ ;
1256      S : '*' ;
1257      INT : '0'..'9'+;
1258      WS : (' '|'\n') {$channel=HIDDEN;} ;
1259  
1260    END
1261    errors.should == [ 'line 1:0 no viable alternative at input "*"' ]
1262    result.should == '<unexpected: 0 S["*"] @ line 1 col 0 (0..0), resync = *>'
1263  end
1264  
1265  
1266  example "cardinality" do
1267    lambda do
1268      parse( <<-'END', :a, "a b 3 4 5" )
1269        grammar Cardinality;
1270        options {language=Ruby;output=AST;}
1271        tokens {BLOCK;}
1272        a : ID ID INT INT INT -> (ID INT)+;
1273        ID : 'a'..'z'+ ;
1274        INT : '0'..'9'+; 
1275        WS : (' '|'\n') {$channel=HIDDEN;} ;
1276      END
1277    end.should raise_error( ANTLR3::Error::RewriteCardinalityError )
1278  end
1279  
1280  example "cardinality2" do
1281    lambda do
1282      parse( <<-'END', :a, "a b" )
1283        grammar Cardinality2;
1284        options {language=Ruby;output=AST;}
1285        tokens {BLOCK;}
1286        a : ID+ -> ID ID ID ; // only 2 input IDs
1287        op : '+'|'-' ;
1288        ID : 'a'..'z'+ ;
1289        INT : '0'..'9'+;
1290        WS : (' '|'\n') {$channel=HIDDEN;} ;
1291      END
1292    end.should raise_error( ANTLR3::Error::RewriteCardinalityError )
1293  end
1294  
1295  example "cardinality3" do
1296    lambda do
1297      parse( <<-'END', :a, "3" )
1298        grammar Cardinality3;
1299        options {language=Ruby;output=AST;}
1300        tokens {BLOCK;}
1301        a : ID? INT -> ID INT ;
1302        op : '+'|'-' ;
1303        ID : 'a'..'z'+ ;
1304        INT : '0'..'9'+;
1305        WS : (' '|'\n') {$channel=HIDDEN;} ;
1306      END
1307    end.should raise_error( ANTLR3::Error::RewriteEmptyStream )
1308  end
1309  
1310  example "loop cardinality" do
1311    lambda do
1312      parse( <<-'END', :a, "3" )
1313        grammar LoopCardinality;
1314        options {language=Ruby;output=AST;}
1315        a : ID? INT -> ID+ INT ;
1316        op : '+'|'-' ;
1317        ID : 'a'..'z'+ ;
1318        INT : '0'..'9'+;
1319        WS : (' '|'\n') {$channel=HIDDEN;} ;
1320      END
1321    end.should raise_error( ANTLR3::Error::RewriteEarlyExit )
1322  end
1323
1324
1325
1326end
1327