Home | History | Annotate | Download | only in ast-output
      1 #!/usr/bin/ruby
      2 # encoding: utf-8
      3 
      4 require 'antlr3/test/functional'
      5 
      6 class 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 
   1326 end
   1327