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