You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
3.8 KiB
166 lines
3.8 KiB
#!/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
|