github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/automaton/run.go (about)

     1  package automaton
     2  
     3  import (
     4  	"unicode"
     5  )
     6  
     7  // util/automaton/RunAutomaton.java
     8  
     9  // Finite-state automaton with fast run operation.
    10  type RunAutomaton struct {
    11  	automaton   *Automaton
    12  	maxInterval int
    13  	size        int
    14  	accept      []bool
    15  	initial     int
    16  	transitions []int // delta(state,c) = transitions[state*len(points)+CharClass(c)]
    17  	points      []int // char interval start points
    18  	classmap    []int // map from char number to class class
    19  }
    20  
    21  func (ra *RunAutomaton) String() string {
    22  	panic("not implemented yet")
    23  }
    24  
    25  // Gets character class of given codepoint
    26  func (ra *RunAutomaton) charClass(c int) int {
    27  	return findIndex(c, ra.points)
    28  }
    29  
    30  // Constructs a new RunAutomaton from a deterministic Automaton.
    31  func newRunAutomaton(a *Automaton, maxInterval int, tablesize bool) *RunAutomaton {
    32  	a = determinize(a)
    33  	size := a.numStates()
    34  	if size < 1 {
    35  		size = 1
    36  	}
    37  	points := a.startPoints()
    38  	nPoints := len(points)
    39  	ans := &RunAutomaton{
    40  		maxInterval: maxInterval,
    41  		automaton:   a,
    42  		points:      points,
    43  		initial:     0,
    44  		size:        size,
    45  		accept:      make([]bool, size),
    46  		transitions: make([]int, size*nPoints),
    47  	}
    48  	for i, _ := range ans.transitions {
    49  		ans.transitions[i] = -1
    50  	}
    51  	for n := 0; n < size; n++ {
    52  		ans.accept[n] = a.IsAccept(n)
    53  		for c, point := range ans.points {
    54  			dest := a.step(n, point)
    55  			assert(dest == -1 || dest < size)
    56  			ans.transitions[n*nPoints+c] = dest
    57  		}
    58  	}
    59  	// Set alphabet table for optimal run performance.
    60  	if tablesize {
    61  		panic("not implemented yet")
    62  	}
    63  	return ans
    64  }
    65  
    66  /*
    67  Returns the state obtained by reading the given char from the given
    68  state. Returns -1 if not obtaining any such state. (If the original
    69  Automaton had no dead states, -1 is returned here if and only if a
    70  dead state is entered in an equivalent automaton with a total
    71  transition function.)
    72  */
    73  func (ra *RunAutomaton) step(state, c int) int {
    74  	if ra.classmap == nil {
    75  		return ra.transitions[state*len(ra.points)+ra.charClass(c)]
    76  	} else {
    77  		return ra.transitions[state*len(ra.points)+ra.classmap[c]]
    78  	}
    79  }
    80  
    81  // Automaton representation for matching []char
    82  type CharacterRunAutomaton struct {
    83  	*RunAutomaton
    84  }
    85  
    86  func NewCharacterRunAutomaton(a *Automaton) *CharacterRunAutomaton {
    87  	ans := &CharacterRunAutomaton{}
    88  	ans.RunAutomaton = newRunAutomaton(a, unicode.MaxRune, false)
    89  	return ans
    90  }