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