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