class MorMor::FSA::FSA5

Port of FSA5.java

See constant description and other docs there: github.com/morfologik/morfologik-stemming/blob/master/morfologik-fsa/src/main/java/morfologik/fsa/FSA5.java

Constants

ADDRESS_OFFSET
BIT_FINAL_ARC
BIT_LAST_ARC
BIT_TARGET_NEXT

Attributes

arcs[R]
gtl[R]

Public Class Methods

new(io) click to toggle source
# File lib/mormor/fsa/fsa5.rb, line 15
def initialize(io)
  @filler = io.getbyte
  @annotation = io.getbyte
  hgtl = io.getbyte

  # OC: Determine if the automaton was compiled with NUMBERS. If so, modify
  # ctl and goto fields accordingly.

  # zverok: ???? This variables/flags doesn't used at all
  # flags = [FLEXIBLE, STOPBIT, NEXTBIT]
  # flags << NUMBERS if hgtl.anybits?(0xf0)

  @node_data_length = (hgtl >> 4) & 0x0f
  @gtl = hgtl & 0x0f

  @arcs = io.read.unpack('c*')
end

Public Instance Methods

arc_label(arc) click to toggle source

Examining arcs

# File lib/mormor/fsa/fsa5.rb, line 51
def arc_label(arc)
  arcs[arc]
end
end_node(arc) click to toggle source
# File lib/mormor/fsa/fsa5.rb, line 46
def end_node(arc)
  destination_node_offset(arc)
end
final_arc?(arc) click to toggle source
# File lib/mormor/fsa/fsa5.rb, line 55
def final_arc?(arc)
  arcs[arc + ADDRESS_OFFSET].allbits?(BIT_FINAL_ARC)
end
first_arc(node) click to toggle source

Navigating through arcs

# File lib/mormor/fsa/fsa5.rb, line 42
def first_arc(node)
  @node_data_length + node
end
last_arc?(arc) click to toggle source
# File lib/mormor/fsa/fsa5.rb, line 59
def last_arc?(arc)
  arcs[arc + ADDRESS_OFFSET].allbits?(BIT_LAST_ARC)
end
root_node() click to toggle source
# File lib/mormor/fsa/fsa5.rb, line 33
def root_node
  # OC: Skip dummy node marking terminating state.
  epsilon_node = skip_arc(first_arc(0))

  # OC: And follow the epsilon node's first (and only) arc.
  destination_node_offset(first_arc(epsilon_node))
end
terminal_arc?(arc) click to toggle source
# File lib/mormor/fsa/fsa5.rb, line 63
def terminal_arc?(arc)
  destination_node_offset(arc).zero?
end

Private Instance Methods

decode_from_bytes(arcs, start, n) click to toggle source
# File lib/mormor/fsa/fsa5.rb, line 71
def decode_from_bytes(arcs, start, n)
  (n - 1).downto(0).inject(0) { |r, i| r << 8 | (arcs[start + i] & 0xff) }
end
destination_node_offset(arc) click to toggle source
# File lib/mormor/fsa/fsa5.rb, line 75
def destination_node_offset(arc)
  if next_set?(arc)
    # OC: The destination node follows this arc in the array.
    skip_arc(arc)
  else
    # OC: The destination node address has to be extracted from the arc's
    # goto field.
    decode_from_bytes(arcs, arc + ADDRESS_OFFSET, gtl) >> 3
  end
end
next_set?(arc) click to toggle source
# File lib/mormor/fsa/fsa5.rb, line 86
def next_set?(arc)
  arcs[arc + ADDRESS_OFFSET].allbits?(BIT_TARGET_NEXT)
end
skip_arc(offset) click to toggle source

OC: Read the arc's layout and skip as many bytes, as needed.

# File lib/mormor/fsa/fsa5.rb, line 91
def skip_arc(offset)
  offset + if next_set?(offset)
             1 + 1   # OC: label + flags
           else
             1 + gtl # OC: label + flags/address
           end
end