Source file
src/go/token/token.go
1
2
3
4
5
6
7
8 package token
9
10 import (
11 "strconv"
12 "unicode"
13 "unicode/utf8"
14 )
15
16
17 type Token int
18
19
20 const (
21
22 ILLEGAL Token = iota
23 EOF
24 COMMENT
25
26 literal_beg
27
28
29 IDENT
30 INT
31 FLOAT
32 IMAG
33 CHAR
34 STRING
35 literal_end
36
37 operator_beg
38
39 ADD
40 SUB
41 MUL
42 QUO
43 REM
44
45 AND
46 OR
47 XOR
48 SHL
49 SHR
50 AND_NOT
51
52 ADD_ASSIGN
53 SUB_ASSIGN
54 MUL_ASSIGN
55 QUO_ASSIGN
56 REM_ASSIGN
57
58 AND_ASSIGN
59 OR_ASSIGN
60 XOR_ASSIGN
61 SHL_ASSIGN
62 SHR_ASSIGN
63 AND_NOT_ASSIGN
64
65 LAND
66 LOR
67 ARROW
68 INC
69 DEC
70
71 EQL
72 LSS
73 GTR
74 ASSIGN
75 NOT
76
77 NEQ
78 LEQ
79 GEQ
80 DEFINE
81 ELLIPSIS
82
83 LPAREN
84 LBRACK
85 LBRACE
86 COMMA
87 PERIOD
88
89 RPAREN
90 RBRACK
91 RBRACE
92 SEMICOLON
93 COLON
94 operator_end
95
96 keyword_beg
97
98 BREAK
99 CASE
100 CHAN
101 CONST
102 CONTINUE
103
104 DEFAULT
105 DEFER
106 ELSE
107 FALLTHROUGH
108 FOR
109
110 FUNC
111 GO
112 GOTO
113 IF
114 IMPORT
115
116 INTERFACE
117 MAP
118 PACKAGE
119 RANGE
120 RETURN
121
122 SELECT
123 STRUCT
124 SWITCH
125 TYPE
126 VAR
127 keyword_end
128 )
129
130 var tokens = [...]string{
131 ILLEGAL: "ILLEGAL",
132
133 EOF: "EOF",
134 COMMENT: "COMMENT",
135
136 IDENT: "IDENT",
137 INT: "INT",
138 FLOAT: "FLOAT",
139 IMAG: "IMAG",
140 CHAR: "CHAR",
141 STRING: "STRING",
142
143 ADD: "+",
144 SUB: "-",
145 MUL: "*",
146 QUO: "/",
147 REM: "%",
148
149 AND: "&",
150 OR: "|",
151 XOR: "^",
152 SHL: "<<",
153 SHR: ">>",
154 AND_NOT: "&^",
155
156 ADD_ASSIGN: "+=",
157 SUB_ASSIGN: "-=",
158 MUL_ASSIGN: "*=",
159 QUO_ASSIGN: "/=",
160 REM_ASSIGN: "%=",
161
162 AND_ASSIGN: "&=",
163 OR_ASSIGN: "|=",
164 XOR_ASSIGN: "^=",
165 SHL_ASSIGN: "<<=",
166 SHR_ASSIGN: ">>=",
167 AND_NOT_ASSIGN: "&^=",
168
169 LAND: "&&",
170 LOR: "||",
171 ARROW: "<-",
172 INC: "++",
173 DEC: "--",
174
175 EQL: "==",
176 LSS: "<",
177 GTR: ">",
178 ASSIGN: "=",
179 NOT: "!",
180
181 NEQ: "!=",
182 LEQ: "<=",
183 GEQ: ">=",
184 DEFINE: ":=",
185 ELLIPSIS: "...",
186
187 LPAREN: "(",
188 LBRACK: "[",
189 LBRACE: "{",
190 COMMA: ",",
191 PERIOD: ".",
192
193 RPAREN: ")",
194 RBRACK: "]",
195 RBRACE: "}",
196 SEMICOLON: ";",
197 COLON: ":",
198
199 BREAK: "break",
200 CASE: "case",
201 CHAN: "chan",
202 CONST: "const",
203 CONTINUE: "continue",
204
205 DEFAULT: "default",
206 DEFER: "defer",
207 ELSE: "else",
208 FALLTHROUGH: "fallthrough",
209 FOR: "for",
210
211 FUNC: "func",
212 GO: "go",
213 GOTO: "goto",
214 IF: "if",
215 IMPORT: "import",
216
217 INTERFACE: "interface",
218 MAP: "map",
219 PACKAGE: "package",
220 RANGE: "range",
221 RETURN: "return",
222
223 SELECT: "select",
224 STRUCT: "struct",
225 SWITCH: "switch",
226 TYPE: "type",
227 VAR: "var",
228 }
229
230
231
232
233
234
235
236 func (tok Token) String() string {
237 s := ""
238 if 0 <= tok && tok < Token(len(tokens)) {
239 s = tokens[tok]
240 }
241 if s == "" {
242 s = "token(" + strconv.Itoa(int(tok)) + ")"
243 }
244 return s
245 }
246
247
248
249
250
251
252
253 const (
254 LowestPrec = 0
255 UnaryPrec = 6
256 HighestPrec = 7
257 )
258
259
260
261
262
263 func (op Token) Precedence() int {
264 switch op {
265 case LOR:
266 return 1
267 case LAND:
268 return 2
269 case EQL, NEQ, LSS, LEQ, GTR, GEQ:
270 return 3
271 case ADD, SUB, OR, XOR:
272 return 4
273 case MUL, QUO, REM, SHL, SHR, AND, AND_NOT:
274 return 5
275 }
276 return LowestPrec
277 }
278
279 var keywords map[string]Token
280
281 func init() {
282 keywords = make(map[string]Token)
283 for i := keyword_beg + 1; i < keyword_end; i++ {
284 keywords[tokens[i]] = i
285 }
286 }
287
288
289
290 func Lookup(ident string) Token {
291 if tok, is_keyword := keywords[ident]; is_keyword {
292 return tok
293 }
294 return IDENT
295 }
296
297
298
299
300
301
302 func (tok Token) IsLiteral() bool { return literal_beg < tok && tok < literal_end }
303
304
305
306
307 func (tok Token) IsOperator() bool { return operator_beg < tok && tok < operator_end }
308
309
310
311
312 func (tok Token) IsKeyword() bool { return keyword_beg < tok && tok < keyword_end }
313
314
315
316 func IsExported(name string) bool {
317 ch, _ := utf8.DecodeRuneInString(name)
318 return unicode.IsUpper(ch)
319 }
320
321
322
323 func IsKeyword(name string) bool {
324
325 _, ok := keywords[name]
326 return ok
327 }
328
329
330
331
332
333 func IsIdentifier(name string) bool {
334 for i, c := range name {
335 if !unicode.IsLetter(c) && c != '_' && (i == 0 || !unicode.IsDigit(c)) {
336 return false
337 }
338 }
339 return name != "" && !IsKeyword(name)
340 }
341
View as plain text