1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver# encoding: utf-8
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3/test/functional'
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass TestProfileMode < ANTLR3::Test::Functional
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  compile_options :profile => true
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  inline_grammar( <<-'END' )
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    grammar SimpleC;
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    options { language = Ruby; }
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    program
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   declaration+
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** In this rule, the functionHeader left prefix on the last two
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  alternatives is not LL(k) for a fixed k.  However, it is
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  LL(*).  The LL(*) algorithm simply scans ahead until it sees
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  either the ';' or the '{' of the block and then it picks
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  the appropriate alternative.  Lookhead can be arbitrarily
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  long in theory, but is <=10 in most cases.  Works great.
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  Use ANTLRWorks to see the lookahead use (step by Location)
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  and look for blue tokens in the input window pane. :)
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    declaration
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   variable
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        |   functionHeader ';'
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        |   functionHeader block
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    variable
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   type declarator ';'
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    declarator
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   ID 
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    functionHeader
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   type ID '(' ( formalParameter ( ',' formalParameter )* )? ')'
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    formalParameter
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   type declarator        
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    type
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   'int'   
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        |   'char'  
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        |   'void'
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        |   ID        
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    block
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   '{'
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                variable*
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stat*
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            '}'
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    stat: forStat
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | expr ';'      
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | block
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | assignStat ';'
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | ';'
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    forStat
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   'for' '(' assignStat ';' expr ';' assignStat ')' block        
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    assignStat
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   ID '=' expr        
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    expr:   condExpr
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    condExpr
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   aexpr ( ('==' | '<') aexpr )?
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    aexpr
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        :   atom ( '+' atom )*
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    atom
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        : ID      
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | INT      
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        | '(' expr ')'
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ; 
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    INT :	('0'..'9')+
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    WS  :   (   ' '
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            |   '\t'
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            |   '\r'
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            |   '\n'
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            )+
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            { $channel=HIDDEN; }
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ;
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  END
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  example 'profile mode output' do
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    input = <<-END.fixed_indent( 0 )
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      char c;
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      int x;
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      void bar(int x);
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      int foo(int y, char d) {
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        int i;
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for (i=0; i<3; i=i+1) {
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          x=3;
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver          y=5;
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver      }
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    END
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    lexer = SimpleC::Lexer.new( input )
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    tokens = ANTLR3::CommonTokenStream.new( lexer )
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser = SimpleC::Parser.new( tokens )
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    parser.program
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data = parser.profile
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.rule_invocations.should == 60
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.guessing_rule_invocations.should == 0
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.rule_invocation_depth.should == 12
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.fixed_decisions.should == 40
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    fixed_data = profile_data.fixed_looks
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    fixed_data.min.should == 1
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    fixed_data.max.should == 2
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    fixed_data.average.should == 1.075
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    fixed_data.standard_deviation.should == 0.26674678283691855
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.cyclic_decisions.should == 4
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    cyclic_data = profile_data.cyclic_looks
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    cyclic_data.min.should == 3
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    cyclic_data.max.should == 10
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    cyclic_data.average.should == 5.75
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    cyclic_data.standard_deviation.should == 3.4034296427770228
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.syntactic_predicates.should == 0
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.memoization_cache_entries.should == 0
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.memoization_cache_hits.should == 0
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.memoization_cache_misses.should == 0
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.semantic_predicates.should == 0
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.tokens.should == 77
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.hidden_tokens.should == 24
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.characters_matched.should == 118
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.hidden_characters_matched.should == 40
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    profile_data.reported_errors.should == 0
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  end
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver  
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend
166