Home | History | Annotate | Download | only in parser
      1 #!/usr/bin/ruby
      2 # encoding: utf-8
      3 
      4 require 'antlr3/test/functional'
      5 
      6 class 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   
     46 end
     47 
     48 
     49 class 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
    113 end
    114 
    115 class 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 
    146 end
    147 
    148 
    149 class 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 
    238 end
    239