Created
December 23, 2014 11:26
-
-
Save shintakezou/88188591a1a856def7c4 to your computer and use it in GitHub Desktop.
Producer/Consumer with just a single goroutine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
io "bufio" | |
"fmt" | |
"os" | |
"unicode" | |
) | |
type ControlFlow struct { | |
c byte | |
eof bool | |
} | |
// states of the FSM | |
const ( | |
START = iota | |
IN_WORD | |
) | |
// token types/kinds | |
const ( | |
WORD = iota | |
PUNCT | |
) | |
// ---- | |
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} | |
} | |
func parser(c chan ControlFlow) { | |
var in ControlFlow | |
var state int | |
var s string | |
state = START | |
for { | |
in = <-c | |
if in.eof { | |
break | |
} | |
switch state { | |
case IN_WORD: | |
if unicode.IsLetter(rune(in.c)) { | |
add_to_token(in.c, &s) | |
continue | |
} | |
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) | |
} | |
} | |
func add_to_token(a byte, s *string) { | |
*s += string(a) | |
} | |
func got_token(kind int, s *string) { | |
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) | |
go decompressor(in, ch) | |
parser(ch) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Comments and best-go-practices or simply best-practices suggestions are welcome of course.