1#!/usr/bin/ruby
2# encoding: utf-8
3
4require 'antlr3/test/functional'
5
6class TestTreeParser1 < ANTLR3::Test::Functional
7  
8  example "flat list" do
9    compile_and_load inline_grammar( <<-'END' )
10      grammar FlatList;
11      options {
12          language=Ruby;
13          output=AST;
14      }
15      a : ID INT;
16      ID : 'a'..'z'+ ;
17      INT : '0'..'9'+;
18      WS : (' '|'\n') {$channel=HIDDEN;} ;
19    END
20    compile_and_load inline_grammar( <<-'END' )
21      tree grammar FlatListWalker;
22      options {
23          language=Ruby;
24          ASTLabelType=CommonTree;
25      }
26      @members { include ANTLR3::Test::CaptureOutput }
27      a : ID INT
28          {self.capture("\%s, \%s" \% [$ID, $INT])}
29        ;
30    END
31    
32    lexer  = FlatList::Lexer.new( "abc 34" )
33    tokens = ANTLR3::CommonTokenStream.new( lexer )
34    parser = FlatList::Parser.new( tokens )
35    
36    result = parser.a
37    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
38    nodes.token_stream = tokens
39    walker = FlatListWalker::TreeParser.new( nodes )
40    walker.a
41    walker.output.should == "abc, 34"
42  end
43  
44  example "simple tree" do
45    compile_and_load inline_grammar( <<-'END' )
46      grammar SimpleTree;
47      options {
48          language=Ruby;
49          output=AST;
50      }
51      a : ID INT -> ^(ID INT);
52      ID : 'a'..'z'+ ;
53      INT : '0'..'9'+;
54      WS : (' '|'\\n') {$channel=HIDDEN;} ;
55    END
56    compile_and_load inline_grammar( <<-'END' )
57      tree grammar SimpleTreeWalker;
58      options {
59          language=Ruby;
60          ASTLabelType=CommonTree;
61      }
62      @members { include ANTLR3::Test::CaptureOutput }
63      
64      a : ^(ID INT)
65          {capture('\%s, \%s' \% [$ID, $INT])}
66        ;
67    END
68    lexer  = SimpleTree::Lexer.new( "abc 34" )
69    tokens = ANTLR3::CommonTokenStream.new( lexer )
70    parser = SimpleTree::Parser.new( tokens )
71    
72    result = parser.a
73    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
74    nodes.token_stream = tokens
75    walker = SimpleTreeWalker::TreeParser.new( nodes )
76    walker.a
77    walker.output.should == "abc, 34"
78  end
79  
80  example "flat vs tree decision" do
81    compile_and_load inline_grammar( <<-'END' )
82      grammar FlatVsTreeDecision;
83      options {
84          language=Ruby;
85          output=AST;
86      }
87      a : b c ;
88      b : ID INT -> ^(ID INT);
89      c : ID INT;
90      ID : 'a'..'z'+ ;
91      INT : '0'..'9'+;
92      WS : (' '|'\\n') {$channel=HIDDEN;} ;
93    END
94    compile_and_load inline_grammar( <<-'END' )
95      tree grammar FlatVsTreeDecisionWalker;
96      options {
97          language=Ruby;
98          ASTLabelType=CommonTree;
99      }
100      @members { include ANTLR3::Test::CaptureOutput }
101      
102      a : b b ;
103      b : ID INT    {capture("\%s \%s\n" \% [$ID, $INT])}
104        | ^(ID INT) {capture("^(\%s \%s)" \% [$ID, $INT])}
105        ;
106    END
107    lexer  = FlatVsTreeDecision::Lexer.new( "a 1 b 2" )
108    tokens = ANTLR3::CommonTokenStream.new( lexer )
109    parser = FlatVsTreeDecision::Parser.new( tokens )
110    
111    result = parser.a
112    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
113    nodes.token_stream = tokens
114    walker = FlatVsTreeDecisionWalker::TreeParser.new( nodes )
115    walker.a
116    walker.output.should == "^(a 1)b 2\n"
117  end
118  
119  example "flat vs tree decision2" do
120    compile_and_load inline_grammar( <<-'END' )
121      grammar FlatVsTreeDecision2;
122      options {
123          language=Ruby;
124          output=AST;
125      }
126      a : b c ;
127      b : ID INT+ -> ^(ID INT+);
128      c : ID INT+;
129      ID : 'a'..'z'+ ;
130      INT : '0'..'9'+;
131      WS : (' '|'\n') {$channel=HIDDEN;} ;
132    END
133    compile_and_load inline_grammar( <<-'END' )
134      tree grammar FlatVsTreeDecision2Walker;
135      options {
136          language=Ruby;
137          ASTLabelType=CommonTree;
138      }
139      @members { include ANTLR3::Test::CaptureOutput }
140      a : b b ;
141      b : ID INT+    {say("#{$ID} #{$INT}")}
142        | ^(x=ID (y=INT)+) {capture("^(#{$x} #{$y})")}
143        ;
144    END
145    lexer  = FlatVsTreeDecision2::Lexer.new( "a 1 2 3 b 4 5" )
146    tokens = ANTLR3::CommonTokenStream.new( lexer )
147    parser = FlatVsTreeDecision2::Parser.new( tokens )
148    
149    result = parser.a
150    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
151    nodes.token_stream = tokens
152    walker = FlatVsTreeDecision2Walker::TreeParser.new( nodes )
153    walker.a
154    walker.output.should == "^(a 3)b 5\n"
155  end
156  
157  example "cyclic dfa lookahead" do
158    compile_and_load inline_grammar( <<-'END' )
159      grammar CyclicDFALookahead;
160      options {
161          language=Ruby;
162          output=AST;
163      }
164      a : ID INT+ PERIOD;
165      ID : 'a'..'z'+ ;
166      INT : '0'..'9'+;
167      SEMI : ';' ;
168      PERIOD : '.' ;
169      WS : (' '|'\n') {$channel=HIDDEN;} ;
170    END
171    compile_and_load inline_grammar( <<-'END' )
172      tree grammar CyclicDFALookaheadWalker;
173      options {
174          language=Ruby;
175          ASTLabelType=CommonTree;
176      }
177      @members { include ANTLR3::Test::CaptureOutput }
178      a : ID INT+ PERIOD {capture("alt 1")}
179        | ID INT+ SEMI   {capture("alt 2")}
180        ;
181    END
182    lexer  = CyclicDFALookahead::Lexer.new( "a 1 2 3." )
183    tokens = ANTLR3::CommonTokenStream.new( lexer )
184    parser = CyclicDFALookahead::Parser.new( tokens )
185    
186    result = parser.a
187    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
188    nodes.token_stream = tokens
189    walker = CyclicDFALookaheadWalker::TreeParser.new( nodes )
190    walker.a
191    walker.output.should == "alt 1"
192  end
193  
194  example "nullable child list" do
195    compile_and_load inline_grammar( <<-'END' )
196      grammar NullableChildList;
197      options {
198          language=Ruby;
199          output=AST;
200      }
201      a : ID INT? -> ^(ID INT?);
202      ID : 'a'..'z'+ ;
203      INT : '0'..'9'+;
204      WS : (' '|'\\n') {$channel=HIDDEN;} ;
205    END
206    compile_and_load inline_grammar( <<-'END' )
207      tree grammar NullableChildListWalker;
208      options {
209          language=Ruby;
210          ASTLabelType=CommonTree;
211      }
212      @members { include ANTLR3::Test::CaptureOutput }
213      a : ^(ID INT?)
214          {capture($ID.to_s)}
215        ;
216    END
217    lexer  = NullableChildList::Lexer.new( "abc" )
218    tokens = ANTLR3::CommonTokenStream.new( lexer )
219    parser = NullableChildList::Parser.new( tokens )
220    
221    result = parser.a
222    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
223    nodes.token_stream = tokens
224    walker = NullableChildListWalker::TreeParser.new( nodes )
225    walker.a
226    walker.output.should == "abc"
227  end
228  
229  example "nullable child list2" do
230    compile_and_load inline_grammar( <<-'END' )
231      grammar NullableChildList2;
232      options {
233          language=Ruby;
234          output=AST;
235      }
236      a : ID INT? SEMI -> ^(ID INT?) SEMI ;
237      ID : 'a'..'z'+ ;
238      INT : '0'..'9'+;
239      SEMI : ';' ;
240      WS : (' '|'\n') {$channel=HIDDEN;} ;
241    END
242    compile_and_load inline_grammar( <<-'END' )
243      tree grammar NullableChildList2Walker;
244      options {
245          language=Ruby;
246          ASTLabelType=CommonTree;
247      }
248      @members { include ANTLR3::Test::CaptureOutput }
249      a : ^(ID INT?) SEMI
250          {capture($ID.to_s)}
251        ;
252    END
253    lexer  = NullableChildList2::Lexer.new( "abc;" )
254    tokens = ANTLR3::CommonTokenStream.new( lexer )
255    parser = NullableChildList2::Parser.new( tokens )
256    
257    result = parser.a
258    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
259    nodes.token_stream = tokens
260    walker = NullableChildList2Walker::TreeParser.new( nodes )
261    walker.a
262    walker.output.should == "abc"
263  end
264  
265  example "nullable child list3" do
266    compile_and_load inline_grammar( <<-'END' )
267      grammar NullableChildList3;
268      options {
269          language=Ruby;
270          output=AST;
271      }
272      a : x=ID INT? (y=ID)? SEMI -> ^($x INT? $y?) SEMI ;
273      ID : 'a'..'z'+ ;
274      INT : '0'..'9'+;
275      SEMI : ';' ;
276      WS : (' '|'\\n') {$channel=HIDDEN;} ;
277    END
278    compile_and_load inline_grammar( <<-'END' )
279      tree grammar NullableChildList3Walker;
280      options {
281          language=Ruby;
282          ASTLabelType=CommonTree;
283      }
284      @members { include ANTLR3::Test::CaptureOutput }
285      a : ^(ID INT? b) SEMI
286          {self.capture($ID.to_s + ", " + $b.text.to_s)}
287        ;
288      b : ID? ;
289    END
290    lexer  = NullableChildList3::Lexer.new( "abc def;" )
291    tokens = ANTLR3::CommonTokenStream.new( lexer )
292    parser = NullableChildList3::Parser.new( tokens )
293    
294    result = parser.a
295    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
296    nodes.token_stream = tokens
297    walker = NullableChildList3Walker::TreeParser.new( nodes )
298    walker.a
299    walker.output.should == "abc, def"
300  end
301  
302  example "actions after root" do
303    compile_and_load inline_grammar( <<-'END' )
304      grammar ActionsAfterRoot;
305      options {
306          language=Ruby;
307          output=AST;
308      }
309      a : x=ID INT? SEMI -> ^($x INT?) ;
310      ID : 'a'..'z'+ ;
311      INT : '0'..'9'+;
312      SEMI : ';' ;
313      WS : (' '|'\n') {$channel=HIDDEN;} ;
314    END
315    compile_and_load inline_grammar( <<-'END' )
316      tree grammar ActionsAfterRootWalker;
317      options {
318          language=Ruby;
319          ASTLabelType=CommonTree;
320      }
321      @members { include ANTLR3::Test::CaptureOutput }
322      a @init {x=0} : ^(ID {x=1} {x=2} INT?)
323          {say( $ID.to_s + ", " + x.to_s )}
324        ;
325    END
326    lexer  = ActionsAfterRoot::Lexer.new( "abc;" )
327    tokens = ANTLR3::CommonTokenStream.new( lexer )
328    parser = ActionsAfterRoot::Parser.new( tokens )
329    
330    result = parser.a
331    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
332    nodes.token_stream = tokens
333    walker = ActionsAfterRootWalker::TreeParser.new( nodes )
334    walker.a
335    walker.output.should == "abc, 2\n"
336  end
337  
338  example "wildcard lookahead" do
339    compile_and_load inline_grammar( <<-'END' )
340      grammar WildcardLookahead;
341      options {language=Ruby; output=AST;}
342      a : ID '+'^ INT;
343      ID : 'a'..'z'+ ;
344      INT : '0'..'9'+;
345      SEMI : ';' ;
346      PERIOD : '.' ;
347      WS : (' '|'\n') {$channel=HIDDEN;} ;
348    END
349    compile_and_load inline_grammar( <<-'END' )
350      tree grammar WildcardLookaheadWalker;
351      options {language=Ruby; tokenVocab=WildcardLookahead; ASTLabelType=CommonTree;}
352      @members { include ANTLR3::Test::CaptureOutput }
353      a : ^('+' . INT) { capture("alt 1") }
354        ;
355    END
356    lexer  = WildcardLookahead::Lexer.new( "a + 2" )
357    tokens = ANTLR3::CommonTokenStream.new( lexer )
358    parser = WildcardLookahead::Parser.new( tokens )
359    
360    result = parser.a
361    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
362    nodes.token_stream = tokens
363    walker = WildcardLookaheadWalker::TreeParser.new( nodes )
364    walker.a
365    walker.output.should == "alt 1"
366  end
367  
368  example "wildcard lookahead2" do
369    compile_and_load inline_grammar( <<-'END' )
370      grammar WildcardLookahead2;
371      options {language=Ruby; output=AST;}
372      a : ID '+'^ INT;
373      ID : 'a'..'z'+ ;
374      INT : '0'..'9'+;
375      SEMI : ';' ;
376      PERIOD : '.' ;
377      WS : (' '|'\n') {$channel=HIDDEN;} ;
378    END
379    compile_and_load inline_grammar( <<-'END' )
380      tree grammar WildcardLookahead2Walker;
381      options {language=Ruby; tokenVocab=WildcardLookahead2; ASTLabelType=CommonTree;}
382      @members { include ANTLR3::Test::CaptureOutput }
383      a : ^('+' . INT) { capture("alt 1") }
384        | ^('+' . .)   { capture("alt 2") }
385        ;
386    END
387    lexer  = WildcardLookahead2::Lexer.new( "a + 2" )
388    tokens = ANTLR3::CommonTokenStream.new( lexer )
389    parser = WildcardLookahead2::Parser.new( tokens )
390    
391    result = parser.a
392    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
393    nodes.token_stream = tokens
394    walker = WildcardLookahead2Walker::TreeParser.new( nodes )
395    walker.a
396    walker.output.should == "alt 1"
397  end
398  
399  example "wildcard lookahead3" do
400    compile_and_load inline_grammar( <<-'END' )
401      grammar WildcardLookahead3;
402      options {language=Ruby; output=AST;}
403      a : ID '+'^ INT;
404      ID : 'a'..'z'+ ;
405      INT : '0'..'9'+;
406      SEMI : ';' ;
407      PERIOD : '.' ;
408      WS : (' '|'\n') {$channel=HIDDEN;} ;
409    END
410    compile_and_load inline_grammar( <<-'END' )
411      tree grammar WildcardLookahead3Walker;
412      options {language=Ruby; tokenVocab=WildcardLookahead3; ASTLabelType=CommonTree;}
413      @members { include ANTLR3::Test::CaptureOutput }
414      a : ^('+' ID INT) { capture("alt 1") }
415        | ^('+' . .)   { capture("alt 2") }
416        ;
417    END
418    lexer  = WildcardLookahead3::Lexer.new( "a + 2" )
419    tokens = ANTLR3::CommonTokenStream.new( lexer )
420    parser = WildcardLookahead3::Parser.new( tokens )
421    
422    result = parser.a
423    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
424    nodes.token_stream = tokens
425    walker = WildcardLookahead3Walker::TreeParser.new( nodes )
426    walker.a
427    walker.output.should == "alt 1"
428  end
429  
430  example "wildcard plus lookahead" do
431    compile_and_load inline_grammar( <<-'END' )
432      grammar WildcardPlusLookahead;
433      options {language=Ruby; output=AST;}
434      a : ID '+'^ INT;
435      ID : 'a'..'z'+ ;
436      INT : '0'..'9'+;
437      SEMI : ';' ;
438      PERIOD : '.' ;
439      WS : (' '|'\n') {$channel=HIDDEN;} ;
440    END
441    compile_and_load inline_grammar( <<-'END' )
442      tree grammar WildcardPlusLookaheadWalker;
443      options {language=Ruby; tokenVocab=WildcardPlusLookahead; ASTLabelType=CommonTree;}
444      @members { include ANTLR3::Test::CaptureOutput }
445      a : ^('+' INT INT ) { capture("alt 1") }
446        | ^('+' .+)   { capture("alt 2") }
447        ;
448    END
449    lexer  = WildcardPlusLookahead::Lexer.new( "a + 2" )
450    tokens = ANTLR3::CommonTokenStream.new( lexer )
451    parser = WildcardPlusLookahead::Parser.new( tokens )
452    
453    result = parser.a
454    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
455    nodes.token_stream = tokens
456    walker = WildcardPlusLookaheadWalker::TreeParser.new( nodes )
457    walker.a
458    walker.output.should == "alt 2"
459  end
460  
461end
462
463
464class TestTreeParser2 < ANTLR3::Test::Functional
465  inline_grammar( <<-'END' )
466    grammar GenericLanguage;
467    options {
468        language = Ruby;
469        output=AST;
470    }
471    
472    tokens {
473        VAR_DEF;
474        ARG_DEF;
475        FUNC_HDR;
476        FUNC_DECL;
477        FUNC_DEF;
478        BLOCK;
479    }
480    
481    program
482        :   declaration+
483        ;
484    
485    declaration
486        :   variable
487        |   functionHeader ';' -> ^(FUNC_DECL functionHeader)
488        |   functionHeader block -> ^(FUNC_DEF functionHeader block)
489        ;
490    
491    variable
492        :   type declarator ';' -> ^(VAR_DEF type declarator)
493        ;
494    
495    declarator
496        :   ID 
497        ;
498    
499    functionHeader
500        :   type ID '(' ( formalParameter ( ',' formalParameter )* )? ')'
501            -> ^(FUNC_HDR type ID formalParameter+)
502        ;
503    
504    formalParameter
505        :   type declarator -> ^(ARG_DEF type declarator)
506        ;
507    
508    type
509        :   'int'   
510        |   'char'  
511        |   'void'
512        |   ID        
513        ;
514    
515    block
516        :   lc='{'
517                variable*
518                stat*
519            '}'
520            -> ^(BLOCK[$lc,"BLOCK"] variable* stat*)
521        ;
522    
523    stat: forStat
524        | expr ';'!
525        | block
526        | assignStat ';'!
527        | ';'!
528        ;
529    
530    forStat
531        :   'for' '(' start=assignStat ';' expr ';' next=assignStat ')' block
532            -> ^('for' $start expr $next block)
533        ;
534    
535    assignStat
536        :   ID EQ expr -> ^(EQ ID expr)
537        ;
538    
539    expr:   condExpr
540        ;
541    
542    condExpr
543        :   aexpr ( ('=='^ | '<'^) aexpr )?
544        ;
545    
546    aexpr
547        :   atom ( '+'^ atom )*
548        ;
549    
550    atom
551        : ID      
552        | INT      
553        | '(' expr ')' -> expr
554        ; 
555    
556    FOR : 'for' ;
557    INT_TYPE : 'int' ;
558    CHAR: 'char';
559    VOID: 'void';
560    
561    ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
562        ;
563    
564    INT :	('0'..'9')+
565        ;
566    
567    EQ   : '=' ;
568    EQEQ : '==' ;
569    LT   : '<' ;
570    PLUS : '+' ;
571    
572    WS  :   (   ' '
573            |   '\t'
574            |   '\r'
575            |   '\n'
576            )+
577            { $channel=HIDDEN }
578        ;
579  END
580
581  inline_grammar( <<-'END' )
582    tree grammar GenericLanguageWalker;
583    options {
584        language = Ruby;
585        tokenVocab = GenericLanguage;
586        ASTLabelType = CommonTree;
587    }
588    
589    @init { @traces = [] }
590    @members {
591      attr_reader :traces
592      
593      def trace_in(rule_name, rule_index)
594        @traces << ">#{rule_name}"
595      end
596      
597      def trace_out(rule_name, rule_index)
598        @traces << "<#{rule_name}"
599      end
600    }
601    
602    program
603        :   declaration+
604        ;
605    
606    declaration
607        :   variable
608        |   ^(FUNC_DECL functionHeader)
609        |   ^(FUNC_DEF functionHeader block)
610        ;
611    
612    variable returns [res]
613        :   ^(VAR_DEF type declarator)
614            { 
615                $res = $declarator.text; 
616            }
617        ;
618    
619    declarator
620        :   ID 
621        ;
622    
623    functionHeader
624        :   ^(FUNC_HDR type ID formalParameter+)
625        ;
626    
627    formalParameter
628        :   ^(ARG_DEF type declarator)
629        ;
630    
631    type
632        :   'int'
633        |   'char'
634        |   'void'
635        |   ID        
636        ;
637    
638    block
639        :   ^(BLOCK variable* stat*)
640        ;
641    
642    stat: forStat
643        | expr
644        | block
645        ;
646    
647    forStat
648        :   ^('for' expr expr expr block)
649        ;
650    
651    expr:   ^(EQEQ expr expr)
652        |   ^(LT expr expr)
653        |   ^(PLUS expr expr)
654        |   ^(EQ ID expr)
655        |   atom
656        ;
657    
658    atom
659        : ID      
660        | INT      
661        ;
662  END
663  
664  compile_options :trace => true
665  
666  example "processing AST output from a parser with a tree parser" do
667    input_source = <<-END.fixed_indent( 0 )
668      char c;
669      int x;
670      
671      void bar(int x);
672      
673      int foo(int y, char d) {
674        int i;
675        for (i=0; i<3; i=i+1) {
676          x=3;
677          y=5;
678        }
679      }
680    END
681    
682    lexer = GenericLanguage::Lexer.new( input_source )
683    parser = GenericLanguage::Parser.new( lexer )
684    
685    expected_tree = <<-END.strip!.gsub!( /\s+/, ' ' )
686      (VAR_DEF char c)
687      (VAR_DEF int x)
688      (FUNC_DECL (FUNC_HDR void bar (ARG_DEF int x)))
689      (FUNC_DEF
690        (FUNC_HDR int foo (ARG_DEF int y) (ARG_DEF char d))
691        (BLOCK
692          (VAR_DEF int i)
693          (for (= i 0) (< i 3) (= i (+ i 1))
694            (BLOCK (= x 3) (= y 5)))))
695    END
696    
697    result = parser.program
698    result.tree.inspect.should == expected_tree
699    
700    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
701    nodes.token_stream = parser.input
702    tree_parser = GenericLanguageWalker::TreeParser.new( nodes )
703    
704    tree_parser.program
705    tree_parser.traces.should == %w(
706      >program          >declaration      >variable         >type           
707      <type             >declarator       <declarator       <variable       
708      <declaration      >declaration      >variable         >type           
709      <type             >declarator       <declarator       <variable       
710      <declaration      >declaration      >functionHeader   >type           
711      <type             >formalParameter  >type             <type           
712      >declarator       <declarator       <formalParameter  <functionHeader 
713      <declaration      >declaration      >functionHeader   >type           
714      <type             >formalParameter  >type             <type           
715      >declarator       <declarator       <formalParameter  >formalParameter
716      >type             <type             >declarator       <declarator     
717      <formalParameter  <functionHeader   >block            >variable       
718      >type             <type             >declarator       <declarator     
719      <variable         >stat             >forStat          >expr           
720      >expr             >atom             <atom             <expr           
721      <expr             >expr             >expr             >atom           
722      <atom             <expr             >expr             >atom           
723      <atom             <expr             <expr             >expr           
724      >expr             >expr             >atom             <atom           
725      <expr             >expr             >atom             <atom           
726      <expr             <expr             <expr             >block          
727      >stat             >expr             >expr             >atom           
728      <atom             <expr             <expr             <stat           
729      >stat             >expr             >expr             >atom           
730      <atom             <expr             <expr             <stat           
731      <block            <forStat          <stat             <block          
732      <declaration      <program        
733    )
734  end
735  
736  example 'tree parser rule label property references' do
737    input = "char c;\n"
738    lexer  = GenericLanguage::Lexer.new( "char c;\n" )
739    parser = GenericLanguage::Parser.new( lexer )
740    
741    result = parser.variable
742    nodes = ANTLR3::AST::CommonTreeNodeStream.new( result.tree )
743    nodes.token_stream = parser.input
744    
745    tree_parser = GenericLanguageWalker::TreeParser.new( nodes )
746    tree_parser.variable.should == 'c'
747  end
748  
749end
750