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