gitql_parser/
token.rs

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    // Values
72    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    // Reserved keywords
127    "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    // Select into
160    "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    // Joins
169    "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    // Grouping
177    "group" => TokenKind::Group,
178    "by" => TokenKind::By,
179    "having" => TokenKind::Having,
180    "with" => TokenKind::With,
181    "rollup" => TokenKind::Rollup,
182
183    // Between kind
184    "symmetric" => TokenKind::Symmetric,
185    "asymmetric" => TokenKind::Asymmetric,
186
187    // Integer division and Modulo operator
188    "div" => TokenKind::Slash,
189    "mod" => TokenKind::Percentage,
190
191    // Logical Operators
192    "or" => TokenKind::OrKeyword,
193    "and" => TokenKind::AndKeyword,
194    "xor" => TokenKind::XorKeyword,
195
196    // Group Operators
197    "all" => TokenKind::All,
198    "some" => TokenKind::Some,
199    "any" => TokenKind::Any,
200
201    "row" => TokenKind::Row,
202
203    // True, False and Null
204    "true" => TokenKind::True,
205    "false" => TokenKind::False,
206    "null" => TokenKind::Null,
207    "nulls" => TokenKind::Nulls,
208
209    // Infinity and NaN
210    "infinity" => TokenKind::Infinity,
211    "inf" => TokenKind::Infinity,
212    "nan" => TokenKind::NaN,
213
214    // As for alias
215    "as" => TokenKind::As,
216
217    // Order by DES and ASC
218    "asc" => TokenKind::Ascending,
219     "desc" => TokenKind::Descending,
220
221    // Order by null ordering policy Null first and last
222    "first" => TokenKind::First,
223    "last" => TokenKind::Last,
224
225    // Array data type
226    "array" => TokenKind::Array,
227
228    // Over
229    "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            // Reserved Keywords
238            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            // Values
302            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            // Group Operators
315            TokenKind::All => "ALL",
316            TokenKind::Some => "Some",
317            TokenKind::Any => "Any",
318
319            // Others
320            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}