-
Notifications
You must be signed in to change notification settings - Fork 2
/
pipeline_lexer.go
76 lines (66 loc) · 1.38 KB
/
pipeline_lexer.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
75
76
package main
type tokenType int
const (
identifier_token tokenType = iota
string_literal_token
pipe_token
plus_token
minus_token
)
type token struct {
tokenType tokenType
tokenValue string
}
func lex(cmd string) []token {
tokens := []token{}
var readingLiteral bool
literal := ""
endLiteral := func() {
if literal != "" {
tokens = append(tokens, token{tokenType: identifier_token, tokenValue: literal})
literal = ""
}
}
escapeNext := false
for _, c := range cmd {
if escapeNext {
literal += string(c)
escapeNext = false
} else {
switch c {
case '\\':
escapeNext = true
case '"':
if readingLiteral {
tokens = append(tokens, token{tokenType: string_literal_token, tokenValue: literal})
}
readingLiteral = !readingLiteral
literal = ""
case '+':
endLiteral()
tokens = append(tokens, token{tokenType: plus_token})
case '-':
endLiteral()
tokens = append(tokens, token{tokenType: minus_token})
case '|':
endLiteral()
tokens = append(tokens, token{tokenType: pipe_token})
case ' ':
if readingLiteral {
literal += string(c)
} else {
endLiteral()
}
default:
literal += string(c)
}
}
}
if readingLiteral {
panic("unterminated string literal")
}
if literal != "" {
tokens = append(tokens, token{tokenType: identifier_token, tokenValue: literal})
}
return tokens
}