class Rattler::Parsers::Analysis
Analysis
represents a static analysis of a set of parse rules.
Public Class Methods
new(rules)
click to toggle source
@param [RuleSet] rules the rule set to analyze
# File lib/rattler/parsers/analysis.rb, line 10 def initialize(rules) @rules = rules @references = {} @left_references = {} @direct_references = {} @direct_left_references = {} @has_super = {} end
Public Instance Methods
left_recursive?(rule_name)
click to toggle source
@param [Symbol] rule_name the name of a parse rule in the rule set @return true
if the rule referenced by rule_name
is left-recursive
# File lib/rattler/parsers/analysis.rb, line 34 def left_recursive?(rule_name) left_referenced_from? rule_name, rule_name end
recursive?(rule_name)
click to toggle source
@param [Symbol] rule_name the name of a parse rule in the rule set @return true
if the rule referenced by rule_name
is recursive
# File lib/rattler/parsers/analysis.rb, line 27 def recursive?(rule_name) has_super? rule_name or referenced_from? rule_name, rule_name end
referenced?(rule_name)
click to toggle source
@param [Symbol] rule_name the name of a parse rule in the rule set @return true
if the rule referenced by rule_name
is referenced by any
other rule in the rule set
# File lib/rattler/parsers/analysis.rb, line 41 def referenced?(rule_name) rule_name == @rules.start_rule or referenced_from? @rules.start_rule, rule_name end
regular?(rule_name)
click to toggle source
@param [Symbol] rule_name the name of a parse rule in the rule set @return true
if the rule referenced by rule_name
is non-recursive
# File lib/rattler/parsers/analysis.rb, line 21 def regular?(rule_name) not recursive?(rule_name) end
Private Instance Methods
direct_left_references(expr)
click to toggle source
# File lib/rattler/parsers/analysis.rb, line 98 def direct_left_references(expr) @direct_left_references[expr] ||= case expr when Apply Set[expr.rule_name] when Choice expr.map {|_| direct_left_references _ }.to_set.flatten when Rattler::Parsers::Parser direct_left_references expr.child else Set[] end end
direct_references(expr)
click to toggle source
# File lib/rattler/parsers/analysis.rb, line 87 def direct_references(expr) @direct_references[expr] ||= case expr when Apply Set[expr.rule_name] when Rattler::Parsers::Parser expr.map {|_| direct_references _ }.to_set.flatten else Set[] end end
expr_has_super?(expr)
click to toggle source
# File lib/rattler/parsers/analysis.rb, line 60 def expr_has_super?(expr) case expr when Super true when Rattler::Parsers::Parser expr.any? {|_| expr_has_super? _ } else false end end
has_super?(rule_name)
click to toggle source
# File lib/rattler/parsers/analysis.rb, line 56 def has_super?(rule_name) @has_super[rule_name] ||= expr_has_super?(@rules[rule_name].expr) end
left_referenced_from?(referencer, referencee)
click to toggle source
# File lib/rattler/parsers/analysis.rb, line 52 def left_referenced_from?(referencer, referencee) left_references_from(referencer).include? referencee end
left_references_from(rule_name)
click to toggle source
# File lib/rattler/parsers/analysis.rb, line 75 def left_references_from(rule_name) @left_references[rule_name] ||= trace_references rule_name, :direct_left_references end
referenced_from?(referencer, referencee)
click to toggle source
# File lib/rattler/parsers/analysis.rb, line 48 def referenced_from?(referencer, referencee) references_from(referencer).include? referencee end
references_from(rule_name)
click to toggle source
# File lib/rattler/parsers/analysis.rb, line 71 def references_from(rule_name) @references[rule_name] ||= trace_references rule_name, :direct_references end
trace_references(rule_name, enum, references=nil)
click to toggle source
# File lib/rattler/parsers/analysis.rb, line 79 def trace_references(rule_name, enum, references=nil) references ||= Set[] for r in send(enum, @rules[rule_name].expr) trace_references(r, enum, references << r) unless references.include? r end references end