Home | History | Annotate | Download | only in tree-parser
      1 #!/usr/bin/ruby
      2 # encoding: utf-8
      3 
      4 require 'antlr3/test/functional'
      5 
      6 class 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   
    461 end
    462 
    463 
    464 class 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   
    749 end
    750