1#!/usr/bin/ruby
2# encoding: utf-8
3
4require 'antlr3/test/functional'
5
6class TestRewritingWhileParsing < ANTLR3::Test::Functional
7
8  inline_grammar( <<-'END' )
9    grammar TokenRewrites;
10    options { language = Ruby; }
11    
12    program
13    @after {
14      @input.insert_before($start,"public class Wrapper {\n")
15      @input.insert_after($stop, "\n}\n")
16    }
17        :   method+
18        ;
19    
20    method
21        :   m='method' ID '(' ')' body
22            {@input.replace($m, "public void");}
23        ; 
24    
25    body
26    scope {
27        decls
28    }
29    @init {
30        $body::decls = []
31    }
32        :   lcurly='{' stat* '}'
33            {
34            $body::decls.uniq!
35            for it in $body::decls
36              @input.insert_after($lcurly, "\nint "+it+";")
37            end
38            }
39        ;
40    
41    stat:   ID '=' expr ';' {$body::decls << $ID.text.to_s}
42        ;
43    
44    expr:   mul ('+' mul)* 
45        ;
46    
47    mul :   atom ('*' atom)*
48        ;
49    
50    atom:   ID
51        |   INT
52        ;
53    
54    ID  :   ('a'..'z'|'A'..'Z')+ ;
55    
56    INT :   ('0'..'9')+ ;
57    
58    WS  :   (' '|'\t'|'\n')+ {$channel=HIDDEN;}
59        ;
60  END
61
62  example 'using a TokenRewriteStream to rewrite input text while parsing' do
63    input = <<-END.fixed_indent( 0 )
64      method foo() {
65        i = 3;
66        k = i;
67        i = k*4;
68      }
69      
70      method bar() {
71        j = i*2;
72      }
73    END
74    expected_output = <<-END.fixed_indent( 0 ).strip!
75      public class Wrapper {
76      public void foo() {
77      int k;
78      int i;
79        i = 3;
80        k = i;
81        i = k*4;
82      }
83      
84      public void bar() {
85      int j;
86        j = i*2;
87      }
88      }
89    END
90    
91    lexer = TokenRewrites::Lexer.new( input )
92    tokens = ANTLR3::TokenRewriteStream.new( lexer )
93    parser = TokenRewrites::Parser.new( tokens )
94    parser.program
95    
96    tokens.render.strip.should == expected_output
97  end
98
99end
100