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

#symbolsObject (readonly)

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) ⇒ Object

Equality testing.

Parameters:

  • other (SymbolSequence or Array)

    the other other sequence to compare to.

Returns:

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



66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/sequitur/symbol_sequence.rb', line 66

def ==(other)
  return true if object_id == other.object_id

  same = case other
           when SymbolSequence
             symbols == other.symbols
           when Array
             symbols == other
           else
             false
         end

  return same
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)
  return symbols[anIndex]
end

#accept(aVisitor) ⇒ Object

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

Parameters:



155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/sequitur/symbol_sequence.rb', line 155

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 (Fixnum)

    a zero-based index.



148
149
150
151
# File 'lib/sequitur/symbol_sequence.rb', line 148

def delete_at(position)
  invalidate_refs if symbols[position].is_a?(ProductionRef)
  symbols.delete_at(position)
end

#empty?true / false

Tell whether the sequence is empty.

Returns:

  • (true / false)

    true only if the sequence has no symbol in it.



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

def empty?
  return 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).



116
117
118
119
120
# File 'lib/sequitur/symbol_sequence.rb', line 116

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 (Fixnum)

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

  • aProduction (Production or ProductionRef)

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



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/sequitur/symbol_sequence.rb', line 129

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

#referencesArray of ProductionRef

Select the references to production appearing in the rhs.

Returns:



83
84
85
86
# File 'lib/sequitur/symbol_sequence.rb', line 83

def references
  @memo_references ||= symbols.select { |symb| symb.is_a?(ProductionRef) }
  return @memo_references
end

#references_of(aProduction) ⇒ Array of ProductionRef

Select the references of the given production appearing in the rhs.

Parameters:

Returns:



91
92
93
94
95
96
# File 'lib/sequitur/symbol_sequence.rb', line 91

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

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

#sizeObject

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



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

def size
  return symbols.size
end

#to_stringString

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

Returns:

  • (String)


101
102
103
104
105
106
107
108
109
110
# File 'lib/sequitur/symbol_sequence.rb', line 101

def to_string
  rhs_text = symbols.map do |elem|
    case elem
      when String then "'#{elem}'"
      else elem.to_s
    end
  end

  return rhs_text.join(' ')
end