1#!/usr/bin/ruby 2# encoding: utf-8 3 4require 'antlr3/test/functional' 5 6class TestActions1 < ANTLR3::Test::Functional 7 inline_grammar( <<-'END' ) 8 grammar ParserActions; 9 options { language = Ruby; } 10 11 declaration returns [name] 12 : functionHeader ';' 13 { $name = $functionHeader.name } 14 ; 15 16 functionHeader returns [name] 17 : type id=ID 18 { $name = $id.text } 19 ; 20 21 type 22 : 'int' 23 | 'char' 24 | 'void' 25 ; 26 27 ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* 28 ; 29 30 WS : ( ' ' 31 | '\t' 32 | '\r' 33 | '\n' 34 )+ 35 {$channel=HIDDEN} 36 ; 37 END 38 39 example "parser action execution" do 40 lexer = ParserActions::Lexer.new "int foo;" 41 parser = ParserActions::Parser.new lexer 42 43 parser.declaration.should == 'foo' 44 end 45 46end 47 48 49class TestActions2 < ANTLR3::Test::Functional 50 51 inline_grammar( <<-'END' ) 52 grammar AllKindsOfActions; 53 options { language = Ruby; } 54 55 @parser::members { 56 include ANTLR3::Test::CaptureOutput 57 } 58 59 @lexer::members { 60 include ANTLR3::Test::CaptureOutput 61 } 62 @lexer::init { @foobar = 'attribute' } 63 64 prog 65 @init { say('init') } 66 @after { say('after') } 67 : IDENTIFIER EOF 68 ; 69 catch [ RecognitionError => exc ] { 70 say('catch') 71 raise 72 } 73 finally { say('finally') } 74 75 76 IDENTIFIER 77 : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')* 78 { 79 # a comment 80 say('action') 81 say('\%p \%p \%p \%p \%p \%p \%p \%p' \% [$text, $type, $line, $pos, $index, $channel, $start, $stop]) 82 say(@foobar) 83 } 84 ; 85 86 WS: (' ' | '\n')+; 87 END 88 89 90 example "execution of special named actions" do 91 lexer = AllKindsOfActions::Lexer.new( "foobar _Ab98 \n A12sdf" ) 92 parser = AllKindsOfActions::Parser.new lexer 93 parser.prog 94 95 parser.output.should == <<-END.fixed_indent( 0 ) 96 init 97 after 98 finally 99 END 100 101 lexer.output.should == <<-END.fixed_indent( 0 ) 102 action 103 "foobar" 4 1 0 -1 :default 0 5 104 attribute 105 action 106 "_Ab98" 4 1 7 -1 :default 7 11 107 attribute 108 action 109 "A12sdf" 4 2 1 -1 :default 15 20 110 attribute 111 END 112 end 113end 114 115class TestFinally < ANTLR3::Test::Functional 116 117 inline_grammar( <<-'END' ) 118 grammar Finally; 119 120 options { 121 language = Ruby; 122 } 123 124 prog returns [events] 125 @init {events = []} 126 @after {events << 'after'} 127 : ID {raise RuntimeError} 128 ; 129 catch [RuntimeError] {events << 'catch'} 130 finally { events << 'finally'} 131 132 ID : ('a'..'z')+ 133 ; 134 135 WS : (' '|'\n'|'\r')+ {$channel=HIDDEN} 136 ; 137 END 138 139 140 example "order of catch and ensure clauses" do 141 lexer = Finally::Lexer.new( 'foobar' ) 142 parser = Finally::Parser.new lexer 143 parser.prog.should == %w(catch finally) 144 end 145 146end 147 148 149class TestActionScopes < ANTLR3::Test::Functional 150 151 inline_grammar( <<-'END' ) 152 grammar SpecialActionScopes; 153 options { language=Ruby; } 154 155 @all::header { 156 \$all_header_files ||= [] 157 \$all_header_files << File.basename( __FILE__ ) 158 } 159 160 @all::footer { 161 \$all_footer_files ||= [] 162 \$all_footer_files << File.basename( __FILE__ ) 163 } 164 165 @header { 166 \$header_location = __LINE__ 167 \$header_context = self 168 } 169 170 @footer { 171 \$footer_location = __LINE__ 172 \$footer_context = self 173 } 174 175 @module::head { 176 \$module_head_location = __LINE__ 177 \$module_head_context = self 178 179 class << self 180 attr_accessor :head_var 181 end 182 } 183 184 @module::foot { 185 \$module_foot_location = __LINE__ 186 \$module_foot_context = self 187 188 FOOT_CONST = 1 189 } 190 191 @token::scheme { 192 \$token_scheme_location = __LINE__ 193 \$token_scheme_context = self 194 195 SCHEME_CONST = 1 196 } 197 198 @token::members { 199 \$token_members_location = __LINE__ 200 \$token_members_context = self 201 202 def value 203 text.to_i 204 end 205 } 206 207 @members { 208 \$members_location = __LINE__ 209 } 210 211 nums returns [ds]: digs+=DIGIT+ 212 { $ds = $digs.map { |t| t.value } }; 213 214 DIGIT: ('0'..'9')+; 215 WS: (' ' | '\t' | '\n' | '\r' | '\f')+ { $channel=HIDDEN; }; 216 END 217 218 example 'verifying action scope behavior' do 219 lexer = SpecialActionScopes::Lexer.new( "10 20 30 40 50" ) 220 parser = SpecialActionScopes::Parser.new lexer 221 parser.nums.should == [ 10, 20, 30, 40, 50 ] 222 end 223 224 example 'special action scope locations' do 225 $all_header_files.should include "SpecialActionScopesLexer.rb" 226 $all_header_files.should include "SpecialActionScopesParser.rb" 227 $all_footer_files.should include "SpecialActionScopesLexer.rb" 228 $all_footer_files.should include "SpecialActionScopesParser.rb" 229 230 $header_location.should be < $module_head_location 231 $module_head_location.should be < $token_scheme_location 232 $token_scheme_location.should be < $token_members_location 233 $token_members_location.should be < $members_location 234 $members_location.should be < $module_foot_location 235 $module_foot_location.should be < $footer_location 236 end 237 238end 239