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 }