class Sequitur::SymbolSequence
Represents a sequence (concatenation) of grammar symbols as they appear in rhs of productions
Attributes
@return [Array] The sequence of symbols itself
Public Class Methods
Create an empty sequence
# File lib/sequitur/symbol_sequence.rb, line 11 def initialize @symbols = [] end
Public Instance Methods
Append a grammar symbol at the end of the sequence. @param aSymbol [Object] The symbol to append.
# File lib/sequitur/symbol_sequence.rb, line 47 def <<(aSymbol) symbols << aSymbol return unless aSymbol.is_a?(ProductionRef) @memo_references ||= [] @memo_references << aSymbol end
Equality testing. @param other [SymbolSequence, Array] the other other sequence
to compare to.
@return [TrueClass, FalseClass] true when an item from self equals the corresponding
item from 'other'
# File lib/sequitur/symbol_sequence.rb, line 66 def ==(other) true if object_id == other.object_id case other when SymbolSequence symbols == other.symbols when Array symbols == other else false end end
Retrieve the element from the sequence at given position. @param anIndex [Fixnum] A zero-based index of the element to access.
# File lib/sequitur/symbol_sequence.rb, line 57 def [](anIndex) symbols[anIndex] end
Part of the ‘visitee’ role in Visitor design pattern. @param aVisitor
# File lib/sequitur/symbol_sequence.rb, line 152 def accept(aVisitor) aVisitor.start_visit_rhs(self) # Let's proceed with the visit of productions symbols.each do |a_symb| if a_symb.is_a?(ProductionRef) a_symb.accept(aVisitor) else aVisitor.visit_terminal(a_symb) end end aVisitor.end_visit_rhs(self) end
Clear the symbol sequence.
# File lib/sequitur/symbol_sequence.rb, line 26 def clear refs = references refs.each(&:unbind) @symbols = [] invalidate_refs end
Remove the element at given position @param position [Integer] a zero-based index.
# File lib/sequitur/symbol_sequence.rb, line 145 def delete_at(position) invalidate_refs if symbols[position].is_a?(ProductionRef) symbols.delete_at(position) end
Tell whether the sequence is empty. @[true / false] true only if the sequence has no symbol in it.
# File lib/sequitur/symbol_sequence.rb, line 35 def empty? symbols.empty? end
Copy constructor invoked by dup or clone methods. @param orig [SymbolSequence]
# File lib/sequitur/symbol_sequence.rb, line 17 def initialize_copy(orig) # Deep copy to avoid the aliasing of production reference @symbols = orig.symbols.map do |sym| sym.is_a?(ProductionRef) ? sym.dup : sym end invalidate_refs end
Insert at position the elements from another sequence. @param position [Fixnum] A zero-based index of the symbols to replace. @param another [SymbolSequence] A production with a two-elements rhs
(a single digram).
# File lib/sequitur/symbol_sequence.rb, line 113 def insert_at(position, another) klone = another.dup symbols.insert(position, *klone.symbols) invalidate_refs end
Given that the production P passed as argument has exactly 2 symbols
in its rhs s1 s2, substitute in the rhs of self all occurrences of s1 s2 by a reference to P.
@param index [Integer] the position of a two symbol sequence to be replaced
by the production
@param aProduction [Production, ProductionRef] a production that
consists exactly of one digram (= 2 symbols).
# File lib/sequitur/symbol_sequence.rb, line 126 def reduce_step(index, aProduction) if symbols[index].is_a?(ProductionRef) symbols[index].bind_to(aProduction) else new_ref = ProductionRef.new(aProduction) symbols[index] = new_ref @memo_references ||= [] @memo_references << new_ref end index1 = index + 1 if symbols[index1].is_a?(ProductionRef) symbols[index1].unbind invalidate_refs end delete_at(index1) end
Select the references to production appearing in the rhs. @[Array of ProductionRef]
# File lib/sequitur/symbol_sequence.rb, line 81 def references @memo_references ||= symbols.select { |symb| symb.is_a?(ProductionRef) } @memo_references end
Select the references of the given production appearing in the rhs. @param aProduction [Production] @[Array of ProductionRef]
# File lib/sequitur/symbol_sequence.rb, line 89 def references_of(aProduction) [] if references.empty? references.select { |a_ref| a_ref == aProduction } end
Count the number of elements in the sequence.
@[Fixnum] the number of elements
# File lib/sequitur/symbol_sequence.rb, line 41 def size symbols.size end
Emit a text representation of the symbol sequence. Text is of the form: space-separated sequence of symbols. @[String]
# File lib/sequitur/symbol_sequence.rb, line 98 def to_string rhs_text = symbols.map do |elem| case elem when String then "'#{elem}'" else elem.to_s end end rhs_text.join(' ') end
Private Instance Methods
# File lib/sequitur/symbol_sequence.rb, line 169 def invalidate_refs @memo_references = nil @lookup_references = nil end