1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3/test/functional'
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TestRewritingWhileParsing < ANTLR3::Test::Functional
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  inline_grammar( <<-'END' )
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    grammar TokenRewrites;
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    options { language = Ruby; }
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    program
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @after {
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @input.insert_before($start,"public class Wrapper {\n")
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      @input.insert_after($stop, "\n}\n")
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   method+
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    method
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   m='method' ID '(' ')' body
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {@input.replace($m, "public void");}
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ; 
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    body
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    scope {
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        decls
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    @init {
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        $body::decls = []
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   lcurly='{' stat* '}'
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            $body::decls.uniq!
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for it in $body::decls
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver              @input.insert_after($lcurly, "\nint "+it+";")
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            end
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stat:   ID '=' expr ';' {$body::decls << $ID.text.to_s}
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    expr:   mul ('+' mul)* 
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    mul :   atom ('*' atom)*
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    atom:   ID
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        |   INT
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ID  :   ('a'..'z'|'A'..'Z')+ ;
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    INT :   ('0'..'9')+ ;
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    WS  :   (' '|'\t'|'\n')+ {$channel=HIDDEN;}
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  END
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  example 'using a TokenRewriteStream to rewrite input text while parsing' do
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    input = <<-END.fixed_indent( 0 )
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      method foo() {
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        i = 3;
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        k = i;
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        i = k*4;
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      }
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      method bar() {
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        j = i*2;
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      }
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    END
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    expected_output = <<-END.fixed_indent( 0 ).strip!
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      public class Wrapper {
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      public void foo() {
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      int k;
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      int i;
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        i = 3;
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        k = i;
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        i = k*4;
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      }
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      public void bar() {
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      int j;
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        j = i*2;
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      }
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      }
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    END
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    lexer = TokenRewrites::Lexer.new( input )
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tokens = ANTLR3::TokenRewriteStream.new( lexer )
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser = TokenRewrites::Parser.new( tokens )
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.program
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tokens.render.strip.should == expected_output
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
100