Class: Antelope::Generation::Recognizer::State
- Inherits:
-
Object
- Object
- Antelope::Generation::Recognizer::State
- Extended by:
- Forwardable
- Includes:
- Enumerable
- Defined in:
- lib/antelope/generation/recognizer/state.rb
Overview
A state within the parser. A state has a set of rules, as well as transitions on those rules.
Instance Attribute Summary collapse
-
#id ⇒ String, Numeric
The id of this state.
-
#rules ⇒ Set<Rule>
readonly
All of the rules in this state.
-
#transitions ⇒ Hash<(Symbol, State)>
readonly
All of the transitions that can be made on this state.
Instance Method Summary collapse
-
#<<(rule) ⇒ self
(also: #push)
Appends the given object to this state.
-
#===(other) ⇒ Boolean
Check to see if this state is fuzzily equivalent to another state.
-
#initialize ⇒ State
constructor
Initialize the state.
-
#inspect ⇒ String
Gives a nice string representation of the state.
-
#merge!(other) ⇒ self
Merges another state with this state.
-
#rule_for(production) ⇒ Rule?
Finds the rule that match the given production.
Constructor Details
#initialize ⇒ State
Initialize the state.
37 38 39 40 41 |
# File 'lib/antelope/generation/recognizer/state.rb', line 37 def initialize @rules = Set.new @transitions = {} @id = format('%10x', object_id) end |
Instance Attribute Details
#id ⇒ String, Numeric
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.
29 30 31 |
# File 'lib/antelope/generation/recognizer/state.rb', line 29 def id @id end |
#rules ⇒ Set<Rule> (readonly)
All of the rules in this state.
17 18 19 |
# File 'lib/antelope/generation/recognizer/state.rb', line 17 def rules @rules end |
#transitions ⇒ Hash<(Symbol, State)> (readonly)
All of the transitions that can be made on this state.
22 23 24 |
# File 'lib/antelope/generation/recognizer/state.rb', line 22 def transitions @transitions end |
Instance Method Details
#<<(rule) ⇒ self Also known as: push
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.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# 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 |
#===(other) ⇒ Boolean
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)
.
117 118 119 120 121 122 123 124 125 |
# 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 ⇒ String
Gives a nice string representation of the state.
46 47 48 49 50 |
# 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) ⇒ self
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.
59 60 61 62 63 64 65 66 67 |
# 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 |
#rule_for(production) ⇒ Rule?
Finds the rule that match the given production. It uses fuzzy equality checking. It returns the first rule that matches.
75 76 77 |
# File 'lib/antelope/generation/recognizer/state.rb', line 75 def rule_for(production) rules.find { |rule| production === rule } end |