Home | History | Annotate | Download | only in debugging
      1 #!/usr/bin/ruby
      2 # encoding: utf-8
      3 
      4 require 'antlr3/test/functional'
      5 
      6 class TestProfileMode < ANTLR3::Test::Functional
      7   compile_options :profile => true
      8   
      9   inline_grammar( <<-'END' )
     10     grammar SimpleC;
     11     
     12     options { language = Ruby; }
     13     
     14     program
     15         :   declaration+
     16         ;
     17     
     18     /** In this rule, the functionHeader left prefix on the last two
     19      *  alternatives is not LL(k) for a fixed k.  However, it is
     20      *  LL(*).  The LL(*) algorithm simply scans ahead until it sees
     21      *  either the ';' or the '{' of the block and then it picks
     22      *  the appropriate alternative.  Lookhead can be arbitrarily
     23      *  long in theory, but is <=10 in most cases.  Works great.
     24      *  Use ANTLRWorks to see the lookahead use (step by Location)
     25      *  and look for blue tokens in the input window pane. :)
     26      */
     27     declaration
     28         :   variable
     29         |   functionHeader ';'
     30         |   functionHeader block
     31         ;
     32     
     33     variable
     34         :   type declarator ';'
     35         ;
     36     
     37     declarator
     38         :   ID 
     39         ;
     40     
     41     functionHeader
     42         :   type ID '(' ( formalParameter ( ',' formalParameter )* )? ')'
     43         ;
     44     
     45     formalParameter
     46         :   type declarator        
     47         ;
     48     
     49     type
     50         :   'int'   
     51         |   'char'  
     52         |   'void'
     53         |   ID        
     54         ;
     55     
     56     block
     57         :   '{'
     58                 variable*
     59                 stat*
     60             '}'
     61         ;
     62     
     63     stat: forStat
     64         | expr ';'      
     65         | block
     66         | assignStat ';'
     67         | ';'
     68         ;
     69     
     70     forStat
     71         :   'for' '(' assignStat ';' expr ';' assignStat ')' block        
     72         ;
     73     
     74     assignStat
     75         :   ID '=' expr        
     76         ;
     77     
     78     expr:   condExpr
     79         ;
     80     
     81     condExpr
     82         :   aexpr ( ('==' | '<') aexpr )?
     83         ;
     84     
     85     aexpr
     86         :   atom ( '+' atom )*
     87         ;
     88     
     89     atom
     90         : ID      
     91         | INT      
     92         | '(' expr ')'
     93         ; 
     94     
     95     ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
     96         ;
     97     
     98     INT :	('0'..'9')+
     99         ;
    100     
    101     WS  :   (   ' '
    102             |   '\t'
    103             |   '\r'
    104             |   '\n'
    105             )+
    106             { $channel=HIDDEN; }
    107         ;
    108   END
    109   
    110   example 'profile mode output' do
    111     input = <<-END.fixed_indent( 0 )
    112       char c;
    113       int x;
    114       
    115       void bar(int x);
    116       
    117       int foo(int y, char d) {
    118         int i;
    119         for (i=0; i<3; i=i+1) {
    120           x=3;
    121           y=5;
    122         }
    123       }
    124     END
    125     
    126     lexer = SimpleC::Lexer.new( input )
    127     tokens = ANTLR3::CommonTokenStream.new( lexer )
    128     parser = SimpleC::Parser.new( tokens )
    129     parser.program
    130     
    131     profile_data = parser.profile
    132     profile_data.rule_invocations.should == 60
    133     profile_data.guessing_rule_invocations.should == 0
    134     profile_data.rule_invocation_depth.should == 12
    135     
    136     profile_data.fixed_decisions.should == 40
    137     fixed_data = profile_data.fixed_looks
    138     fixed_data.min.should == 1
    139     fixed_data.max.should == 2
    140     fixed_data.average.should == 1.075
    141     fixed_data.standard_deviation.should == 0.26674678283691855
    142     
    143     profile_data.cyclic_decisions.should == 4
    144     cyclic_data = profile_data.cyclic_looks
    145     cyclic_data.min.should == 3
    146     cyclic_data.max.should == 10
    147     cyclic_data.average.should == 5.75
    148     cyclic_data.standard_deviation.should == 3.4034296427770228
    149     
    150     profile_data.syntactic_predicates.should == 0
    151     
    152     profile_data.memoization_cache_entries.should == 0
    153     profile_data.memoization_cache_hits.should == 0
    154     profile_data.memoization_cache_misses.should == 0
    155     
    156     profile_data.semantic_predicates.should == 0
    157     profile_data.tokens.should == 77
    158     profile_data.hidden_tokens.should == 24
    159     profile_data.characters_matched.should == 118
    160     profile_data.hidden_characters_matched.should == 40
    161     profile_data.reported_errors.should == 0
    162   end
    163   
    164   
    165 end
    166