#!/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