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