-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtoken.go
169 lines (150 loc) · 3.48 KB
/
token.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package strparam
import (
"bytes"
"fmt"
)
var DefaultStartParam = '{'
var DefaultEndParam = '}'
type Token struct {
Mode TokenMode
// len of bytes
Len int
// multifunctional field
Raw string
Param *Token
}
// Equal returns true if mode and length and values is equal.
func (t Token) Equal(in Token) bool {
return t.Mode == in.Mode && t.Len == in.Len && t.Raw == in.Raw
}
// String returns human-readable format of token .
func (t *Token) String() string {
switch t.Mode {
case UNKNOWN_TokenMode:
return ""
case CONST:
return fmt.Sprintf("Const(%q, len=%d)", t.Raw, t.Len)
case SEPARATOR:
return fmt.Sprintf("Separator(%q, len=%d)", t.Raw, t.Len)
case PARAMETER:
return fmt.Sprintf("Param(%q)", t.Raw)
case PARAMETER_PARSED:
return fmt.Sprintf("ParsedParam(%s=%q)", t.ParamName(), t.Raw)
case START:
return fmt.Sprintf("START")
case END:
if t.Raw != "" {
// named token
return fmt.Sprintf("END(%q)", t.Raw)
}
return fmt.Sprintf("END")
}
return fmt.Sprintf("%#v", t)
}
// ParamName returns parameter name if mode of current token is PARAMETER.
// In all other cases returns an empty value.
func (t *Token) ParamName() string {
if t.Mode == PARAMETER && len(t.Raw) > 2 {
return t.Raw[1 : len(t.Raw)-1]
}
if t.Mode == PARAMETER_PARSED && len(t.Param.Raw) > 2 {
return t.Param.Raw[1 : len(t.Param.Raw)-1]
}
return ""
}
// Tokens helper type for list tokens.
type Tokens []Token
func (t Tokens) String() string {
res := new(bytes.Buffer)
for i, token := range t {
if i > 0 {
fmt.Fprint(res, "->")
}
fmt.Fprint(res, token.String())
}
return res.String()
}
var (
StartToken = Token{Mode: START}
EndToken = Token{Mode: END}
EmptySchema = Tokens{StartToken, EndToken}
)
// TokenMode type of token mode.
type TokenMode int
// String returns human-readable format of token mode.
func (m TokenMode) String() string {
switch m {
case SEPARATOR:
return "separator"
case CONST:
return "const"
case UNKNOWN_TokenMode:
return "empty_token?"
case PARAMETER:
return "param"
case START:
return "begin"
case END:
return "end"
case PARAMETER_PARSED:
return "parsed_param"
}
return fmt.Sprintf("TokenMode(%d)", m)
}
const (
UNKNOWN_TokenMode TokenMode = 0
// CONST boarder of pattern
CONST TokenMode = 1
// PARAMETER boarder of parameter
PARAMETER TokenMode = 2
// START marker of begin line
START TokenMode = 4
// END marker of end line
END TokenMode = 5
// PARAMETER_PARSED with known offsets
PARAMETER_PARSED TokenMode = 6
// SEPARATOR special token for separating constants
SEPARATOR TokenMode = 7
)
// ConstToken returns a token of type CONST.
func ConstToken(in string) Token {
return Token{
Mode: CONST,
Len: len(in),
Raw: in,
}
}
// SeparatorToken returns a token of type SEPARATOR.
func SeparatorToken(in string) Token {
return Token{
Mode: SEPARATOR,
Len: len(in),
Raw: in,
}
}
// ParameterToken returns a token of type PARAM.
func ParameterToken(rawName string) Token {
return Token{
Mode: PARAMETER,
Raw: string(DefaultStartParam) + rawName + string(DefaultEndParam),
}
}
// ParsedParameterToken returns a token of type PARSED_PARAM.
func ParsedParameterToken(rawName, val string) Token {
return Token{
Mode: PARAMETER_PARSED,
Raw: val,
Len: len(val),
Param: &Token{
Mode: PARAMETER,
Raw: string(DefaultStartParam) + rawName + string(DefaultEndParam),
},
}
}
// NamedEndToken returns a named token of type END.
func NamedEndToken(name string) Token {
return Token{
Mode: END,
Raw: name,
}
}