Class: Sequitur::SymbolSequence

Inherits:
Object
  • Object
show all
Defined in:
lib/sequitur/symbol_sequence.rb

Overview

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSymbolSequence

Create an empty sequence



11
12
13
# File 'lib/sequitur/symbol_sequence.rb', line 11

def initialize
  @symbols = []
end

Instance Attribute Details

#symbolsArray (readonly)

Returns The sequence of symbols itself.

Returns:

  • (Array)

    The sequence of symbols itself



8
9
10
# File 'lib/sequitur/symbol_sequence.rb', line 8

def symbols
  @symbols
end

Instance Method Details

#<<(aSymbol) ⇒ Object

Append a grammar symbol at the end of the sequence.

Parameters:

  • aSymbol (Object)

    The symbol to append.



47
48
49
50
51
52
53
# 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) ⇒ TrueClass, FalseClass

Equality testing.

Parameters:

  • other (SymbolSequence, Array)

    the other other sequence to compare to.

Returns:

  • (TrueClass, FalseClass)

    true when an item from self equals the corresponding item from 'other'



66
67
68
69
70
71
72
73
74
75
76
77
# 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) ⇒ Object

Retrieve the element from the sequence at given position.

Parameters:

  • anIndex (Fixnum)

    A zero-based index of the element to access.



57
58
59
# File 'lib/sequitur/symbol_sequence.rb', line 57

def [](anIndex)
  symbols[anIndex]
end

#accept(aVisitor) ⇒ Object

Part of the 'visitee' role in Visitor design pattern.

Parameters:



152
153
154
155
156
157
158
159
160
161
162
163
164
165
# 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

#clearObject

Clear the symbol sequence.



26
27
28
29
30
31
# File 'lib/sequitur/symbol_sequence.rb', line 26

def clear
  refs = references
  refs.each(&:unbind)
  @symbols = []
  invalidate_refs
end

#delete_at(position) ⇒ Object

Remove the element at given position

Parameters:

  • position (Integer)

    a zero-based index.



145
146
147
148
# 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?Boolean

Tell whether the sequence is empty. @[true / false] true only if the sequence has no symbol in it.

Returns:

  • (Boolean)


35
36
37
# File 'lib/sequitur/symbol_sequence.rb', line 35

def empty?
  symbols.empty?
end

#initialize_copy(orig) ⇒ Object

Copy constructor invoked by dup or clone methods.

Parameters:



17
18
19
20
21
22
23
# 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) ⇒ Object

Insert at position the elements from another sequence.

Parameters:

  • position (Fixnum)

    A zero-based index of the symbols to replace.

  • another (SymbolSequence)

    A production with a two-elements rhs (a single digram).



113
114
115
116
117
# 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) ⇒ Object

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.

Parameters:

  • index (Integer)

    the position of a two symbol sequence to be replaced by the production

  • aProduction (Production, ProductionRef)

    a production that consists exactly of one digram (= 2 symbols).



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# 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

#referencesObject

Select the references to production appearing in the rhs. @[Array of ProductionRef]



81
82
83
84
# 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) ⇒ Object

Select the references of the given production appearing in the rhs. @[Array of ProductionRef]

Parameters:



89
90
91
92
93
# File 'lib/sequitur/symbol_sequence.rb', line 89

def references_of(aProduction)
  [] if references.empty?

  references.select { |a_ref| a_ref == aProduction }
end

#sizeObject

Count the number of elements in the sequence. @[Fixnum] the number of elements



41
42
43
# File 'lib/sequitur/symbol_sequence.rb', line 41

def size
  symbols.size
end

#to_stringObject

Emit a text representation of the symbol sequence. Text is of the form: space-separated sequence of symbols. @[String]



98
99
100
101
102
103
104
105
106
107
# 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