-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlexer_traditional.go
74 lines (61 loc) · 1.06 KB
/
lexer_traditional.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package functionalstatemachineexample
import (
"bufio"
"errors"
"io"
"strings"
)
func TokensTraditional(r io.Reader, ch chan<- Token) {
inInt := false
intBuf := strings.Builder{}
inString := false
stringBuf := strings.Builder{}
bufR := bufio.NewReader(r)
for {
c, _, err := bufR.ReadRune()
if err != nil {
if !errors.Is(err, io.EOF) {
panic(err)
}
if inInt {
ch <- makeToken(Int, intBuf.String())
}
if inString {
panic(errors.New("string not closed")) //nolint:go-lint
}
break
}
if inInt {
if isDigit(c) {
intBuf.WriteRune(c)
continue
}
ch <- makeToken(Int, intBuf.String())
inInt = false
intBuf.Reset()
}
if inString {
if c != '"' {
stringBuf.WriteRune(c)
continue
}
ch <- makeToken(String, stringBuf.String())
inString = false
stringBuf.Reset()
continue
}
if isDigit(c) {
inInt = true
intBuf.WriteRune(c)
continue
}
switch c {
case '+':
ch <- makeToken(Plus, "+")
case '-':
ch <- makeToken(Minus, "-")
case '"':
inString = true
}
}
}