class MorMor::FSA::Enumerator

Rubyfied port of ByteSequenceIterator.java

See: github.com/morfologik/morfologik-stemming/blob/master/morfologik-fsa/src/main/java/morfologik/fsa/ByteSequenceIterator.java

From some node of automaton, it iterates through all paths starting at that node to their end, and yields each full path packed into original dictionary bytes string.

Attributes

arcs_stack[R]
fsa[R]
sequence[R]

Public Class Methods

new(fsa, node) click to toggle source
# File lib/mormor/fsa/enumerator.rb, line 12
def initialize(fsa, node)
  @fsa = fsa
  @arcs_stack = []
  @sequence = []

  unless (first = fsa.first_arc(node)).zero? # rubocop:disable Style/GuardClause
    arcs_stack << first
  end
end

Public Instance Methods

each() { |pack('C*')| ... } click to toggle source
# File lib/mormor/fsa/enumerator.rb, line 22
def each
  return to_enum(__method__) unless block_given?

  while (el = advance)
    yield el.pack('C*')
  end
end

Private Instance Methods

advance() click to toggle source

Method is left unsplit to leave original algorithm recognizable, hence rubocop:disable

# File lib/mormor/fsa/enumerator.rb, line 37
def advance # rubocop:disable Metrics/AbcSize
  until arcs_stack.empty?
    arc = arcs_stack.last

    if arc.zero?
      # OC: Remove the current node from the queue.
      arcs_stack.pop
      next
    end

    # OC: Go to the next arc, but leave it on the stack
    # so that we keep the recursion depth level accurate.
    arcs_stack[-1] = fsa.next_arc(arc)

    sequence[arcs_stack.count - 1] = fsa.arc_label(arc)

    # OC: Recursively descend into the arc's node.
    arcs_stack.push(fsa.end_node(arc)) unless fsa.terminal_arc?(arc)

    if fsa.final_arc?(arc)
      sequence.slice!(arcs_stack.count)
      return sequence
    end
  end

  nil
end