Skip to content

Instantly share code, notes, and snippets.

@shintakezou
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shintakezou/9f8aa5d6acb9d0e75247 to your computer and use it in GitHub Desktop.
Save shintakezou/9f8aa5d6acb9d0e75247 to your computer and use it in GitHub Desktop.
Go-routines
package main
import (
io "bufio"
"fmt"
"os"
"sync"
"unicode"
)
type ControlFlow struct {
c byte
end_of_file bool
}
// states of the FSM
const (
START = iota
IN_WORD
)
// token types/kinds
const (
WORD = iota
PUNCT
)
// syncing
var wg sync.WaitGroup
// ----
func decompressor(in *io.Reader, out_stream chan ControlFlow) {
for {
b, err := in.ReadByte()
if err != nil {
break
} else if b == 0xFF {
len, _ := in.ReadByte() // ignore errors...
real_len := int(len) + 1
c, _ := in.ReadByte()
for ; real_len >= 0; real_len-- {
out_stream <- ControlFlow{c, false}
}
} else {
out_stream <- ControlFlow{b, false}
}
}
out_stream <- ControlFlow{0, true}
wg.Done()
}
func parser(c chan ControlFlow) {
var in ControlFlow
var s string
var state int
state = START
for in = <-c; !in.end_of_file; in = <-c {
switch state {
case IN_WORD:
if unicode.IsLetter(rune(in.c)) {
add_to_token(in.c, &s)
continue // "=" return
}
got_token(WORD, &s)
state = START
fallthrough
case START:
add_to_token(in.c, &s)
if unicode.IsLetter(rune(in.c)) {
state = IN_WORD
} else {
got_token(PUNCT, &s)
}
break
}
}
if state == IN_WORD {
got_token(WORD, &s)
}
wg.Done()
}
func add_to_token(a byte, s *string) {
*s += string(a)
}
func got_token(kind int, s *string) {
if len(*s) > 0 {
switch kind {
case WORD:
fmt.Printf("WORD: %s\n", *s)
break
case PUNCT:
fmt.Printf("PUNCT: %s\n", *s)
break
}
*s = ""
}
}
func main() {
in := io.NewReader(os.Stdin)
ch := make(chan ControlFlow)
wg.Add(2)
go parser(ch)
go decompressor(in, ch)
wg.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment