Home | History | Annotate | Download | only in ast-output
      1 #!/usr/bin/ruby
      2 # encoding: utf-8
      3 
      4 require 'antlr3/test/functional'
      5 
      6 
      7 class TestHeterogeneousNodeTypes < ANTLR3::Test::Functional
      8 
      9   inline_grammar( <<-'END' )
     10     grammar VToken;
     11     options {
     12         language=Ruby;
     13         output=AST;
     14     }
     15     @members {
     16       class V < ANTLR3::CommonTree
     17         def to_s
     18           return @token.text + "<V>"
     19         end
     20       end
     21     }
     22     a : ID<V> ;
     23     ID : 'a'..'z'+ ;
     24     WS : (' '|'\n') {$channel=HIDDEN;} ;
     25   END
     26 
     27 
     28   inline_grammar( <<-'END' )
     29     grammar TokenWithQualifiedType;
     30     options {
     31         language=Ruby;
     32         output=AST;
     33     }
     34     @members {
     35       class V < ANTLR3::CommonTree
     36         def to_s
     37           return @token.text + "<V>"
     38         end
     39       end
     40     }
     41     a : ID<TokenWithQualifiedType.Parser.V> ;
     42     ID : 'a'..'z'+ ;
     43     WS : (' '|'\n') {$channel=HIDDEN;} ;
     44   END
     45 
     46 
     47   inline_grammar( <<-'END' )
     48     grammar TokenWithLabel;
     49     options {
     50         language=Ruby;
     51         output=AST;
     52     }
     53     @members {
     54     class V < ANTLR3::CommonTree
     55       def to_s
     56         return @token.text + "<V>"
     57       end
     58     end
     59     }
     60     a : x=ID<V> ;
     61     ID : 'a'..'z'+ ;
     62     WS : (' '|'\n') {$channel=HIDDEN;} ;
     63   END
     64 
     65 
     66   inline_grammar( <<-'END' )
     67     grammar TokenWithListLabel;
     68     options {
     69         language=Ruby;
     70         output=AST;
     71     }
     72     @members {
     73       class V < ANTLR3::CommonTree
     74         def to_s
     75           return @token.text + "<V>"
     76         end
     77       end
     78     }
     79     a : x+=ID<V> ;
     80     ID : 'a'..'z'+ ;
     81     WS : (' '|'\n') {$channel=HIDDEN;} ;
     82   END
     83 
     84 
     85   inline_grammar( <<-'END' )
     86     grammar TokenRoot;
     87     options {
     88         language=Ruby;
     89         output=AST;
     90     }
     91     @members {
     92       class V < ANTLR3::CommonTree
     93         def to_s
     94           return @token.text + "<V>"
     95         end
     96       end
     97     
     98     }
     99     a : ID<V>^ ;
    100     ID : 'a'..'z'+ ;
    101     WS : (' '|'\n') {$channel=HIDDEN;} ;
    102   END
    103 
    104 
    105   inline_grammar( <<-'END' )
    106     grammar TokenRootWithListLabel;
    107     options {
    108         language=Ruby;
    109         output=AST;
    110     }
    111     @members {
    112       class V < ANTLR3::CommonTree
    113         def to_s
    114           return @token.text + "<V>"
    115         end
    116       end
    117     
    118     }
    119     a : x+=ID<V>^ ;
    120     ID : 'a'..'z'+ ;
    121     WS : (' '|'\n') {$channel=HIDDEN;} ;
    122   END
    123 
    124 
    125   inline_grammar( <<-'END' )
    126     grammar FromString;
    127     options {
    128         language=Ruby;
    129         output=AST;
    130     }
    131     @members {
    132       class V < ANTLR3::CommonTree
    133         def to_s
    134           return @token.text + "<V>"
    135         end
    136       end
    137     
    138     }
    139     a : 'begin'<V> ;
    140     ID : 'a'..'z'+ ;
    141     WS : (' '|'\n') {$channel=HIDDEN;} ;
    142   END
    143 
    144 
    145   inline_grammar( <<-'END' )
    146     grammar StringRoot;
    147     options {
    148         language=Ruby;
    149         output=AST;
    150     }
    151     @members {
    152       class V < ANTLR3::CommonTree
    153         def to_s
    154           return @token.text + "<V>"
    155         end
    156       end
    157     
    158     }
    159     a : 'begin'<V>^ ;
    160     ID : 'a'..'z'+ ;
    161     WS : (' '|'\n') {$channel=HIDDEN;} ;
    162   END
    163 
    164 
    165   inline_grammar( <<-'END' )
    166     grammar RewriteToken;
    167     options {
    168         language=Ruby;
    169         output=AST;
    170     }
    171     @members {
    172       class V < ANTLR3::CommonTree
    173         def to_s
    174           return @token.text + "<V>"
    175         end
    176       end
    177     
    178     }
    179     a : ID -> ID<V> ;
    180     ID : 'a'..'z'+ ;
    181     WS : (' '|'\n') {$channel=HIDDEN;} ;
    182   END
    183 
    184 
    185   inline_grammar( <<-'END' )
    186     grammar RewriteTokenWithArgs;
    187     options {
    188         language=Ruby;
    189         output=AST;
    190     }
    191     @members {
    192       class V < ANTLR3::CommonTree
    193         def initialize(*args)
    194           case args.length
    195           when 4
    196             ttype, @x, @y, @z = args
    197             token = ANTLR3::CommonToken.new(ttype, nil, '')
    198           when 3
    199             ttype, token, @x = args
    200             @y = @z = 0
    201           else raise ArgumentError, "invalid number of arguments: #{args.length} for 3-4"
    202           end
    203           super(token)
    204         end
    205         
    206         def to_s
    207           (@token.text.to_s rescue '') << "<V>;\%d\%d\%d" \% [@x, @y, @z]
    208         end
    209       end
    210     
    211     }
    212     a : ID -> ID<V>[42,19,30] ID<V>[$ID,99];
    213     ID : 'a'..'z'+ ;
    214     WS : (' '|'\n') {$channel=HIDDEN;} ;
    215   END
    216 
    217 
    218   inline_grammar( <<-'END' )
    219     grammar RewriteTokenRoot;
    220     options {
    221         language=Ruby;
    222         output=AST;
    223     }
    224     @members {
    225       class V < ANTLR3::CommonTree
    226         def to_s
    227           return @token.text + "<V>"
    228         end
    229       end
    230     
    231     }
    232     a : ID INT -> ^(ID<V> INT) ;
    233     ID : 'a'..'z'+ ;
    234     INT : '0'..'9'+ ;
    235     WS : (' '|'\n') {$channel=HIDDEN;} ;
    236   END
    237 
    238 
    239   inline_grammar( <<-'END' )
    240     grammar RewriteString;
    241     options {
    242         language=Ruby;
    243         output=AST;
    244     }
    245     @members {
    246       class V < ANTLR3::CommonTree
    247         def to_s
    248           return @token.text + "<V>"
    249         end
    250       end
    251     
    252     }
    253     a : 'begin' -> 'begin'<V> ;
    254     ID : 'a'..'z'+ ;
    255     WS : (' '|'\n') {$channel=HIDDEN;} ;
    256   END
    257 
    258 
    259   inline_grammar( <<-'END' )
    260     grammar RewriteStringRoot;
    261     options {
    262         language=Ruby;
    263         output=AST;
    264     }
    265     @members {
    266       class V < ANTLR3::CommonTree
    267         def to_s
    268           return @token.text + "<V>"
    269         end
    270       end
    271     
    272     }
    273     a : 'begin' INT -> ^('begin'<V> INT) ;
    274     ID : 'a'..'z'+ ;
    275     INT : '0'..'9'+ ;
    276     WS : (' '|'\n') {$channel=HIDDEN;} ;
    277   END
    278 
    279 
    280   inline_grammar( <<-'END' )
    281     grammar RewriteRuleResults;
    282     options {
    283         language=Ruby;
    284         output=AST;
    285     }
    286     tokens {LIST;}
    287     @members {
    288       class V < ANTLR3::CommonTree
    289         def to_s
    290           return @token.text + "<V>"
    291         end
    292       end
    293       class W < ANTLR3::CommonTree
    294         def initialize(tok, text)
    295           tok.text = text
    296           super(tok)
    297         end
    298         def to_s
    299           return @token.text + "<W>"
    300         end
    301       end
    302     
    303     }
    304     a : id (',' id)* -> ^(LIST<W>["LIST"] id+);
    305     id : ID -> ID<V>;
    306     ID : 'a'..'z'+ ;
    307     WS : (' '|'\n') {$channel=HIDDEN;} ;
    308   END
    309 
    310 
    311   inline_grammar( <<-'END' )
    312     grammar CopySemanticsWithHetero;
    313     options {
    314         language=Ruby;
    315         output=AST;
    316     }
    317     @members {
    318       class V < ANTLR3::CommonTree
    319         def dup_node
    320           return V.new(self)
    321         end
    322         def to_s
    323           return @token.text + "<V>"
    324         end
    325       end
    326     }
    327     a : type ID (',' ID)* ';' -> ^(type ID)+;
    328     type : 'int'<V> ;
    329     ID : 'a'..'z'+ ;
    330     INT : '0'..'9'+;
    331     WS : (' '|'\\n') {$channel=HIDDEN;} ;
    332   END
    333 
    334 
    335   inline_grammar( <<-'END' )
    336     grammar TreeParserRewriteFlatList;
    337     options {
    338         language=Ruby;
    339         output=AST;
    340     }
    341     a : ID INT;
    342     ID : 'a'..'z'+ ;
    343     INT : '0'..'9'+;
    344     WS : (' '|'\n') {$channel=HIDDEN;} ;
    345   END
    346 
    347 
    348   inline_grammar( <<-'END' )
    349     tree grammar TreeParserRewriteFlatListWalker;
    350     options {
    351         language=Ruby;
    352         output=AST;
    353         ASTLabelType=CommonTree;
    354         tokenVocab=TreeParserRewriteFlatList;
    355     }
    356     @members {
    357       class V < ANTLR3::CommonTree
    358         def to_s
    359           return @token.text + "<V>"
    360         end
    361       end
    362       class W < ANTLR3::CommonTree
    363         def to_s
    364           return @token.text + "<W>"
    365         end
    366       end
    367     }
    368     a : ID INT -> INT<V> ID<W>
    369       ;
    370   END
    371 
    372 
    373   inline_grammar( <<-'END' )
    374     grammar TreeParserRewriteTree;
    375     options {
    376         language=Ruby;
    377         output=AST;
    378     }
    379     a : ID INT;
    380     ID : 'a'..'z'+ ;
    381     INT : '0'..'9'+;
    382     WS : (' '|'\n') {$channel=HIDDEN;} ;
    383   END
    384 
    385 
    386   inline_grammar( <<-'END' )
    387     tree grammar TreeParserRewriteTreeWalker;
    388     options {
    389         language=Ruby;
    390         output=AST;
    391         ASTLabelType=CommonTree;
    392         tokenVocab=TreeParserRewriteTree;
    393     }
    394     @members {
    395       class V < ANTLR3::CommonTree
    396         def to_s
    397           return @token.text + "<V>"
    398         end
    399       end
    400     
    401       class W < ANTLR3::CommonTree
    402         def to_s
    403           return @token.text + "<W>"
    404         end
    405       end      
    406     }
    407     a : ID INT -> ^(INT<V> ID<W>)
    408       ;
    409   END
    410 
    411 
    412   inline_grammar( <<-'END' )
    413     grammar TreeParserRewriteImaginary;
    414     options {
    415         language=Ruby;
    416         output=AST;
    417     }
    418     a : ID ;
    419     ID : 'a'..'z'+ ;
    420     INT : '0'..'9'+;
    421     WS : (' '|'\n') {$channel=HIDDEN;} ;
    422   END
    423 
    424 
    425   inline_grammar( <<-'END' )
    426     tree grammar TreeParserRewriteImaginaryWalker;
    427     options {
    428         language=Ruby;
    429         output=AST;
    430         ASTLabelType=CommonTree;
    431         tokenVocab=TreeParserRewriteImaginary;
    432     }
    433     tokens { ROOT; }
    434     @members {
    435       class V < ANTLR3::CommonTree
    436         def to_s
    437           return @token.name + "<V>"
    438         end
    439       end
    440     }
    441     a : ID -> ROOT<V> ID
    442       ;
    443   END
    444 
    445 
    446   inline_grammar( <<-'END' )
    447     grammar TreeParserRewriteImaginaryWithArgs;
    448     options {
    449         language=Ruby;
    450         output=AST;
    451     }
    452     a : ID ;
    453     ID : 'a'..'z'+ ;
    454     INT : '0'..'9'+;
    455     WS : (' '|'\n') {$channel=HIDDEN;} ;
    456   END
    457 
    458 
    459   inline_grammar( <<-'END' )
    460     tree grammar TreeParserRewriteImaginaryWithArgsWalker;
    461     options {
    462         language=Ruby;
    463         output=AST;
    464         ASTLabelType=CommonTree;
    465         tokenVocab=TreeParserRewriteImaginaryWithArgs;
    466     }
    467     tokens { ROOT; }
    468     @members {
    469       class V < ANTLR3::CommonTree
    470         def initialize(token_type, x)
    471           super(token_type)
    472           @x = x
    473         end
    474         def to_s
    475           return @token.name + "<V>;#@x"
    476         end
    477       end
    478     }
    479     a : ID -> ROOT<V>[42] ID
    480       ;
    481   END
    482 
    483 
    484   inline_grammar( <<-'END' )
    485     grammar TreeParserRewriteImaginaryRoot;
    486     options {
    487         language=Ruby;
    488         output=AST;
    489     }
    490     a : ID ;
    491     ID : 'a'..'z'+ ;
    492     INT : '0'..'9'+;
    493     WS : (' '|'\n') {$channel=HIDDEN;} ;
    494   END
    495 
    496 
    497   inline_grammar( <<-'END' )
    498     tree grammar TreeParserRewriteImaginaryRootWalker;
    499     options {
    500         language=Ruby;
    501         output=AST;
    502         ASTLabelType=CommonTree;
    503         tokenVocab=TreeParserRewriteImaginaryRoot;
    504     }
    505     tokens { ROOT; }
    506     @members {
    507       class V < ANTLR3::CommonTree
    508         def to_s
    509           return @token.name + "<V>"
    510         end
    511       end
    512     }
    513     a : ID -> ^(ROOT<V> ID)
    514       ;
    515   END
    516 
    517 
    518   inline_grammar( <<-'END' )
    519     grammar TreeParserRewriteImaginaryFromReal;
    520     options {
    521         language=Ruby;
    522         output=AST;
    523     }
    524     a : ID ;
    525     ID : 'a'..'z'+ ;
    526     INT : '0'..'9'+;
    527     WS : (' '|'\n') {$channel=HIDDEN;} ;
    528   END
    529 
    530 
    531   inline_grammar( <<-'END' )
    532     tree grammar TreeParserRewriteImaginaryFromRealWalker;
    533     options {
    534         language=Ruby;
    535         output=AST;
    536         ASTLabelType=CommonTree;
    537         tokenVocab=TreeParserRewriteImaginaryFromReal;
    538     }
    539     tokens { ROOT; }
    540     @members {
    541       class V < ANTLR3::CommonTree
    542         def initialize(token, tree = nil)
    543           if tree.nil? then super(token)
    544           else
    545             super(tree)
    546             @token = TokenData::Token.from_token(@token)
    547             @token.type = token.type
    548           end
    549         end
    550         def to_s
    551           return @token.name + "<V>@" + @token.line.to_s
    552         end
    553       end
    554     }
    555     a : ID -> ROOT<V>[$ID]
    556       ;
    557   END
    558 
    559 
    560   inline_grammar( <<-'END' )
    561     grammar TreeParserAutoHeteroAST;
    562     options {
    563         language=Ruby;
    564         output=AST;
    565     }
    566     a : ID ';' ;
    567     ID : 'a'..'z'+ ;
    568     INT : '0'..'9'+;
    569     WS : (' '|'\n') {$channel=HIDDEN;} ;
    570   END
    571 
    572 
    573   inline_grammar( <<-'END' )
    574     tree grammar TreeParserAutoHeteroASTWalker;
    575     options {
    576         language=Ruby;
    577         output=AST;
    578         ASTLabelType=CommonTree;
    579         tokenVocab=TreeParserAutoHeteroAST;
    580     }
    581     tokens { ROOT; }
    582     @members {
    583       class V < ANTLR3::CommonTree
    584         def to_s
    585           return @token.text + "<V>"
    586         end
    587       end
    588     }
    589     
    590     a : ID<V> ';'<V>;
    591   END
    592 
    593   def parse( grammar_name, grammar_rule, input )
    594     grammar_module = self.class.const_get( grammar_name.to_s )
    595     lexer  = grammar_module::Lexer.new( input )
    596     tokens = ANTLR3::CommonTokenStream.new( lexer )
    597     parser = grammar_module::Parser.new( tokens )
    598     r = parser.send( grammar_rule )
    599     
    600     return( r.tree.inspect rescue '' )
    601   end
    602   
    603   def tree_parse( grammar_name, grammar_rule, tree_grammar_rule, input )
    604     grammar_module = self.class.const_get( grammar_name.to_s )
    605     tree_grammar_module = self.class.const_get( grammar_name.to_s + 'Walker' )
    606     
    607     lexer  = grammar_module::Lexer.new( input )
    608     tokens = ANTLR3::CommonTokenStream.new( lexer )
    609     parser = grammar_module::Parser.new( tokens )
    610     r = parser.send( grammar_rule )
    611     
    612     nodes = ANTLR3::CommonTreeNodeStream.new( r.tree )
    613     nodes.token_stream = tokens
    614     tree_parser = tree_grammar_module::TreeParser.new( nodes )
    615     r = tree_parser.send( tree_grammar_rule )
    616     
    617     return( r.tree.inspect rescue '' )
    618   end
    619 
    620   example "v token" do
    621     result = parse( :VToken, :a, 'a' )
    622     result.should == 'a<V>'
    623   end
    624 
    625 
    626   example "token with qualified type" do
    627     result = parse( :TokenWithQualifiedType, :a, 'a' )
    628     result.should == 'a<V>'
    629   end
    630 
    631 
    632   example "token with label" do
    633     result = parse( :TokenWithLabel, :a, 'a' )
    634     result.should == 'a<V>'
    635   end
    636 
    637 
    638   example "token with list label" do
    639     result = parse( :TokenWithListLabel, :a, 'a' )
    640     result.should == 'a<V>'
    641   end
    642 
    643 
    644   example "token root" do
    645     result = parse( :TokenRoot, :a, 'a' )
    646     result.should == 'a<V>'
    647   end
    648 
    649 
    650   example "token root with list label" do
    651     result = parse( :TokenRootWithListLabel, :a, 'a' )
    652     result.should == 'a<V>'
    653   end
    654 
    655 
    656   example "string" do
    657     result = parse( :FromString, :a, 'begin' )
    658     result.should == 'begin<V>'
    659   end
    660 
    661 
    662   example "string root" do
    663     result = parse( :StringRoot, :a, 'begin' )
    664     result.should == 'begin<V>'
    665   end
    666 
    667 
    668   example "rewrite token" do
    669     result = parse( :RewriteToken, :a, 'a' )
    670     result.should == 'a<V>'
    671   end
    672 
    673 
    674   example "rewrite token with args" do
    675     result = parse( :RewriteTokenWithArgs, :a, 'a' )
    676     result.should == '<V>;421930 a<V>;9900'
    677   end
    678 
    679 
    680   example "rewrite token root" do
    681     result = parse( :RewriteTokenRoot, :a, 'a 2' )
    682     result.should == '(a<V> 2)'
    683   end
    684 
    685 
    686   example "rewrite string" do
    687     result = parse( :RewriteString, :a, 'begin' )
    688     result.should == 'begin<V>'
    689   end
    690 
    691 
    692   example "rewrite string root" do
    693     result = parse( :RewriteStringRoot, :a, 'begin 2' )
    694     result.should == '(begin<V> 2)'
    695   end
    696 
    697 
    698   example "rewrite rule results" do
    699     result = parse( :RewriteRuleResults, :a, 'a,b,c' )
    700     result.should == '(LIST<W> a<V> b<V> c<V>)'
    701   end
    702 
    703 
    704   example "copy semantics with hetero" do
    705     result = parse( :CopySemanticsWithHetero, :a, 'int a, b, c;' )
    706     result.should == '(int<V> a) (int<V> b) (int<V> c)'
    707   end
    708 
    709 
    710   example "tree parser rewrite flat list" do
    711     result = tree_parse( :TreeParserRewriteFlatList, :a, :a, 'abc 34' )
    712     result.should == '34<V> abc<W>'
    713   end
    714 
    715 
    716   example "tree parser rewrite tree" do
    717     result = tree_parse( :TreeParserRewriteTree, :a, :a, 'abc 34' )
    718     result.should == '(34<V> abc<W>)'
    719   end
    720 
    721 
    722   example "tree parser rewrite imaginary" do
    723     result = tree_parse( :TreeParserRewriteImaginary, :a, :a, 'abc' )
    724     result.should == 'ROOT<V> abc'
    725   end
    726 
    727 
    728   example "tree parser rewrite imaginary with args" do
    729     result = tree_parse( :TreeParserRewriteImaginaryWithArgs, :a, :a, 'abc' )
    730     result.should == 'ROOT<V>;42 abc'
    731   end
    732 
    733 
    734   example "tree parser rewrite imaginary root" do
    735     result = tree_parse( :TreeParserRewriteImaginaryRoot, :a, :a, 'abc' )
    736     result.should == '(ROOT<V> abc)'
    737   end
    738 
    739 
    740   example "tree parser rewrite imaginary from real" do
    741     result = tree_parse( :TreeParserRewriteImaginaryFromReal, :a, :a, 'abc' )
    742     result.should == 'ROOT<V>@1'
    743   end
    744 
    745 
    746   example "tree parser auto hetero ast" do
    747     result = tree_parse( :TreeParserAutoHeteroAST, :a, :a, 'abc;' )
    748     result.should == 'abc<V> ;<V>'
    749   end
    750 
    751 end
    752