1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3/test/functional' 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TestTemplateOutput < ANTLR3::Test::Functional 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def parse( grammar, input, options = nil ) 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @grammar = inline_grammar( grammar ) 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver compile_and_load( @grammar ) 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar_module = self.class.const_get( @grammar.name ) 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parser_options = {} 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if options 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rule = options.fetch( :rule ) { grammar_module::Parser.default_rule } 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver group = options[ :templates ] and parser_options[ :templates ] = group 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rule = grammar_module::Parser.default_rule 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @lexer = grammar_module::Lexer.new( input ) 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parser = grammar_module::Parser.new( @lexer, parser_options ) 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver out = @parser.send( rule ).template 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( out ? out.to_s : out ) 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def parse_templates( source ) 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3::Template::Group.parse( source.fixed_indent( 0 ) ) 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver example 'inline templates' do 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = parse( <<-'END', "abc 34" ) 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar InlineTemplates; 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language = Ruby; 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output = template; 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a : ID INT 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> template(id={$ID.text}, int={$INT.text}) 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "id=<%= @id %>, int=<%= @int %>" 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ID : 'a'..'z'+; 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver INT : '0'..'9'+; 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WS : (' '|'\n') {$channel=HIDDEN;} ; 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text.should == "id=abc, int=34" 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver example 'external template' do 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver templates = ANTLR3::Template::Group.new do 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver define_template( :expr, <<-'END'.strip ) 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver [<%= @args.join( @op.to_s ) %>] 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = parse( <<-'END', 'a + b', :templates => templates ) 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar ExternalTemplate; 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language = Ruby; 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output = template; 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a : r+=arg OP r+=arg 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> expr( op={$OP.text}, args={$r} ) 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver arg: ID -> template(t={$ID.text}) "<%= @t %>"; 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ID : 'a'..'z'+; 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver OP: '+'; 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WS : (' '|'\n') {$channel=HIDDEN;} ; 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text.should == '[a+b]' 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver example "empty template" do 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = parse( <<-'END', 'abc 34' ) 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar EmptyTemplate; 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language=Ruby; 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output=template; 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a : ID INT 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ID : 'a'..'z'+; 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver INT : '0'..'9'+; 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WS : (' '|'\n') {$channel=HIDDEN;} ; 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text.should be_nil 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver example "list" do 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = parse( <<-'END', "abc def ghi" ) 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar List; 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language=Ruby; 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output=template; 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a: (r+=b)* EOF 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> template(r={$r}) "<%= @r.join(',') %>" 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver b: ID 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> template(t={$ID.text}) "<%= @t %>" 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ID : 'a'..'z'+; 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WS : (' '|'\n') {$channel=HIDDEN;} ; 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text.should == 'abc,def,ghi' 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver example 'action' do 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = parse( <<-'END', "abc" ) 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar Action; 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language=Ruby; 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output=template; 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a: ID 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> { create_template( "hello" ) } 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ID : 'a'..'z'+; 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WS : (' '|'\n') {$channel=HIDDEN;} ; 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text.should == 'hello' 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver example "template expression in action" do 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = parse( <<-'END', 'abc' ) 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar TemplateExpressionInAction; 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language=Ruby; 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output=template; 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a: ID 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { $st = %{"hello"} } 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ID : 'a'..'z'+; 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WS : (' '|'\n') {$channel=HIDDEN;} ; 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text.should == 'hello' 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver #example "template expression in action2" do 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # text = parse( <<-'END', 'abc' ) 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # grammar TemplateExpressionInAction2; 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # options { 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # language=Ruby; 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # output=template; 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # } 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # a: ID 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # { 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # res = %{"hello <%= @foo %>"} 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # %res.foo = "world"; 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # } 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # -> { res } 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # ; 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # ID : 'a'..'z'+; 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # WS : (' '|'\n') {$channel=HIDDEN;} ; 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # END 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver # text.should == 'hello world' 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver #end 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver example "indirect template constructor" do 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver templates = ANTLR3::Template::Group.new do 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver define_template( :expr, <<-'END'.strip ) 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver [<%= @args.join( @op.to_s ) %>] 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = parse( <<-'END', 'abc', :templates => templates ) 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar IndirectTemplateConstructor; 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language=Ruby; 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output=template; 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a: ID 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver $st = %({"expr"})(args={[1, 2, 3]}, op={"+"}) 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ID : 'a'..'z'+; 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WS : (' '|'\n') {$channel=HIDDEN;} ; 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text.should == '[1+2+3]' 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver example "predicates" do 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = parse( <<-'END', 'b 34' ) 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar Predicates; 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language=Ruby; 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output=template; 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a : ID INT 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> {$ID.text=='a'}? template(int={$INT.text}) 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "A: <%= @int %>" 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> {$ID.text=='b'}? template(int={$INT.text}) 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "B: <%= @int %>" 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> template(int={$INT.text}) 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "C: <%= @int %>" 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ID : 'a'..'z'+; 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver INT : '0'..'9'+; 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WS : (' '|'\n') {$channel=HIDDEN;} ; 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text.should == 'B: 34' 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver example "backtracking mode" do 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text = parse( <<-'END', 'abc 34' ) 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar BacktrackingMode; 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language=Ruby; 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output=template; 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver backtrack=true; 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a : (ID INT)=> ID INT 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> template(id={$ID.text}, int={$INT.text}) 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "id=<%= @id %>, int=<%= @int %>" 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ID : 'a'..'z'+; 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver INT : '0'..'9'+; 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WS : (' '|'\n') {$channel=HIDDEN;} ; 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver text.should == "id=abc, int=34" 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver example "rewrite" do 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input = <<-'END'.here_indent! 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | if ( foo ) { 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | b = /* bla */ 2; 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | return 1 /* foo */; 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | } 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | /* gnurz */ 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | return 12; 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver expected = <<-'END'.here_indent! 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | if ( foo ) { 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | b = /* bla */ 2; 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | return boom(1) /* foo */; 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | } 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | /* gnurz */ 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | return boom(12); 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parse( <<-'END', input ) 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar Rewrite; 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language=Ruby; 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output=template; 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rewrite=true; 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver prog: stat+; 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stat 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : 'if' '(' expr ')' stat 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | 'return' return_expr ';' 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | '{' stat* '}' 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | ID '=' expr ';' 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return_expr 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : expr 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> template(t={$text}) <<boom(<%= @t %>)>> 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver expr 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : ID 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | INT 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ID: 'a'..'z'+; 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver INT: '0'..'9'+; 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WS: (' '|'\n')+ {$channel=HIDDEN;} ; 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver COMMENT: '/*' (options {greedy=false;} : .)* '*/' {$channel = HIDDEN;} ; 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parser.input.render.should == expected 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver example "tree rewrite" do 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input = <<-'END'.here_indent! 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | if ( foo ) { 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | b = /* bla */ 2; 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | return 1 /* foo */; 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | } 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | /* gnurz */ 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | return 12; 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver expected = <<-'END'.here_indent! 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | if ( foo ) { 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | b = /* bla */ 2; 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | return boom(1) /* foo */; 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | } 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | /* gnurz */ 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | return boom(12); 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver compile_and_load( inline_grammar( <<-'END' ) ) 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar TreeRewrite; 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language=Ruby; 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output=AST; 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokens { 334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver BLOCK; 335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ASSIGN; 336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver prog: stat+; 339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stat 341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : IF '(' e=expr ')' s=stat 342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> ^(IF $e $s) 343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | RETURN expr ';' 344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> ^(RETURN expr) 345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | '{' stat* '}' 346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> ^(BLOCK stat*) 347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | ID '=' expr ';' 348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> ^(ASSIGN ID expr) 349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver expr 352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : ID 353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | INT 354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver IF: 'if'; 357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver RETURN: 'return'; 358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ID: 'a'..'z'+; 359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver INT: '0'..'9'+; 360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver WS: (' '|'\n')+ {$channel=HIDDEN;} ; 361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver COMMENT: '/*' (options {greedy=false;} : .)* '*/' {$channel = HIDDEN;} ; 362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver compile_and_load( inline_grammar( <<-'END' ) ) 365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree grammar TreeRewriteTG; 366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options { 367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver language=Ruby; 368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenVocab=TreeRewrite; 369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ASTLabelType=CommonTree; 370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver output=template; 371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver rewrite=true; 372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver prog: stat+; 375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stat 377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : ^(IF expr stat) 378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | ^(RETURN return_expr) 379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | ^(BLOCK stat*) 380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | ^(ASSIGN ID expr) 381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return_expr 384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : expr 385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver -> template(t={$text}) <<boom(<%= @t %>)>> 386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver expr 389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver : ID 390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | INT 391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ; 392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver lexer = TreeRewrite::Lexer.new( input ) 395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokens = ANTLR3::TokenRewriteStream.new( lexer ) 396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parser = TreeRewrite::Parser.new( tokens ) 397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree = parser.prog.tree 398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nodes = ANTLR3::AST::CommonTreeNodeStream.new( tree ) 399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nodes.token_stream = tokens 400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree_parser = TreeRewriteTG::TreeParser.new( nodes ) 401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tree_parser.prog 402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokens.render.should == expected 403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 405