blob: e4ff7630b8e81fcc03da7ec466977cd9173aad4e [file] [log] [blame]
#!/usr/bin/ruby
# encoding: utf-8
require 'antlr3/test/functional'
class TestProfileMode < ANTLR3::Test::Functional
compile_options :profile => true
inline_grammar( <<-'END' )
grammar SimpleC;
options { language = Ruby; }
program
: declaration+
;
/** In this rule, the functionHeader left prefix on the last two
* alternatives is not LL(k) for a fixed k. However, it is
* LL(*). The LL(*) algorithm simply scans ahead until it sees
* either the ';' or the '{' of the block and then it picks
* the appropriate alternative. Lookhead can be arbitrarily
* long in theory, but is <=10 in most cases. Works great.
* Use ANTLRWorks to see the lookahead use (step by Location)
* and look for blue tokens in the input window pane. :)
*/
declaration
: variable
| functionHeader ';'
| functionHeader block
;
variable
: type declarator ';'
;
declarator
: ID
;
functionHeader
: type ID '(' ( formalParameter ( ',' formalParameter )* )? ')'
;
formalParameter
: type declarator
;
type
: 'int'
| 'char'
| 'void'
| ID
;
block
: '{'
variable*
stat*
'}'
;
stat: forStat
| expr ';'
| block
| assignStat ';'
| ';'
;
forStat
: 'for' '(' assignStat ';' expr ';' assignStat ')' block
;
assignStat
: ID '=' expr
;
expr: condExpr
;
condExpr
: aexpr ( ('==' | '<') aexpr )?
;
aexpr
: atom ( '+' atom )*
;
atom
: ID
| INT
| '(' expr ')'
;
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
INT : ('0'..'9')+
;
WS : ( ' '
| '\t'
| '\r'
| '\n'
)+
{ $channel=HIDDEN; }
;
END
example 'profile mode output' do
input = <<-END.fixed_indent( 0 )
char c;
int x;
void bar(int x);
int foo(int y, char d) {
int i;
for (i=0; i<3; i=i+1) {
x=3;
y=5;
}
}
END
lexer = SimpleC::Lexer.new( input )
tokens = ANTLR3::CommonTokenStream.new( lexer )
parser = SimpleC::Parser.new( tokens )
parser.program
profile_data = parser.profile
profile_data.rule_invocations.should == 60
profile_data.guessing_rule_invocations.should == 0
profile_data.rule_invocation_depth.should == 12
profile_data.fixed_decisions.should == 40
fixed_data = profile_data.fixed_looks
fixed_data.min.should == 1
fixed_data.max.should == 2
fixed_data.average.should == 1.075
fixed_data.standard_deviation.should == 0.26674678283691855
profile_data.cyclic_decisions.should == 4
cyclic_data = profile_data.cyclic_looks
cyclic_data.min.should == 3
cyclic_data.max.should == 10
cyclic_data.average.should == 5.75
cyclic_data.standard_deviation.should == 3.4034296427770228
profile_data.syntactic_predicates.should == 0
profile_data.memoization_cache_entries.should == 0
profile_data.memoization_cache_hits.should == 0
profile_data.memoization_cache_misses.should == 0
profile_data.semantic_predicates.should == 0
profile_data.tokens.should == 77
profile_data.hidden_tokens.should == 24
profile_data.characters_matched.should == 118
profile_data.hidden_characters_matched.should == 40
profile_data.reported_errors.should == 0
end
end