profile-mode.rb revision 324c4644fee44b9898524c09511bd33c3f12e2df
1#!/usr/bin/ruby
2# encoding: utf-8
3
4require 'antlr3/test/functional'
5
6class 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  
165end
166