class Sequitur::SymbolSequence

Represents a sequence (concatenation) of grammar symbols as they appear in rhs of productions

Attributes

symbols[R]

@return [Array] The sequence of symbols itself

Public Class Methods

new() click to toggle source

Create an empty sequence

# File lib/sequitur/symbol_sequence.rb, line 11
def initialize
  @symbols = []
end

Public Instance Methods

<<(aSymbol) click to toggle source

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
==(other) click to toggle source

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
[](anIndex) click to toggle source

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
accept(aVisitor) click to toggle source

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() click to toggle source

Clear the symbol sequence.

# File lib/sequitur/symbol_sequence.rb, line 26
def clear
  refs = references
  refs.each(&:unbind)
  @symbols = []
  invalidate_refs
end
delete_at(position) click to toggle source

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
empty?() click to toggle source

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
initialize_copy(orig) click to toggle source

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, another) click to toggle source

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
reduce_step(index, aProduction) click to toggle source

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
references() click to toggle source

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
references_of(aProduction) click to toggle source

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
size() click to toggle source

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
to_string() click to toggle source

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

invalidate_refs() click to toggle source
# File lib/sequitur/symbol_sequence.rb, line 169
def invalidate_refs
  @memo_references = nil
  @lookup_references = nil
end