Skip to content

Commit

Permalink
Merge pull request #4 from ikawaha/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
ikawaha committed Dec 17, 2014
2 parents 569e736 + 4149f8a commit 38344ce
Show file tree
Hide file tree
Showing 15 changed files with 1,256 additions and 53 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ go:
before_install:
- go get github.com/axw/gocov/gocov
- go get github.com/mattn/goveralls
- go get code.google.com/p/go.tools/cmd/cover
- go get golang.org/x/tools/cmd/cover

install:

script:
- go test -v ./ss
- go test -v ./si
- go test -v ./si32
- /bin/sh ./go-coverall.sh

#branches:
Expand Down
2 changes: 1 addition & 1 deletion si/fstvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func toInt(b []byte) int {
// String returns a string representation of a program.
func (vm FstVM) String() string {
ret := ""
for pc, end := 0, len(vm.prog); pc < end; {
for pc := 0; pc < len(vm.prog); {
p := pc
op := instOp(vm.prog[pc] & instMask)
sz := int(vm.prog[pc] & valMask)
Expand Down
35 changes: 15 additions & 20 deletions si/mast.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ func commonPrefixLen(a, b string) int {
return i
}

func buildMast(input PairSlice) (m *mast) {
func buildMast(input PairSlice) (m *mast) { //XXX TODO private
sort.Sort(input)

//fmt.Println("sorted---") //XXX
const initialMastSize = 1024
m = new(mast)
dic := make(map[uint][]*state)
m.states = make([]*state, 0, initialMastSize)
m.finalStates = make([]*state, 0, initialMastSize)

Expand All @@ -53,29 +54,25 @@ func buildMast(input PairSlice) (m *mast) {
}
prev := ""
for _, pair := range input {
//fmt.Println(pair) //XXX
in, out := pair.In, pair.Out
prefixLen := commonPrefixLen(in, prev)
candidate := m.finalStates
for i := len(prev); i > prefixLen; i-- {
var s *state
detected := false
if candidate != nil {
for _, c := range candidate {
if cs, ok := dic[buf[i].hcode]; ok {
for _, c := range cs {
if c.eq(buf[i]) {
buf[i].renew()
s = c
candidate = c.Prev
detected = true
break
}
}
}
if !detected {
candidate = nil
if s == nil {
s = &state{}
*s = *buf[i]
buf[i].renew()
m.addState(s)
dic[s.hcode] = append(dic[s.hcode], s)
}
buf[i-1].setTransition(prev[i-1], s)
s.setInvTransition()
Expand All @@ -90,24 +87,22 @@ func buildMast(input PairSlice) (m *mast) {
prev = in
}
// flush the buf
candidate := m.finalStates
for i := len(prev); i > 0; i-- {
var s *state
detected := false
if candidate != nil {
for _, c := range candidate {
if cs, ok := dic[buf[i].hcode]; ok {
for _, c := range cs {
if c.eq(buf[i]) {
s = c
candidate = c.Prev
detected = true
break
}
}
}
if !detected {
candidate = nil
s = buf[i]
if s == nil {
s = &state{}
*s = *buf[i]
buf[i].renew()
m.addState(s)
dic[s.hcode] = append(dic[s.hcode], s)
}
buf[i-1].setTransition(prev[i-1], s)
s.setInvTransition()
Expand Down
20 changes: 12 additions & 8 deletions si/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type state struct {
Tail intSet
IsFinal bool
Prev []*state
hcode uint
}

func newState() (n *state) {
Expand All @@ -27,10 +28,9 @@ func (n *state) hasTail() bool {

func (n *state) addTail(t int) {
n.Tail[t] = true
}

func (n *state) setTail(s intSet) {
n.Tail = s
const magic = 117709
n.hcode += uint(t) * magic
}

func (n *state) tails() (t []int) {
Expand All @@ -43,6 +43,9 @@ func (n *state) tails() (t []int) {

func (n *state) setTransition(ch byte, next *state) {
n.Trans[ch] = next

const magic = 1001
n.hcode += (uint(ch) + uint(next.ID)) * magic
}

func (n *state) setInvTransition() {
Expand All @@ -56,18 +59,19 @@ func (n *state) renew() {
n.Tail = make(intSet)
n.IsFinal = false
n.Prev = make([]*state, 0)
n.hcode = 0
}

func (n *state) eq(dst *state) bool {
if n == nil || dst == nil {
return false
}
if n == dst {
return true
if n.hcode != dst.hcode {
return false
}
if len(n.Trans) != len(dst.Trans) ||
len(n.Tail) != len(dst.Tail) ||
n.IsFinal != dst.IsFinal {
if n.IsFinal != dst.IsFinal ||
len(n.Trans) != len(dst.Trans) ||
len(n.Tail) != len(dst.Tail) {
return false
}
for ch, next := range n.Trans {
Expand Down
4 changes: 0 additions & 4 deletions si/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ func TestEq01(t *testing.T) {
{pair{x: &state{}, y: nil}, false},
{pair{&state{ID: 1}, &state{ID: 2}}, true},
{pair{&state{IsFinal: true}, &state{IsFinal: false}}, false},
//{pair{&state{Output: map[byte]int{1: 1}}, &state{}}, false},
//{pair{&state{Output: map[byte]int{1: 1}}, &state{Output: map[byte]int{1: 1}}}, true},
//{pair{&state{Output: map[byte]int{1: 1}}, &state{Output: map[byte]int{1: 2}}}, false},
//{pair{&state{Output: map[byte]int{1: 1}}, &state{Output: map[byte]int{2: 1}}}, false},
{pair{&state{Tail: map[int]bool{1: true}}, &state{Tail: map[int]bool{1: true}}}, true},
}
for _, cr := range crs {
Expand Down
2 changes: 2 additions & 0 deletions si32/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package si32 implements string to int32 transducers.
package si32

0 comments on commit 38344ce

Please sign in to comment.