go(lex): Add "no concurrent" modification from the video.
authorsgf <sgf.dma@gmail.com>
Fri, 24 Jun 2022 15:37:28 +0000 (18:37 +0300)
committersgf <sgf.dma@gmail.com>
Fri, 24 Jun 2022 15:38:32 +0000 (18:38 +0300)
lexical-scanning-in-go/lex.go

index 0dc0bb9..a23c9bd 100644 (file)
@@ -53,6 +53,7 @@ type lexer struct {
     start int
     pos int
     width int
+    state stateFn // Used by non-concurrent 'lexNoConcurrent'
     items chan item
 }
 
@@ -203,11 +204,41 @@ func (l *lexer) errorf(format string, args ...interface{}) stateFn {
     return nil
 }
 
+func lexNoConcurrent(name, input string) *lexer {
+    l := &lexer{
+        name: name,
+        input: input,
+        state: lexText,
+        items: make(chan item, 2),
+    }
+    return l
+}
+
+func (l *lexer) nextItem() item {
+    for {
+        select {
+        case item := <-l.items:
+            return item
+        default:
+            l.state = l.state(l)
+        }
+    }
+    panic("not reached")
+}
+
 func main() {
+    fmt.Println("### Concurrent version:")
     _, ch := lex("huy", "text {{ 1.34e3 }} yet another text")
     for it := range ch {
         fmt.Printf("Received %v\n", it)
     }
     fmt.Println("End")
+
+    fmt.Println("\n### Not concurrent version:")
+    l := lexNoConcurrent("huy", "text {{ 1.34e3 }} yet another text")
+    for it := l.nextItem(); it.typ != itemEOF; it = l.nextItem() {
+        fmt.Printf("Received %v\n", it)
+    }
+    fmt.Println("End")
 }