Skip to main content

squawk_parser/
lib.rs

1// via https://github.com/rust-lang/rust-analyzer/blob/d8887c0758bbd2d5f752d5bd405d4491e90e7ed6/crates/parser/src/lib.rs
2//
3// Permission is hereby granted, free of charge, to any
4// person obtaining a copy of this software and associated
5// documentation files (the "Software"), to deal in the
6// Software without restriction, including without
7// limitation the rights to use, copy, modify, merge,
8// publish, distribute, sublicense, and/or sell copies of
9// the Software, and to permit persons to whom the Software
10// is furnished to do so, subject to the following
11// conditions:
12//
13// The above copyright notice and this permission notice
14// shall be included in all copies or substantial portions
15// of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25// DEALINGS IN THE SOFTWARE.
26
27use drop_bomb::DropBomb;
28use event::Event;
29use grammar::OPERATOR_FIRST;
30use std::cell::Cell;
31use token_set::TokenSet;
32mod event;
33mod generated;
34mod grammar;
35mod input;
36mod lexed_str;
37mod output;
38mod shortcuts;
39mod syntax_kind;
40mod token_set;
41
42pub use crate::{
43    lexed_str::LexedStr,
44    // output::{Output, Step},
45    shortcuts::StrStep,
46    syntax_kind::SyntaxKind,
47};
48
49use crate::input::Input;
50pub use crate::output::Output;
51
52/// See [`Parser::start`].
53pub(crate) struct Marker {
54    pos: u32,
55    bomb: DropBomb,
56}
57
58impl Marker {
59    fn new(pos: u32) -> Marker {
60        Marker {
61            pos,
62            bomb: DropBomb::new("Marker must be either completed or abandoned"),
63        }
64    }
65
66    /// Finishes the syntax tree node and assigns `kind` to it,
67    /// and mark the create a `CompletedMarker` for possible future
68    /// operation like `.precede()` to deal with `forward_parent`.
69    pub(crate) fn complete(mut self, p: &mut Parser<'_>, kind: SyntaxKind) -> CompletedMarker {
70        self.bomb.defuse();
71        let idx = self.pos as usize;
72        match &mut p.events[idx] {
73            Event::Start { kind: slot, .. } => {
74                *slot = kind;
75            }
76            _ => unreachable!(),
77        }
78        p.push_event(Event::Finish);
79        CompletedMarker::new(self.pos, kind)
80    }
81
82    /// Abandons the syntax tree node. All its children
83    /// are attached to its parent instead.
84    pub(crate) fn abandon(mut self, p: &mut Parser<'_>) {
85        self.bomb.defuse();
86        let idx = self.pos as usize;
87        if idx == p.events.len() - 1 {
88            match p.events.pop() {
89                Some(Event::Start {
90                    kind: SyntaxKind::TOMBSTONE,
91                    forward_parent: None,
92                }) => (),
93                _ => unreachable!(),
94            }
95        }
96    }
97}
98
99pub(crate) struct CompletedMarker {
100    pos: u32,
101    kind: SyntaxKind,
102}
103
104impl CompletedMarker {
105    fn new(pos: u32, kind: SyntaxKind) -> Self {
106        CompletedMarker { pos, kind }
107    }
108
109    /// This method allows to create a new node which starts
110    /// *before* the current one. That is, parser could start
111    /// node `A`, then complete it, and then after parsing the
112    /// whole `A`, decide that it should have started some node
113    /// `B` before starting `A`. `precede` allows to do exactly
114    /// that. See also docs about
115    /// [`Event::Start::forward_parent`](crate::event::Event::Start::forward_parent).
116    ///
117    /// Given completed events `[START, FINISH]` and its corresponding
118    /// `CompletedMarker(pos: 0, _)`.
119    /// Append a new `START` events as `[START, FINISH, NEWSTART]`,
120    /// then mark `NEWSTART` as `START`'s parent with saving its relative
121    /// distance to `NEWSTART` into `forward_parent`(=2 in this case);
122    pub(crate) fn precede(self, p: &mut Parser<'_>) -> Marker {
123        let new_pos = p.start();
124        let idx = self.pos as usize;
125        match &mut p.events[idx] {
126            Event::Start { forward_parent, .. } => {
127                *forward_parent = Some(new_pos.pos - self.pos);
128            }
129            _ => unreachable!(),
130        }
131        new_pos
132    }
133
134    /// Extends this completed marker *to the left* up to `m`.
135    pub(crate) fn extend_to(self, p: &mut Parser<'_>, mut m: Marker) -> CompletedMarker {
136        m.bomb.defuse();
137        let idx = m.pos as usize;
138        match &mut p.events[idx] {
139            Event::Start { forward_parent, .. } => {
140                *forward_parent = Some(self.pos - m.pos);
141            }
142            _ => unreachable!(),
143        }
144        self
145    }
146
147    pub(crate) fn kind(&self) -> SyntaxKind {
148        self.kind
149    }
150}
151
152pub fn parse(input: &Input) -> Output {
153    let mut p = Parser::new(input);
154    // 2. lex tokens to event vec via parser aka actually run the parser code,
155    // it calls the methods on the parser to create a vector of events
156    grammar::entry_point(&mut p);
157    let events = p.finish();
158    // 3. forward parents
159    event::process(events)
160}
161
162pub(crate) struct Parser<'t> {
163    inp: &'t Input,
164    pos: usize,
165    events: Vec<Event>,
166    steps: Cell<u32>,
167}
168
169const PARSER_STEP_LIMIT: usize = 15_000_000;
170
171enum TrivaBetween {
172    NotAllowed,
173    Allowed,
174}
175
176impl<'t> Parser<'t> {
177    fn new(inp: &'t Input) -> Parser<'t> {
178        Parser {
179            inp,
180            pos: 0,
181            events: vec![],
182            steps: Cell::new(0),
183        }
184    }
185
186    /// Consume the next token if `kind` matches.
187    pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool {
188        if !self.at(kind) {
189            return false;
190        }
191        let n_raw_tokens = match kind {
192            SyntaxKind::COLON_EQ
193            | SyntaxKind::NEQ
194            | SyntaxKind::NEQB
195            | SyntaxKind::LTEQ
196            | SyntaxKind::FAT_ARROW
197            | SyntaxKind::GTEQ => 2,
198            SyntaxKind::SIMILAR_TO => {
199                let m = self.start();
200                self.bump(SyntaxKind::SIMILAR_KW);
201                self.bump(SyntaxKind::TO_KW);
202                m.complete(self, SyntaxKind::SIMILAR_TO);
203                return true;
204            }
205            SyntaxKind::AT_TIME_ZONE => {
206                let m = self.start();
207                self.bump(SyntaxKind::AT_KW);
208                self.bump(SyntaxKind::TIME_KW);
209                self.bump(SyntaxKind::ZONE_KW);
210                m.complete(self, SyntaxKind::AT_TIME_ZONE);
211                return true;
212            }
213            SyntaxKind::IS_NOT_NORMALIZED => {
214                let m = self.start();
215                self.bump(SyntaxKind::IS_KW);
216                self.bump(SyntaxKind::NOT_KW);
217                if matches!(
218                    self.current(),
219                    SyntaxKind::NFC_KW
220                        | SyntaxKind::NFD_KW
221                        | SyntaxKind::NFKC_KW
222                        | SyntaxKind::NFKD_KW
223                ) {
224                    let fm = self.start();
225                    self.bump_any();
226                    fm.complete(self, SyntaxKind::UNICODE_NORMAL_FORM);
227                }
228                self.bump(SyntaxKind::NORMALIZED_KW);
229                m.complete(self, SyntaxKind::IS_NOT_NORMALIZED);
230                return true;
231            }
232            SyntaxKind::IS_NORMALIZED => {
233                let m = self.start();
234                self.bump(SyntaxKind::IS_KW);
235                if matches!(
236                    self.current(),
237                    SyntaxKind::NFC_KW
238                        | SyntaxKind::NFD_KW
239                        | SyntaxKind::NFKC_KW
240                        | SyntaxKind::NFKD_KW
241                ) {
242                    let fm = self.start();
243                    self.bump_any();
244                    fm.complete(self, SyntaxKind::UNICODE_NORMAL_FORM);
245                }
246                self.bump(SyntaxKind::NORMALIZED_KW);
247                m.complete(self, SyntaxKind::IS_NORMALIZED);
248                return true;
249            }
250            SyntaxKind::COLON_COLON => {
251                let m = self.start();
252                self.bump(SyntaxKind::COLON);
253                self.bump(SyntaxKind::COLON);
254                m.complete(self, SyntaxKind::COLON_COLON);
255                return true;
256            }
257            SyntaxKind::IS_JSON => {
258                let m = self.start();
259                self.bump(SyntaxKind::IS_KW);
260                self.bump(SyntaxKind::JSON_KW);
261                grammar::opt_json_keys_unique_clause(self);
262                m.complete(self, SyntaxKind::IS_JSON);
263                return true;
264            }
265            SyntaxKind::IS_NOT_JSON => {
266                let m = self.start();
267                self.bump(SyntaxKind::IS_KW);
268                self.bump(SyntaxKind::NOT_KW);
269                self.bump(SyntaxKind::JSON_KW);
270                grammar::opt_json_keys_unique_clause(self);
271                m.complete(self, SyntaxKind::IS_NOT_JSON);
272                return true;
273            }
274            SyntaxKind::IS_NOT_JSON_OBJECT => {
275                let m = self.start();
276                self.bump(SyntaxKind::IS_KW);
277                self.bump(SyntaxKind::NOT_KW);
278                self.bump(SyntaxKind::JSON_KW);
279                self.bump(SyntaxKind::OBJECT_KW);
280                grammar::opt_json_keys_unique_clause(self);
281                m.complete(self, SyntaxKind::IS_NOT_JSON_OBJECT);
282                return true;
283            }
284            SyntaxKind::IS_NOT_JSON_ARRAY => {
285                let m = self.start();
286                self.bump(SyntaxKind::IS_KW);
287                self.bump(SyntaxKind::NOT_KW);
288                self.bump(SyntaxKind::JSON_KW);
289                self.bump(SyntaxKind::ARRAY_KW);
290                grammar::opt_json_keys_unique_clause(self);
291                m.complete(self, SyntaxKind::IS_NOT_JSON_ARRAY);
292                return true;
293            }
294            SyntaxKind::IS_NOT_JSON_VALUE => {
295                let m = self.start();
296                self.bump(SyntaxKind::IS_KW);
297                self.bump(SyntaxKind::NOT_KW);
298                self.bump(SyntaxKind::JSON_KW);
299                self.bump(SyntaxKind::VALUE_KW);
300                grammar::opt_json_keys_unique_clause(self);
301                m.complete(self, SyntaxKind::IS_NOT_JSON_VALUE);
302                return true;
303            }
304            SyntaxKind::IS_NOT_JSON_SCALAR => {
305                let m = self.start();
306                self.bump(SyntaxKind::IS_KW);
307                self.bump(SyntaxKind::NOT_KW);
308                self.bump(SyntaxKind::JSON_KW);
309                self.bump(SyntaxKind::SCALAR_KW);
310                grammar::opt_json_keys_unique_clause(self);
311                m.complete(self, SyntaxKind::IS_NOT_JSON_SCALAR);
312                return true;
313            }
314            SyntaxKind::IS_JSON_OBJECT => {
315                let m = self.start();
316                self.bump(SyntaxKind::IS_KW);
317                self.bump(SyntaxKind::JSON_KW);
318                self.bump(SyntaxKind::OBJECT_KW);
319                grammar::opt_json_keys_unique_clause(self);
320                m.complete(self, SyntaxKind::IS_JSON_OBJECT);
321                return true;
322            }
323            SyntaxKind::IS_JSON_ARRAY => {
324                let m = self.start();
325                self.bump(SyntaxKind::IS_KW);
326                self.bump(SyntaxKind::JSON_KW);
327                self.bump(SyntaxKind::ARRAY_KW);
328                grammar::opt_json_keys_unique_clause(self);
329                m.complete(self, SyntaxKind::IS_JSON_ARRAY);
330                return true;
331            }
332            SyntaxKind::IS_JSON_VALUE => {
333                let m = self.start();
334                self.bump(SyntaxKind::IS_KW);
335                self.bump(SyntaxKind::JSON_KW);
336                self.bump(SyntaxKind::VALUE_KW);
337                grammar::opt_json_keys_unique_clause(self);
338                m.complete(self, SyntaxKind::IS_JSON_VALUE);
339                return true;
340            }
341            SyntaxKind::IS_JSON_SCALAR => {
342                let m = self.start();
343                self.bump(SyntaxKind::IS_KW);
344                self.bump(SyntaxKind::JSON_KW);
345                self.bump(SyntaxKind::SCALAR_KW);
346                grammar::opt_json_keys_unique_clause(self);
347                m.complete(self, SyntaxKind::IS_JSON_SCALAR);
348                return true;
349            }
350            SyntaxKind::NOT_SIMILAR_TO => {
351                let m = self.start();
352                self.bump(SyntaxKind::NOT_KW);
353                self.bump(SyntaxKind::SIMILAR_KW);
354                self.bump(SyntaxKind::TO_KW);
355                m.complete(self, SyntaxKind::NOT_SIMILAR_TO);
356                return true;
357            }
358            SyntaxKind::IS_NOT_DISTINCT_FROM => {
359                let m = self.start();
360                self.bump(SyntaxKind::IS_KW);
361                self.bump(SyntaxKind::NOT_KW);
362                self.bump(SyntaxKind::DISTINCT_KW);
363                self.bump(SyntaxKind::FROM_KW);
364                m.complete(self, SyntaxKind::IS_NOT_DISTINCT_FROM);
365                return true;
366            }
367            SyntaxKind::OPERATOR_CALL => {
368                let m = self.start();
369                self.bump(SyntaxKind::OPERATOR_KW);
370                self.bump(SyntaxKind::L_PAREN);
371
372                // database.
373                if self.eat(SyntaxKind::IDENT) {
374                    self.expect(SyntaxKind::DOT);
375                }
376                // schema.
377                if self.eat(SyntaxKind::IDENT) {
378                    self.expect(SyntaxKind::DOT);
379                }
380
381                // +, -, etc.
382                match grammar::current_operator(self) {
383                    Some(kind) => {
384                        self.bump(kind);
385                    }
386                    None => {
387                        self.error("expected operator");
388                    }
389                }
390
391                self.expect(SyntaxKind::R_PAREN);
392                m.complete(self, SyntaxKind::OPERATOR_CALL);
393                return true;
394            }
395            SyntaxKind::IS_DISTINCT_FROM => {
396                let m = self.start();
397                self.bump(SyntaxKind::IS_KW);
398                self.bump(SyntaxKind::DISTINCT_KW);
399                self.bump(SyntaxKind::FROM_KW);
400                m.complete(self, SyntaxKind::IS_DISTINCT_FROM);
401                return true;
402            }
403            SyntaxKind::NOT_LIKE => {
404                let m = self.start();
405                self.bump(SyntaxKind::NOT_KW);
406                self.bump(SyntaxKind::LIKE_KW);
407                m.complete(self, SyntaxKind::NOT_LIKE);
408                return true;
409            }
410            SyntaxKind::NOT_ILIKE => {
411                let m = self.start();
412                self.bump(SyntaxKind::NOT_KW);
413                self.bump(SyntaxKind::ILIKE_KW);
414                m.complete(self, SyntaxKind::NOT_ILIKE);
415                return true;
416            }
417            SyntaxKind::NOT_IN => {
418                let m = self.start();
419                self.bump(SyntaxKind::NOT_KW);
420                self.bump(SyntaxKind::IN_KW);
421                m.complete(self, SyntaxKind::NOT_IN);
422                return true;
423            }
424            SyntaxKind::IS_NOT => {
425                let m = self.start();
426                self.bump(SyntaxKind::IS_KW);
427                self.bump(SyntaxKind::NOT_KW);
428                m.complete(self, SyntaxKind::IS_NOT);
429                return true;
430            }
431            SyntaxKind::CUSTOM_OP => {
432                let m = self.start();
433                while !self.at(SyntaxKind::EOF) {
434                    let is_joint = self.inp.is_joint(self.pos);
435                    if self.at_ts(OPERATOR_FIRST) {
436                        self.bump_any();
437                    } else {
438                        break;
439                    }
440                    if !is_joint {
441                        break;
442                    }
443                }
444                m.complete(self, SyntaxKind::CUSTOM_OP);
445                return true;
446            }
447            _ => 1,
448        };
449        self.do_bump(kind, n_raw_tokens);
450        true
451    }
452
453    fn at_composite2(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind, triva: TrivaBetween) -> bool {
454        let tokens_match =
455            self.inp.kind(self.pos + n) == k1 && self.inp.kind(self.pos + n + 1) == k2;
456        // We need to do this so we can say that:
457        // 1 > > 2, is not the same as 1 >> 2
458        match triva {
459            TrivaBetween::Allowed => tokens_match,
460            TrivaBetween::NotAllowed => {
461                return tokens_match
462                    && self.inp.is_joint(self.pos + n)
463                    && self.next_not_joined_op(n + 1);
464            }
465        }
466    }
467
468    fn at_composite3(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind, k3: SyntaxKind) -> bool {
469        self.inp.kind(self.pos + n) == k1
470            && self.inp.kind(self.pos + n + 1) == k2
471            && self.inp.kind(self.pos + n + 2) == k3
472    }
473
474    fn at_composite4(
475        &self,
476        n: usize,
477        k1: SyntaxKind,
478        k2: SyntaxKind,
479        k3: SyntaxKind,
480        k4: SyntaxKind,
481    ) -> bool {
482        self.inp.kind(self.pos + n) == k1
483            && self.inp.kind(self.pos + n + 1) == k2
484            && self.inp.kind(self.pos + n + 2) == k3
485            && self.inp.kind(self.pos + n + 3) == k4
486    }
487
488    fn next_not_joined_op(&self, n: usize) -> bool {
489        let next = self.inp.kind(self.pos + n + 1);
490        // next isn't an operator so we know we're not joined to it
491        if !OPERATOR_FIRST.contains(next) {
492            return true;
493        }
494        // current kind isn't joined
495        if !self.inp.is_joint(self.pos + n) {
496            return true;
497        }
498        false
499    }
500
501    /// Checks if the current token is in `kinds`.
502    pub(crate) fn at_ts(&self, kinds: TokenSet) -> bool {
503        kinds.contains(self.current())
504    }
505
506    /// Starts a new node in the syntax tree. All nodes and tokens
507    /// consumed between the `start` and the corresponding `Marker::complete`
508    /// belong to the same node.
509    pub(crate) fn start(&mut self) -> Marker {
510        let pos = self.events.len() as u32;
511        self.push_event(Event::tombstone());
512        Marker::new(pos)
513    }
514
515    /// Consume the next token. Panics if the parser isn't currently at `kind`.
516    pub(crate) fn bump(&mut self, kind: SyntaxKind) {
517        assert!(self.eat(kind));
518    }
519
520    /// Advances the parser by one token
521    pub(crate) fn bump_any(&mut self) {
522        let kind = self.nth(0);
523        if kind == SyntaxKind::EOF {
524            return;
525        }
526        self.do_bump(kind, 1);
527    }
528
529    /// Advances the parser by one token
530    pub(crate) fn split_float(&mut self, mut marker: Marker) -> (bool, Marker) {
531        assert!(self.at(SyntaxKind::FLOAT_NUMBER));
532        // we have parse `<something>.`
533        // `<something>`.0.1
534        // here we need to insert an extra event
535        //
536        // `<something>`. 0. 1;
537        // here we need to change the follow up parse, the return value will cause us to emulate a dot
538        // the actual splitting happens later
539        let ends_in_dot = !self.inp.is_joint(self.pos);
540        if !ends_in_dot {
541            let new_marker = self.start();
542            let idx = marker.pos as usize;
543            match &mut self.events[idx] {
544                Event::Start {
545                    forward_parent,
546                    kind,
547                } => {
548                    *kind = SyntaxKind::FIELD_EXPR;
549                    *forward_parent = Some(new_marker.pos - marker.pos);
550                }
551                _ => unreachable!(),
552            }
553            marker.bomb.defuse();
554            marker = new_marker;
555        };
556        self.pos += 1;
557        self.push_event(Event::FloatSplitHack { ends_in_dot });
558        (ends_in_dot, marker)
559    }
560
561    /// Consume the next token if it is `kind` or emit an error
562    /// otherwise.
563    pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
564        if self.eat(kind) {
565            return true;
566        }
567        self.error(format!("expected {kind:?}"));
568        false
569    }
570
571    /// Create an error node and consume the next token.
572    pub(crate) fn err_and_bump(&mut self, message: &str) {
573        self.err_recover(message, TokenSet::EMPTY);
574    }
575
576    /// Create an error node and consume the next token.
577    pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
578        // TODO: maybe we actually want this?
579        // if matches!(self.current(), SyntaxKind::L_PAREN | SyntaxKind::R_PAREN) {
580        //     self.error(message);
581        //     return;
582        // }
583
584        if self.at_ts(recovery) {
585            self.error(message);
586            return;
587        }
588
589        let m = self.start();
590        self.error(message);
591        self.bump_any();
592        m.complete(self, SyntaxKind::ERROR);
593    }
594
595    fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
596        self.pos += n_raw_tokens as usize;
597        self.steps.set(0);
598        self.push_event(Event::Token { kind, n_raw_tokens });
599    }
600
601    fn push_event(&mut self, event: Event) {
602        self.events.push(event);
603    }
604
605    fn finish(self) -> Vec<Event> {
606        self.events
607    }
608
609    /// Emit error with the `message`
610    /// FIXME: this should be much more fancy and support
611    /// structured errors with spans and notes, like rustc
612    /// does.
613    pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
614        let msg = message.into();
615        self.push_event(Event::Error { msg });
616    }
617
618    /// Checks if the current token is `kind`.
619    #[must_use]
620    pub(crate) fn at(&self, kind: SyntaxKind) -> bool {
621        self.nth_at(0, kind)
622    }
623
624    /// Checks if the nth token is in `kinds`.
625    #[must_use]
626    pub(crate) fn nth_at_ts(&self, n: usize, kinds: TokenSet) -> bool {
627        kinds.contains(self.nth(n))
628    }
629
630    #[must_use]
631    pub(crate) fn nth_at(&self, n: usize, kind: SyntaxKind) -> bool {
632        match kind {
633            // =>
634            SyntaxKind::FAT_ARROW => self.at_composite2(
635                n,
636                SyntaxKind::EQ,
637                SyntaxKind::R_ANGLE,
638                TrivaBetween::NotAllowed,
639            ),
640            // :=
641            SyntaxKind::COLON_EQ => self.at_composite2(
642                n,
643                SyntaxKind::COLON,
644                SyntaxKind::EQ,
645                TrivaBetween::NotAllowed,
646            ),
647            // ::
648            SyntaxKind::COLON_COLON => self.at_composite2(
649                n,
650                SyntaxKind::COLON,
651                SyntaxKind::COLON,
652                TrivaBetween::NotAllowed,
653            ),
654            // !=
655            SyntaxKind::NEQ => self.at_composite2(
656                n,
657                SyntaxKind::BANG,
658                SyntaxKind::EQ,
659                TrivaBetween::NotAllowed,
660            ),
661            // <>
662            SyntaxKind::NEQB => self.at_composite2(
663                n,
664                SyntaxKind::L_ANGLE,
665                SyntaxKind::R_ANGLE,
666                TrivaBetween::NotAllowed,
667            ),
668            // is not
669            SyntaxKind::IS_NOT => self.at_composite2(
670                n,
671                SyntaxKind::IS_KW,
672                SyntaxKind::NOT_KW,
673                TrivaBetween::Allowed,
674            ),
675            // not like
676            SyntaxKind::NOT_LIKE => self.at_composite2(
677                n,
678                SyntaxKind::NOT_KW,
679                SyntaxKind::LIKE_KW,
680                TrivaBetween::Allowed,
681            ),
682            // not ilike
683            SyntaxKind::NOT_ILIKE => self.at_composite2(
684                n,
685                SyntaxKind::NOT_KW,
686                SyntaxKind::ILIKE_KW,
687                TrivaBetween::Allowed,
688            ),
689            // not in
690            SyntaxKind::NOT_IN => self.at_composite2(
691                n,
692                SyntaxKind::NOT_KW,
693                SyntaxKind::IN_KW,
694                TrivaBetween::Allowed,
695            ),
696            // at time zone
697            SyntaxKind::AT_TIME_ZONE => self.at_composite3(
698                n,
699                SyntaxKind::AT_KW,
700                SyntaxKind::TIME_KW,
701                SyntaxKind::ZONE_KW,
702            ),
703            // is distinct from
704            SyntaxKind::IS_DISTINCT_FROM => self.at_composite3(
705                n,
706                SyntaxKind::IS_KW,
707                SyntaxKind::DISTINCT_KW,
708                SyntaxKind::FROM_KW,
709            ),
710            // is not distinct from
711            SyntaxKind::IS_NOT_DISTINCT_FROM => self.at_composite4(
712                n,
713                SyntaxKind::IS_KW,
714                SyntaxKind::NOT_KW,
715                SyntaxKind::DISTINCT_KW,
716                SyntaxKind::FROM_KW,
717            ),
718            // is normalized
719            SyntaxKind::IS_NORMALIZED => {
720                if self.at(SyntaxKind::IS_KW) {
721                    if matches!(
722                        self.nth(1),
723                        SyntaxKind::NFC_KW
724                            | SyntaxKind::NFD_KW
725                            | SyntaxKind::NFKC_KW
726                            | SyntaxKind::NFKD_KW
727                    ) {
728                        if self.nth_at(2, SyntaxKind::NORMALIZED_KW) {
729                            return true;
730                        }
731                    } else {
732                        if self.nth_at(1, SyntaxKind::NORMALIZED_KW) {
733                            return true;
734                        }
735                    }
736                }
737                return false;
738            }
739            // is not normalized
740            SyntaxKind::IS_NOT_NORMALIZED => {
741                if self.at(SyntaxKind::IS_KW) && self.nth_at(1, SyntaxKind::NOT_KW) {
742                    if matches!(
743                        self.nth(2),
744                        SyntaxKind::NFC_KW
745                            | SyntaxKind::NFD_KW
746                            | SyntaxKind::NFKC_KW
747                            | SyntaxKind::NFKD_KW
748                    ) {
749                        if self.nth_at(3, SyntaxKind::NORMALIZED_KW) {
750                            return true;
751                        }
752                    } else if self.nth_at(2, SyntaxKind::NORMALIZED_KW) {
753                        return true;
754                    }
755                }
756                return false;
757            }
758            SyntaxKind::NOT_SIMILAR_TO => self.at_composite3(
759                n,
760                SyntaxKind::NOT_KW,
761                SyntaxKind::SIMILAR_KW,
762                SyntaxKind::TO_KW,
763            ),
764            // similar to
765            SyntaxKind::SIMILAR_TO => self.at_composite2(
766                n,
767                SyntaxKind::SIMILAR_KW,
768                SyntaxKind::TO_KW,
769                TrivaBetween::Allowed,
770            ),
771            // https://www.postgresql.org/docs/17/sql-expressions.html#SQL-EXPRESSIONS-OPERATOR-CALLS
772            // TODO: is this right?
773            SyntaxKind::OPERATOR_CALL => self.at_composite2(
774                n,
775                SyntaxKind::OPERATOR_KW,
776                SyntaxKind::L_PAREN,
777                TrivaBetween::Allowed,
778            ),
779            // is json
780            SyntaxKind::IS_JSON => self.at_composite2(
781                n,
782                SyntaxKind::IS_KW,
783                SyntaxKind::JSON_KW,
784                TrivaBetween::Allowed,
785            ),
786            // is not json
787            SyntaxKind::IS_NOT_JSON => self.at_composite3(
788                n,
789                SyntaxKind::IS_KW,
790                SyntaxKind::NOT_KW,
791                SyntaxKind::JSON_KW,
792            ),
793            // is not json object
794            SyntaxKind::IS_NOT_JSON_OBJECT => self.at_composite4(
795                n,
796                SyntaxKind::IS_KW,
797                SyntaxKind::NOT_KW,
798                SyntaxKind::JSON_KW,
799                SyntaxKind::OBJECT_KW,
800            ),
801            // is not json array
802            SyntaxKind::IS_NOT_JSON_ARRAY => self.at_composite4(
803                n,
804                SyntaxKind::IS_KW,
805                SyntaxKind::NOT_KW,
806                SyntaxKind::JSON_KW,
807                SyntaxKind::ARRAY_KW,
808            ),
809            // is not json value
810            SyntaxKind::IS_NOT_JSON_VALUE => self.at_composite4(
811                n,
812                SyntaxKind::IS_KW,
813                SyntaxKind::NOT_KW,
814                SyntaxKind::JSON_KW,
815                SyntaxKind::VALUE_KW,
816            ),
817            // is not json scalar
818            SyntaxKind::IS_NOT_JSON_SCALAR => self.at_composite4(
819                n,
820                SyntaxKind::IS_KW,
821                SyntaxKind::NOT_KW,
822                SyntaxKind::JSON_KW,
823                SyntaxKind::SCALAR_KW,
824            ),
825            // is json object
826            SyntaxKind::IS_JSON_OBJECT => self.at_composite3(
827                n,
828                SyntaxKind::IS_KW,
829                SyntaxKind::JSON_KW,
830                SyntaxKind::OBJECT_KW,
831            ),
832            // is json array
833            SyntaxKind::IS_JSON_ARRAY => self.at_composite3(
834                n,
835                SyntaxKind::IS_KW,
836                SyntaxKind::JSON_KW,
837                SyntaxKind::ARRAY_KW,
838            ),
839            // is json value
840            SyntaxKind::IS_JSON_VALUE => self.at_composite3(
841                n,
842                SyntaxKind::IS_KW,
843                SyntaxKind::JSON_KW,
844                SyntaxKind::VALUE_KW,
845            ),
846            // is json scalar
847            SyntaxKind::IS_JSON_SCALAR => self.at_composite3(
848                n,
849                SyntaxKind::IS_KW,
850                SyntaxKind::JSON_KW,
851                SyntaxKind::SCALAR_KW,
852            ),
853            // <=
854            SyntaxKind::LTEQ => self.at_composite2(
855                n,
856                SyntaxKind::L_ANGLE,
857                SyntaxKind::EQ,
858                TrivaBetween::NotAllowed,
859            ),
860            // <=
861            SyntaxKind::GTEQ => self.at_composite2(
862                n,
863                SyntaxKind::R_ANGLE,
864                SyntaxKind::EQ,
865                TrivaBetween::NotAllowed,
866            ),
867            SyntaxKind::CUSTOM_OP => {
868                // TODO: is this right?
869                if self.at_ts(OPERATOR_FIRST) {
870                    return true;
871                }
872                return false;
873            }
874            // TODO: we probably shouldn't be using a _ for this but be explicit for each type?
875            _ => self.inp.kind(self.pos + n) == kind,
876        }
877    }
878
879    /// Returns the kind of the current token.
880    /// If parser has already reached the end of input,
881    /// the special `EOF` kind is returned.
882    #[must_use]
883    pub(crate) fn current(&self) -> SyntaxKind {
884        self.nth(0)
885    }
886
887    /// Lookahead operation: returns the kind of the next nth
888    /// token.
889    #[must_use]
890    fn nth(&self, n: usize) -> SyntaxKind {
891        assert!(n <= 3);
892
893        let steps = self.steps.get();
894        assert!(
895            (steps as usize) < PARSER_STEP_LIMIT,
896            "the parser seems stuck"
897        );
898        self.steps.set(steps + 1);
899
900        self.inp.kind(self.pos + n)
901    }
902}