1use std::fmt::Display;
2use std::fmt::Formatter;
3use std::fmt::Result;
4
5#[derive(PartialEq)]
6pub enum TokenKind {
7 Do,
8 Set,
9 Select,
10 Distinct,
11 From,
12 Group,
13 Where,
14 Having,
15 Qualify,
16 Limit,
17 Offset,
18 Order,
19 Using,
20 Like,
21 Glob,
22 Describe,
23 Show,
24 RegExp,
25 Array,
26 Cast,
27 Benchmark,
28 Join,
29 Left,
30 Right,
31 Cross,
32 Inner,
33 Outer,
34 Case,
35 When,
36 Then,
37 Else,
38 End,
39 Into,
40 Outfile,
41 Dumpfile,
42 Lines,
43 Fields,
44 Enclosed,
45 Terminated,
46 Between,
47 By,
48 In,
49 Is,
50 On,
51 Not,
52 As,
53 With,
54 Rollup,
55 OrKeyword,
56 AndKeyword,
57 XorKeyword,
58 Ascending,
59 Descending,
60 Symmetric,
61 Asymmetric,
62 Window,
63 Over,
64 Partition,
65 First,
66 Last,
67 Interval,
68
69 Row,
71 Symbol(String),
72 GlobalVariable(String),
73 String(String),
74 Integer(i64),
75 Float(f64),
76 True,
77 False,
78 Null,
79 Nulls,
80 Infinity,
81 NaN,
82
83 All,
84 Some,
85 Any,
86
87 Greater,
88 GreaterEqual,
89 Less,
90 LessEqual,
91 Equal,
92 Bang,
93 BangEqual,
94 NullSafeEqual,
95 AtRightArrow,
96 ArrowRightAt,
97 LeftParen,
98 RightParen,
99 LeftBracket,
100 RightBracket,
101 OrOr,
102 AndAnd,
103 BitwiseNot,
104 BitwiseXor,
105 BitwiseOr,
106 BitwiseAnd,
107 BitwiseRightShift,
108 BitwiseLeftShift,
109 Colon,
110 ColonColon,
111 ColonEqual,
112 Plus,
113 Minus,
114 Star,
115 Slash,
116 Percentage,
117 Caret,
118 Comma,
119 Dot,
120 Semicolon,
121}
122
123impl Display for TokenKind {
124 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
125 let literal = match self {
126 TokenKind::Do => "DO",
128 TokenKind::Set => "SET",
129 TokenKind::Select => "SELECT",
130 TokenKind::Distinct => "DISTINCT",
131 TokenKind::From => "FROM",
132 TokenKind::Group => "GROUP",
133 TokenKind::Where => "WHERE",
134 TokenKind::Having => "HAVING",
135 TokenKind::Qualify => "QUALIFY",
136 TokenKind::Limit => "LIMIT",
137 TokenKind::Offset => "OFFSET",
138 TokenKind::Order => "ORDER",
139 TokenKind::Using => "USING",
140 TokenKind::Like => "LIKE",
141 TokenKind::Glob => "GLOB",
142 TokenKind::Describe => "DESCRIBE",
143 TokenKind::Show => "SHOW",
144 TokenKind::RegExp => "REGEXP",
145 TokenKind::Array => "ARRAY",
146 TokenKind::Cast => "CAST",
147 TokenKind::Benchmark => "BENCHMARK",
148 TokenKind::Join => "JOIN",
149 TokenKind::Left => "LEFT",
150 TokenKind::Right => "RIGHT",
151 TokenKind::Cross => "CROSS",
152 TokenKind::Inner => "INNER",
153 TokenKind::Outer => "OUTER",
154 TokenKind::Case => "CASE",
155 TokenKind::When => "WHEN",
156 TokenKind::Then => "THEN",
157 TokenKind::Else => "ELSE",
158 TokenKind::End => "END",
159 TokenKind::Into => "INTO",
160 TokenKind::Outfile => "OUTFILE",
161 TokenKind::Dumpfile => "DUMPFILE",
162 TokenKind::Lines => "LINES",
163 TokenKind::Fields => "FIELDS",
164 TokenKind::Enclosed => "ENCLOSED",
165 TokenKind::Terminated => "TERMINATED",
166 TokenKind::Between => "BETWEEN",
167 TokenKind::By => "BY",
168 TokenKind::In => "IN",
169 TokenKind::Is => "IS",
170 TokenKind::On => "ON",
171 TokenKind::Not => "NOT",
172 TokenKind::As => "AS",
173 TokenKind::With => "WITH",
174 TokenKind::Rollup => "ROLLUP",
175 TokenKind::OrKeyword => "OR",
176 TokenKind::AndKeyword => "AND",
177 TokenKind::XorKeyword => "XOE",
178 TokenKind::Ascending => "ASC",
179 TokenKind::Descending => "DESC",
180 TokenKind::Symmetric => "SYMMETRIC",
181 TokenKind::Asymmetric => "ASYMMETRIC",
182 TokenKind::Window => "WINDOW",
183 TokenKind::Over => "OVER",
184 TokenKind::Partition => "PARTITION",
185 TokenKind::Nulls => "NULLS",
186 TokenKind::First => "FIRST",
187 TokenKind::Last => "LAST",
188 TokenKind::Interval => "INTERVAL",
189
190 TokenKind::Row => "Row",
192 TokenKind::Symbol(literal) => literal,
193 TokenKind::GlobalVariable(literal) => literal,
194 TokenKind::String(string) => string,
195 TokenKind::Integer(integer) => &integer.to_string(),
196 TokenKind::Float(float) => &float.to_string(),
197 TokenKind::True => "True",
198 TokenKind::False => "False",
199 TokenKind::Null => "Null",
200 TokenKind::Infinity => "Infinity",
201 TokenKind::NaN => "NaN",
202
203 TokenKind::All => "ALL",
205 TokenKind::Some => "Some",
206 TokenKind::Any => "Any",
207
208 TokenKind::Greater => ">",
210 TokenKind::GreaterEqual => ">=",
211 TokenKind::Less => "<",
212 TokenKind::LessEqual => "<=",
213 TokenKind::Equal => "=",
214 TokenKind::Bang => "!",
215 TokenKind::BangEqual => "!=",
216 TokenKind::NullSafeEqual => "<=>",
217 TokenKind::AtRightArrow => "@>",
218 TokenKind::ArrowRightAt => "<@",
219 TokenKind::LeftParen => "(",
220 TokenKind::RightParen => ")",
221 TokenKind::LeftBracket => "[",
222 TokenKind::RightBracket => "]",
223 TokenKind::OrOr => "||",
224 TokenKind::AndAnd => "&&",
225 TokenKind::BitwiseNot => "~",
226 TokenKind::BitwiseXor => "#",
227 TokenKind::BitwiseOr => "|",
228 TokenKind::BitwiseAnd => "&",
229 TokenKind::BitwiseRightShift => ">>",
230 TokenKind::BitwiseLeftShift => "<<",
231 TokenKind::Colon => ":",
232 TokenKind::ColonColon => "::",
233 TokenKind::ColonEqual => ":=",
234 TokenKind::Plus => "+",
235 TokenKind::Minus => "-",
236 TokenKind::Star => "*",
237 TokenKind::Slash => "/",
238 TokenKind::Percentage => "%",
239 TokenKind::Caret => "^",
240 TokenKind::Comma => ",",
241 TokenKind::Dot => ".",
242 TokenKind::Semicolon => ";",
243 };
244 f.write_str(literal)
245 }
246}
247
248#[derive(Copy, Clone)]
249pub struct SourceLocation {
250 pub line_start: u32,
251 pub line_end: u32,
252 pub column_start: u32,
253 pub column_end: u32,
254}
255
256impl SourceLocation {
257 pub fn new(
258 line_start: u32,
259 line_end: u32,
260 column_start: u32,
261 column_end: u32,
262 ) -> SourceLocation {
263 SourceLocation {
264 line_start,
265 line_end,
266 column_start,
267 column_end,
268 }
269 }
270
271 pub fn expand_until(&mut self, location: SourceLocation) {
272 self.column_end = location.column_end;
273 self.line_end = location.line_end;
274 }
275}
276
277impl Display for SourceLocation {
278 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
279 f.write_fmt(format_args!(
280 "Loc(L {}:{}, C {}:{})",
281 self.line_start, self.line_end, self.column_start, self.column_end
282 ))
283 }
284}
285
286pub struct Token {
287 pub kind: TokenKind,
288 pub location: SourceLocation,
289}
290
291impl Token {
292 pub fn new(kind: TokenKind, location: SourceLocation) -> Token {
293 Token { kind, location }
294 }
295
296 pub fn new_symbol(symbol: String, location: SourceLocation) -> Token {
297 Token {
298 kind: resolve_symbol_kind(symbol),
299 location,
300 }
301 }
302
303 pub fn has_kind(&self, kind: TokenKind) -> bool {
304 self.kind == kind
305 }
306}
307
308impl Display for Token {
309 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
310 f.write_str(&self.kind.to_string())
311 }
312}
313
314fn resolve_symbol_kind(symbol: String) -> TokenKind {
315 match symbol.to_lowercase().as_str() {
316 "do" => TokenKind::Do,
318 "set" => TokenKind::Set,
319 "select" => TokenKind::Select,
320 "distinct" => TokenKind::Distinct,
321 "from" => TokenKind::From,
322 "where" => TokenKind::Where,
323 "qualify" => TokenKind::Qualify,
324 "limit" => TokenKind::Limit,
325 "offset" => TokenKind::Offset,
326 "order" => TokenKind::Order,
327 "using" => TokenKind::Using,
328 "case" => TokenKind::Case,
329 "when" => TokenKind::When,
330 "then" => TokenKind::Then,
331 "else" => TokenKind::Else,
332 "end" => TokenKind::End,
333 "between" => TokenKind::Between,
334 "in" => TokenKind::In,
335 "is" => TokenKind::Is,
336 "on" => TokenKind::On,
337 "not" => TokenKind::Not,
338 "like" => TokenKind::Like,
339 "glob" => TokenKind::Glob,
340 "describe" => TokenKind::Describe,
341 "show" => TokenKind::Show,
342 "regexp" => TokenKind::RegExp,
343
344 "cast" => TokenKind::Cast,
345 "benchmark" => TokenKind::Benchmark,
346
347 "interval" => TokenKind::Interval,
348
349 "into" => TokenKind::Into,
351 "outfile" => TokenKind::Outfile,
352 "dumpfile" => TokenKind::Dumpfile,
353 "lines" => TokenKind::Lines,
354 "fields" => TokenKind::Fields,
355 "enclosed" => TokenKind::Enclosed,
356 "terminated" => TokenKind::Terminated,
357
358 "join" => TokenKind::Join,
360 "left" => TokenKind::Left,
361 "right" => TokenKind::Right,
362 "cross" => TokenKind::Cross,
363 "inner" => TokenKind::Inner,
364 "outer" => TokenKind::Outer,
365
366 "group" => TokenKind::Group,
368 "by" => TokenKind::By,
369 "having" => TokenKind::Having,
370 "with" => TokenKind::With,
371 "rollup" => TokenKind::Rollup,
372
373 "symmetric" => TokenKind::Symmetric,
375 "asymmetric" => TokenKind::Asymmetric,
376
377 "div" => TokenKind::Slash,
379 "mod" => TokenKind::Percentage,
380
381 "or" => TokenKind::OrKeyword,
383 "and" => TokenKind::AndKeyword,
384 "xor" => TokenKind::XorKeyword,
385
386 "all" => TokenKind::All,
388 "some" => TokenKind::Some,
389 "any" => TokenKind::Any,
390
391 "row" => TokenKind::Row,
392
393 "true" => TokenKind::True,
395 "false" => TokenKind::False,
396 "null" => TokenKind::Null,
397 "nulls" => TokenKind::Nulls,
398
399 "infinity" => TokenKind::Infinity,
401 "inf" => TokenKind::Infinity,
402 "nan" => TokenKind::NaN,
403
404 "as" => TokenKind::As,
406
407 "asc" => TokenKind::Ascending,
409 "desc" => TokenKind::Descending,
410
411 "first" => TokenKind::First,
413 "last" => TokenKind::Last,
414
415 "array" => TokenKind::Array,
417
418 "window" => TokenKind::Window,
420 "over" => TokenKind::Over,
421 "partition" => TokenKind::Partition,
422
423 _ => TokenKind::Symbol(symbol),
425 }
426}