class ANTLR3::Profile::Profiler

When ANTLR is run with the -profile switch, it generates recognition code that performs accounting about the decision logic performed while parsing any given input. This information can be used to help refactor a slow grammar. Profiler is an event-listener that performs all of the profiling accounting and builds a simple report to present the various statistics.

Constants

PROTOCOL_VERSION

Attributes

decision_level[R]
decision_look[R]

tracks the maximum look value for the current decision (maxLookaheadInCurrentDecision in java Profiler)

last_token[R]

the last token consumed (lastTokenConsumed in java Profiler)

look_stack[R]
output[RW]
parser[RW]
profile[R]
rule_level[R]

Public Class Methods

new( parser = nil, output = nil ) click to toggle source
# File lib/antlr3/profile.rb, line 217
def initialize( parser = nil, output = nil )
  @parser = parser
  @profile = nil
  @rule_level = 0
  @decision_level = 0
  @decision_look = 0
  @last_token = nil
  @look_stack = []
  @output = output
end

Public Instance Methods

commence() click to toggle source
# File lib/antlr3/profile.rb, line 228
def commence
  @profile = Profile.new
  @rule_level = 0
  @decision_level = 0
  @decision_look = 0
  @last_token = nil
  @look_stack = []
end
consume_hidden_token( token ) click to toggle source
# File lib/antlr3/profile.rb, line 295
def consume_hidden_token( token )
  @last_token = token
end
consume_token( token ) click to toggle source
# File lib/antlr3/profile.rb, line 287
def consume_token( token )
  @last_token = token
end
end_backtrack( level, successful ) click to toggle source
# File lib/antlr3/profile.rb, line 311
def end_backtrack( level, successful )
  @profile.syntactic_predicate_looks << @decision_look
end
enter_decision( decision_number ) click to toggle source
# File lib/antlr3/profile.rb, line 269
def enter_decision( decision_number )
  @decision_level += 1
  starting_look_index = @parser.input.index
  @look_stack << starting_look_index
end
enter_rule( grammar_file_name, rule_name ) click to toggle source
# File lib/antlr3/profile.rb, line 237
def enter_rule( grammar_file_name, rule_name )
  if @rule_level.zero?
    commence
    @profile.grammar_file = grammar_file_name
    @profile.parser_class = @parser.class
    @profile.top_rule = rule_name
  end
  @rule_level += 1
  @profile.rule_invocations += 1
  @profile.rule_invocation_depth < @rule_level and
    @profile.rule_invocation_depth = @rule_level
end
examine_rule_memoization( rule ) click to toggle source
# File lib/antlr3/profile.rb, line 254
def examine_rule_memoization( rule )
  stop_index = parser.rule_memoization( rule, @parser.input.index )
  if stop_index == MEMO_RULE_UNKNOWN
    @profile.memoization_cache_misses += 1
    @profile.guessing_rule_invocations += 1
  else
    @profile.memoization_cache_hits += 1
  end
end
exit_decision( decision_number ) click to toggle source
# File lib/antlr3/profile.rb, line 275
def exit_decision( decision_number )
  @look_stack.pop
  @decision_level -= 1
  if @parser.cyclic_decision? then
    @profile.cyclic_looks << @decision_look
  else @profile.fixed_looks << @decision_look
  end
  
  @parser.cyclic_decision = false
  @decision_look = 0    
end
exit_rule( grammar_file_name, rule_name ) click to toggle source
# File lib/antlr3/profile.rb, line 250
def exit_rule( grammar_file_name, rule_name )
  @rule_level -= 1
end
in_decision?() click to toggle source
# File lib/antlr3/profile.rb, line 291
def in_decision?
  return( @decision_level > 0 )
end
look( i, token ) click to toggle source
# File lib/antlr3/profile.rb, line 299
def look( i, token )
  in_decision? or return
  starting_index = look_stack.last
  input = @parser.input
  this_ref_index = input.index
  num_hidden = input.tokens( starting_index, this_ref_index ).count { |t| t.hidden? }
  depth = i + this_ref_index - starting_index - num_hidden
  if depth > @decision_look
    @decision_look = depth
  end
end
memoize( rule, start_index, success ) click to toggle source
# File lib/antlr3/profile.rb, line 264
def memoize( rule, start_index, success )
  @profile.memoization_cache_entries += 1
end
recognition_exception( error ) click to toggle source
# File lib/antlr3/profile.rb, line 315
def recognition_exception( error )
  @profile.reported_errors += 1
end
report() click to toggle source
# File lib/antlr3/profile.rb, line 353
def report
  @profile.generate_report
end
Also aliased as: to_s
semantic_predicate( result, predicate ) click to toggle source
# File lib/antlr3/profile.rb, line 319
def semantic_predicate( result, predicate )
  in_decision? and @profile.semantic_predicates += 1
end
terminate() click to toggle source
# File lib/antlr3/profile.rb, line 323
def terminate
  input = @parser.input
  hidden_tokens = input.select { |token| token.hidden? }
  @profile.hidden_tokens = hidden_tokens.length
  @profile.tokens = input.tokens.length
  @profile.hidden_characters_matched = hidden_tokens.inject( 0 ) do |count, token|
    count + token.text.length rescue count
  end
  @profile.characters_matched = ( @last_token || input.tokens.last ).stop + 1 rescue 0
  write_report
end
to_s()
Alias for: report
write_report() click to toggle source
# File lib/antlr3/profile.rb, line 336
  def write_report
    @output << @profile.generate_report unless @output.nil?
  rescue NoMethodError => error
    if error.name.to_s == '<<'
      warn( <<-END.strip! % [ __FILE__, __LINE__, @output ] )
        [%s @ %s]: failed to write report to %p as it does not respond to :<<
      END
    else raise
    end
  rescue IOError => error
    $stderr.puts( Util.tidy( <<-END ) % [ __FILE__, __LINE__, @output, error.class, error.message ] )
    | [%s @ %s]: failed to write profile report to %p due to an IO Error:
    |   %s: %s
    END
    $stderr.puts( error.backtrace.map { |call| "  - #{ call }" }.join( "\n" ) )
  end