Class: ANTLR3::Profile::Profiler
Overview
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.
Constant Summary
collapse
- PROTOCOL_VERSION =
2
Constants included
from Constants
Constants::BUILT_IN_TOKEN_NAMES, Constants::DEFAULT, Constants::DOWN, Constants::EOF, Constants::EOF_TOKEN, Constants::EOR_TOKEN_TYPE, Constants::HIDDEN, Constants::INVALID, Constants::INVALID_NODE, Constants::INVALID_TOKEN, Constants::MEMO_RULE_FAILED, Constants::MEMO_RULE_UNKNOWN, Constants::MIN_TOKEN_TYPE, Constants::SKIP_TOKEN, Constants::UP
Debug::EventListener::EVENTS
Instance Attribute Summary collapse
Instance Method Summary
collapse
#add_child, #backtrack, #become_root, #begin_backtrack, #begin_resync, #consume_node, #create_node, #end_resync, #enter_alternative, #enter_subrule, #error_node, #exit_subrule, #flat_node, #location, #mark, #on, #resync, #rewind, #set_token_boundaries
Constructor Details
#initialize(parser = nil, output = nil) ⇒ Profiler
Returns a new instance of Profiler.
217
218
219
220
221
222
223
224
225
226
|
# 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
|
Instance Attribute Details
#decision_level ⇒ Object
Returns the value of attribute decision_level.
203
204
205
|
# File 'lib/antlr3/profile.rb', line 203
def decision_level
@decision_level
end
|
#decision_look ⇒ Object
tracks the maximum look value for the current decision (maxLookaheadInCurrentDecision in java Profiler)
207
208
209
|
# File 'lib/antlr3/profile.rb', line 207
def decision_look
@decision_look
end
|
#last_token ⇒ Object
the last token consumed (lastTokenConsumed in java Profiler)
211
212
213
|
# File 'lib/antlr3/profile.rb', line 211
def last_token
@last_token
end
|
#look_stack ⇒ Object
Returns the value of attribute look_stack.
212
213
214
|
# File 'lib/antlr3/profile.rb', line 212
def look_stack
@look_stack
end
|
#output ⇒ Object
Returns the value of attribute output.
215
216
217
|
# File 'lib/antlr3/profile.rb', line 215
def output
@output
end
|
#parser ⇒ Object
Returns the value of attribute parser.
201
202
203
|
# File 'lib/antlr3/profile.rb', line 201
def parser
@parser
end
|
#profile ⇒ Object
Returns the value of attribute profile.
213
214
215
|
# File 'lib/antlr3/profile.rb', line 213
def profile
@profile
end
|
#rule_level ⇒ Object
Returns the value of attribute rule_level.
202
203
204
|
# File 'lib/antlr3/profile.rb', line 202
def rule_level
@rule_level
end
|
Instance Method Details
#commence ⇒ Object
228
229
230
231
232
233
234
235
|
# 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) ⇒ Object
295
296
297
|
# File 'lib/antlr3/profile.rb', line 295
def consume_hidden_token( token )
@last_token = token
end
|
#consume_token(token) ⇒ Object
287
288
289
|
# File 'lib/antlr3/profile.rb', line 287
def consume_token( token )
@last_token = token
end
|
#end_backtrack(level, successful) ⇒ Object
311
312
313
|
# File 'lib/antlr3/profile.rb', line 311
def end_backtrack( level, successful )
@profile.syntactic_predicate_looks << @decision_look
end
|
#enter_decision(decision_number) ⇒ Object
269
270
271
272
273
|
# 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) ⇒ Object
237
238
239
240
241
242
243
244
245
246
247
248
|
# 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) ⇒ Object
254
255
256
257
258
259
260
261
262
|
# 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) ⇒ Object
275
276
277
278
279
280
281
282
283
284
285
|
# 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) ⇒ Object
250
251
252
|
# File 'lib/antlr3/profile.rb', line 250
def exit_rule( grammar_file_name, rule_name )
@rule_level -= 1
end
|
#in_decision? ⇒ Boolean
291
292
293
|
# File 'lib/antlr3/profile.rb', line 291
def in_decision?
return( @decision_level > 0 )
end
|
#look(i, token) ⇒ Object
299
300
301
302
303
304
305
306
307
308
309
|
# 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) ⇒ Object
264
265
266
|
# File 'lib/antlr3/profile.rb', line 264
def memoize( rule, start_index, success )
@profile.memoization_cache_entries += 1
end
|
#recognition_exception(error) ⇒ Object
315
316
317
|
# File 'lib/antlr3/profile.rb', line 315
def recognition_exception( error )
@profile.reported_errors += 1
end
|
#report ⇒ Object
Also known as:
to_s
353
354
355
|
# File 'lib/antlr3/profile.rb', line 353
def report
@profile.generate_report
end
|
#semantic_predicate(result, predicate) ⇒ Object
319
320
321
|
# File 'lib/antlr3/profile.rb', line 319
def semantic_predicate( result, predicate )
in_decision? and @profile.semantic_predicates += 1
end
|
#terminate ⇒ Object
323
324
325
326
327
328
329
330
331
332
333
|
# 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
|
#write_report ⇒ Object
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
|
# 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
|