class Antelope::Generation::Recognizer::State

A state within the parser. A state has a set of rules, as well as transitions on those rules.

Attributes

id[RW]

The id of this state. This starts off as a string of hexadecmial characters, but after all of the states are finalized, this becomes a numeric.

@return [String, Numeric]

rules[R]

All of the rules in this state.

@return [Set<Rule>]

transitions[R]

All of the transitions that can be made on this state.

@return [Hash<(Symbol, State)>]

Public Class Methods

new() click to toggle source

Initialize the state.

# File lib/antelope/generation/recognizer/state.rb, line 37
def initialize
  @rules = Set.new
  @transitions = {}
  @id = format('%10x', object_id)
end

Public Instance Methods

<<(rule) click to toggle source

Appends the given object to this state. The given object must be a state or a rule. If it’s a state, it appends all of the rules in the state to this state. If it’s a rule, it adds the rule to our rules.

@raise [ArgumentError] if the argument isn’t a {State} or a

{Rule}.

@param rule [State, Rule] the object to append. @return [self]

# File lib/antelope/generation/recognizer/state.rb, line 88
def <<(rule)
  case rule
  when State
    rule.rules.map(&:clone).each { |r| self << r }
  when Rule
    rules << rule
  when Array, Set
    rule.each do |part|
      self << part
    end
  else
    raise ArgumentError, "Expected State or Rule, " \
      "got #{rule.class}"
  end

  self
end
Also aliased as: push
===(other) click to toggle source

Check to see if this state is fuzzily equivalent to another state. It does this by checking if the transitions are equivalent, and then that the rules are fuzzily equivalent. Ideally, the method is commutative; that is, ‘(a === b) == (b === a)`.

@param other [State] the state to check. @return [Boolean] @see Rule#===

Calls superclass method
# File lib/antelope/generation/recognizer/state.rb, line 117
def ===(other)
  return super unless other.is_a? State

  other_rules = other.rules.to_a
  other.transitions == transitions &&
    rules.size == other_rules.size &&
    rules.each_with_index
    .all? { |rule, i| rule === other_rules[i] }
end
inspect() click to toggle source

Gives a nice string representation of the state.

@return [String]

# File lib/antelope/generation/recognizer/state.rb, line 46
def inspect
  "#<#{self.class} id=#{id} " \
    "transitions=[#{transitions.keys.join(', ')}] " \
    "rules=[{#{rules.to_a.join('} {')}}]>"
end
merge!(other) click to toggle source

Merges another state with this state. It copies all of the rules into this state, and then merges the transitions on the given state to this state. It then returns self.

@raise [ArgumentError] if the given argument is not a state. @param other [State] the state to merge. @return [self]

# File lib/antelope/generation/recognizer/state.rb, line 59
def merge!(other)
  raise ArgumentError, "Expected #{self.class}, " \
    "got #{other.class}" unless other.is_a? State

  self << other
  transitions.merge! other.transitions

  self
end
push(rule)
Alias for: <<
rule_for(production) click to toggle source

Finds the rule that match the given production. It uses fuzzy equality checking. It returns the first rule that matches.

@param production [Rule] the rule to compare. @return [Rule?]

# File lib/antelope/generation/recognizer/state.rb, line 75
def rule_for(production)
  rules.find { |rule| production === rule }
end