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                    self.bump_any();
225                }
226                self.bump(SyntaxKind::NORMALIZED_KW);
227                m.complete(self, SyntaxKind::IS_NOT_NORMALIZED);
228                return true;
229            }
230            SyntaxKind::IS_NORMALIZED => {
231                let m = self.start();
232                self.bump(SyntaxKind::IS_KW);
233                if matches!(
234                    self.current(),
235                    SyntaxKind::NFC_KW
236                        | SyntaxKind::NFD_KW
237                        | SyntaxKind::NFKC_KW
238                        | SyntaxKind::NFKD_KW
239                ) {
240                    self.bump_any();
241                }
242                self.bump(SyntaxKind::NORMALIZED_KW);
243                m.complete(self, SyntaxKind::IS_NORMALIZED);
244                return true;
245            }
246            SyntaxKind::COLON_COLON => {
247                let m = self.start();
248                self.bump(SyntaxKind::COLON);
249                self.bump(SyntaxKind::COLON);
250                m.complete(self, SyntaxKind::COLON_COLON);
251                return true;
252            }
253            SyntaxKind::IS_JSON => {
254                let m = self.start();
255                self.bump(SyntaxKind::IS_KW);
256                self.bump(SyntaxKind::JSON_KW);
257                grammar::opt_json_keys_unique_clause(self);
258                m.complete(self, SyntaxKind::IS_JSON);
259                return true;
260            }
261            SyntaxKind::IS_NOT_JSON => {
262                let m = self.start();
263                self.bump(SyntaxKind::IS_KW);
264                self.bump(SyntaxKind::NOT_KW);
265                self.bump(SyntaxKind::JSON_KW);
266                grammar::opt_json_keys_unique_clause(self);
267                m.complete(self, SyntaxKind::IS_NOT_JSON);
268                return true;
269            }
270            SyntaxKind::IS_NOT_JSON_OBJECT => {
271                let m = self.start();
272                self.bump(SyntaxKind::IS_KW);
273                self.bump(SyntaxKind::NOT_KW);
274                self.bump(SyntaxKind::JSON_KW);
275                self.bump(SyntaxKind::OBJECT_KW);
276                grammar::opt_json_keys_unique_clause(self);
277                m.complete(self, SyntaxKind::IS_NOT_JSON_OBJECT);
278                return true;
279            }
280            SyntaxKind::IS_NOT_JSON_ARRAY => {
281                let m = self.start();
282                self.bump(SyntaxKind::IS_KW);
283                self.bump(SyntaxKind::NOT_KW);
284                self.bump(SyntaxKind::JSON_KW);
285                self.bump(SyntaxKind::ARRAY_KW);
286                grammar::opt_json_keys_unique_clause(self);
287                m.complete(self, SyntaxKind::IS_NOT_JSON_ARRAY);
288                return true;
289            }
290            SyntaxKind::IS_NOT_JSON_VALUE => {
291                let m = self.start();
292                self.bump(SyntaxKind::IS_KW);
293                self.bump(SyntaxKind::NOT_KW);
294                self.bump(SyntaxKind::JSON_KW);
295                self.bump(SyntaxKind::VALUE_KW);
296                grammar::opt_json_keys_unique_clause(self);
297                m.complete(self, SyntaxKind::IS_NOT_JSON_VALUE);
298                return true;
299            }
300            SyntaxKind::IS_NOT_JSON_SCALAR => {
301                let m = self.start();
302                self.bump(SyntaxKind::IS_KW);
303                self.bump(SyntaxKind::NOT_KW);
304                self.bump(SyntaxKind::JSON_KW);
305                self.bump(SyntaxKind::SCALAR_KW);
306                grammar::opt_json_keys_unique_clause(self);
307                m.complete(self, SyntaxKind::IS_NOT_JSON_SCALAR);
308                return true;
309            }
310            SyntaxKind::IS_JSON_OBJECT => {
311                let m = self.start();
312                self.bump(SyntaxKind::IS_KW);
313                self.bump(SyntaxKind::JSON_KW);
314                self.bump(SyntaxKind::OBJECT_KW);
315                grammar::opt_json_keys_unique_clause(self);
316                m.complete(self, SyntaxKind::IS_JSON_OBJECT);
317                return true;
318            }
319            SyntaxKind::IS_JSON_ARRAY => {
320                let m = self.start();
321                self.bump(SyntaxKind::IS_KW);
322                self.bump(SyntaxKind::JSON_KW);
323                self.bump(SyntaxKind::ARRAY_KW);
324                grammar::opt_json_keys_unique_clause(self);
325                m.complete(self, SyntaxKind::IS_JSON_ARRAY);
326                return true;
327            }
328            SyntaxKind::IS_JSON_VALUE => {
329                let m = self.start();
330                self.bump(SyntaxKind::IS_KW);
331                self.bump(SyntaxKind::JSON_KW);
332                self.bump(SyntaxKind::VALUE_KW);
333                grammar::opt_json_keys_unique_clause(self);
334                m.complete(self, SyntaxKind::IS_JSON_VALUE);
335                return true;
336            }
337            SyntaxKind::IS_JSON_SCALAR => {
338                let m = self.start();
339                self.bump(SyntaxKind::IS_KW);
340                self.bump(SyntaxKind::JSON_KW);
341                self.bump(SyntaxKind::SCALAR_KW);
342                grammar::opt_json_keys_unique_clause(self);
343                m.complete(self, SyntaxKind::IS_JSON_SCALAR);
344                return true;
345            }
346            SyntaxKind::NOT_SIMILAR_TO => {
347                let m = self.start();
348                self.bump(SyntaxKind::NOT_KW);
349                self.bump(SyntaxKind::SIMILAR_KW);
350                self.bump(SyntaxKind::TO_KW);
351                m.complete(self, SyntaxKind::NOT_SIMILAR_TO);
352                return true;
353            }
354            SyntaxKind::IS_NOT_DISTINCT_FROM => {
355                let m = self.start();
356                self.bump(SyntaxKind::IS_KW);
357                self.bump(SyntaxKind::NOT_KW);
358                self.bump(SyntaxKind::DISTINCT_KW);
359                self.bump(SyntaxKind::FROM_KW);
360                m.complete(self, SyntaxKind::IS_NOT_DISTINCT_FROM);
361                return true;
362            }
363            SyntaxKind::OPERATOR_CALL => {
364                let m = self.start();
365                self.bump(SyntaxKind::OPERATOR_KW);
366                self.bump(SyntaxKind::L_PAREN);
367
368                // database.
369                if self.eat(SyntaxKind::IDENT) {
370                    self.expect(SyntaxKind::DOT);
371                }
372                // schema.
373                if self.eat(SyntaxKind::IDENT) {
374                    self.expect(SyntaxKind::DOT);
375                }
376
377                // +, -, etc.
378                match grammar::current_operator(self) {
379                    Some(kind) => {
380                        self.bump(kind);
381                    }
382                    None => {
383                        self.error("expected operator");
384                    }
385                }
386
387                self.expect(SyntaxKind::R_PAREN);
388                m.complete(self, SyntaxKind::OPERATOR_CALL);
389                return true;
390            }
391            SyntaxKind::IS_DISTINCT_FROM => {
392                let m = self.start();
393                self.bump(SyntaxKind::IS_KW);
394                self.bump(SyntaxKind::DISTINCT_KW);
395                self.bump(SyntaxKind::FROM_KW);
396                m.complete(self, SyntaxKind::IS_DISTINCT_FROM);
397                return true;
398            }
399            SyntaxKind::NOT_LIKE => {
400                let m = self.start();
401                self.bump(SyntaxKind::NOT_KW);
402                self.bump(SyntaxKind::LIKE_KW);
403                m.complete(self, SyntaxKind::NOT_LIKE);
404                return true;
405            }
406            SyntaxKind::NOT_ILIKE => {
407                let m = self.start();
408                self.bump(SyntaxKind::NOT_KW);
409                self.bump(SyntaxKind::ILIKE_KW);
410                m.complete(self, SyntaxKind::NOT_ILIKE);
411                return true;
412            }
413            SyntaxKind::NOT_IN => {
414                let m = self.start();
415                self.bump(SyntaxKind::NOT_KW);
416                self.bump(SyntaxKind::IN_KW);
417                m.complete(self, SyntaxKind::NOT_IN);
418                return true;
419            }
420            SyntaxKind::IS_NOT => {
421                let m = self.start();
422                self.bump(SyntaxKind::IS_KW);
423                self.bump(SyntaxKind::NOT_KW);
424                m.complete(self, SyntaxKind::IS_NOT);
425                return true;
426            }
427            SyntaxKind::CUSTOM_OP => {
428                let m = self.start();
429                while !self.at(SyntaxKind::EOF) {
430                    let is_joint = self.inp.is_joint(self.pos);
431                    if self.at_ts(OPERATOR_FIRST) {
432                        self.bump_any();
433                    } else {
434                        break;
435                    }
436                    if !is_joint {
437                        break;
438                    }
439                }
440                m.complete(self, SyntaxKind::CUSTOM_OP);
441                return true;
442            }
443            _ => 1,
444        };
445        self.do_bump(kind, n_raw_tokens);
446        true
447    }
448
449    fn at_composite2(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind, triva: TrivaBetween) -> bool {
450        let tokens_match =
451            self.inp.kind(self.pos + n) == k1 && self.inp.kind(self.pos + n + 1) == k2;
452        // We need to do this so we can say that:
453        // 1 > > 2, is not the same as 1 >> 2
454        match triva {
455            TrivaBetween::Allowed => tokens_match,
456            TrivaBetween::NotAllowed => {
457                return tokens_match
458                    && self.inp.is_joint(self.pos + n)
459                    && self.next_not_joined_op(n + 1);
460            }
461        }
462    }
463
464    fn at_composite3(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind, k3: SyntaxKind) -> bool {
465        self.inp.kind(self.pos + n) == k1
466            && self.inp.kind(self.pos + n + 1) == k2
467            && self.inp.kind(self.pos + n + 2) == k3
468    }
469
470    fn at_composite4(
471        &self,
472        n: usize,
473        k1: SyntaxKind,
474        k2: SyntaxKind,
475        k3: SyntaxKind,
476        k4: SyntaxKind,
477    ) -> bool {
478        self.inp.kind(self.pos + n) == k1
479            && self.inp.kind(self.pos + n + 1) == k2
480            && self.inp.kind(self.pos + n + 2) == k3
481            && self.inp.kind(self.pos + n + 3) == k4
482    }
483
484    fn next_not_joined_op(&self, n: usize) -> bool {
485        let next = self.inp.kind(self.pos + n + 1);
486        // next isn't an operator so we know we're not joined to it
487        if !OPERATOR_FIRST.contains(next) {
488            return true;
489        }
490        // current kind isn't joined
491        if !self.inp.is_joint(self.pos + n) {
492            return true;
493        }
494        false
495    }
496
497    /// Checks if the current token is in `kinds`.
498    pub(crate) fn at_ts(&self, kinds: TokenSet) -> bool {
499        kinds.contains(self.current())
500    }
501
502    /// Starts a new node in the syntax tree. All nodes and tokens
503    /// consumed between the `start` and the corresponding `Marker::complete`
504    /// belong to the same node.
505    pub(crate) fn start(&mut self) -> Marker {
506        let pos = self.events.len() as u32;
507        self.push_event(Event::tombstone());
508        Marker::new(pos)
509    }
510
511    /// Consume the next token. Panics if the parser isn't currently at `kind`.
512    pub(crate) fn bump(&mut self, kind: SyntaxKind) {
513        assert!(self.eat(kind));
514    }
515
516    /// Advances the parser by one token
517    pub(crate) fn bump_any(&mut self) {
518        let kind = self.nth(0);
519        if kind == SyntaxKind::EOF {
520            return;
521        }
522        self.do_bump(kind, 1);
523    }
524
525    /// Advances the parser by one token
526    pub(crate) fn split_float(&mut self, mut marker: Marker) -> (bool, Marker) {
527        assert!(self.at(SyntaxKind::FLOAT_NUMBER));
528        // we have parse `<something>.`
529        // `<something>`.0.1
530        // here we need to insert an extra event
531        //
532        // `<something>`. 0. 1;
533        // here we need to change the follow up parse, the return value will cause us to emulate a dot
534        // the actual splitting happens later
535        let ends_in_dot = !self.inp.is_joint(self.pos);
536        if !ends_in_dot {
537            let new_marker = self.start();
538            let idx = marker.pos as usize;
539            match &mut self.events[idx] {
540                Event::Start {
541                    forward_parent,
542                    kind,
543                } => {
544                    *kind = SyntaxKind::FIELD_EXPR;
545                    *forward_parent = Some(new_marker.pos - marker.pos);
546                }
547                _ => unreachable!(),
548            }
549            marker.bomb.defuse();
550            marker = new_marker;
551        };
552        self.pos += 1;
553        self.push_event(Event::FloatSplitHack { ends_in_dot });
554        (ends_in_dot, marker)
555    }
556
557    /// Consume the next token if it is `kind` or emit an error
558    /// otherwise.
559    pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool {
560        if self.eat(kind) {
561            return true;
562        }
563        self.error(format!("expected {kind:?}"));
564        false
565    }
566
567    /// Create an error node and consume the next token.
568    pub(crate) fn err_and_bump(&mut self, message: &str) {
569        self.err_recover(message, TokenSet::EMPTY);
570    }
571
572    /// Create an error node and consume the next token.
573    pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
574        // TODO: maybe we actually want this?
575        // if matches!(self.current(), SyntaxKind::L_PAREN | SyntaxKind::R_PAREN) {
576        //     self.error(message);
577        //     return;
578        // }
579
580        if self.at_ts(recovery) {
581            self.error(message);
582            return;
583        }
584
585        let m = self.start();
586        self.error(message);
587        self.bump_any();
588        m.complete(self, SyntaxKind::ERROR);
589    }
590
591    fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) {
592        self.pos += n_raw_tokens as usize;
593        self.steps.set(0);
594        self.push_event(Event::Token { kind, n_raw_tokens });
595    }
596
597    fn push_event(&mut self, event: Event) {
598        self.events.push(event);
599    }
600
601    fn finish(self) -> Vec<Event> {
602        self.events
603    }
604
605    /// Emit error with the `message`
606    /// FIXME: this should be much more fancy and support
607    /// structured errors with spans and notes, like rustc
608    /// does.
609    pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
610        let msg = message.into();
611        self.push_event(Event::Error { msg });
612    }
613
614    /// Checks if the current token is `kind`.
615    #[must_use]
616    pub(crate) fn at(&self, kind: SyntaxKind) -> bool {
617        self.nth_at(0, kind)
618    }
619
620    /// Checks if the nth token is in `kinds`.
621    #[must_use]
622    pub(crate) fn nth_at_ts(&self, n: usize, kinds: TokenSet) -> bool {
623        kinds.contains(self.nth(n))
624    }
625
626    #[must_use]
627    pub(crate) fn nth_at(&self, n: usize, kind: SyntaxKind) -> bool {
628        match kind {
629            // =>
630            SyntaxKind::FAT_ARROW => self.at_composite2(
631                n,
632                SyntaxKind::EQ,
633                SyntaxKind::R_ANGLE,
634                TrivaBetween::NotAllowed,
635            ),
636            // :=
637            SyntaxKind::COLON_EQ => self.at_composite2(
638                n,
639                SyntaxKind::COLON,
640                SyntaxKind::EQ,
641                TrivaBetween::NotAllowed,
642            ),
643            // ::
644            SyntaxKind::COLON_COLON => self.at_composite2(
645                n,
646                SyntaxKind::COLON,
647                SyntaxKind::COLON,
648                TrivaBetween::NotAllowed,
649            ),
650            // !=
651            SyntaxKind::NEQ => self.at_composite2(
652                n,
653                SyntaxKind::BANG,
654                SyntaxKind::EQ,
655                TrivaBetween::NotAllowed,
656            ),
657            // <>
658            SyntaxKind::NEQB => self.at_composite2(
659                n,
660                SyntaxKind::L_ANGLE,
661                SyntaxKind::R_ANGLE,
662                TrivaBetween::NotAllowed,
663            ),
664            // is not
665            SyntaxKind::IS_NOT => self.at_composite2(
666                n,
667                SyntaxKind::IS_KW,
668                SyntaxKind::NOT_KW,
669                TrivaBetween::Allowed,
670            ),
671            // not like
672            SyntaxKind::NOT_LIKE => self.at_composite2(
673                n,
674                SyntaxKind::NOT_KW,
675                SyntaxKind::LIKE_KW,
676                TrivaBetween::Allowed,
677            ),
678            // not ilike
679            SyntaxKind::NOT_ILIKE => self.at_composite2(
680                n,
681                SyntaxKind::NOT_KW,
682                SyntaxKind::ILIKE_KW,
683                TrivaBetween::Allowed,
684            ),
685            // not in
686            SyntaxKind::NOT_IN => self.at_composite2(
687                n,
688                SyntaxKind::NOT_KW,
689                SyntaxKind::IN_KW,
690                TrivaBetween::Allowed,
691            ),
692            // at time zone
693            SyntaxKind::AT_TIME_ZONE => self.at_composite3(
694                n,
695                SyntaxKind::AT_KW,
696                SyntaxKind::TIME_KW,
697                SyntaxKind::ZONE_KW,
698            ),
699            // is distinct from
700            SyntaxKind::IS_DISTINCT_FROM => self.at_composite3(
701                n,
702                SyntaxKind::IS_KW,
703                SyntaxKind::DISTINCT_KW,
704                SyntaxKind::FROM_KW,
705            ),
706            // is not distinct from
707            SyntaxKind::IS_NOT_DISTINCT_FROM => self.at_composite4(
708                n,
709                SyntaxKind::IS_KW,
710                SyntaxKind::NOT_KW,
711                SyntaxKind::DISTINCT_KW,
712                SyntaxKind::FROM_KW,
713            ),
714            // is normalized
715            SyntaxKind::IS_NORMALIZED => {
716                if self.at(SyntaxKind::IS_KW) {
717                    if matches!(
718                        self.nth(1),
719                        SyntaxKind::NFC_KW
720                            | SyntaxKind::NFD_KW
721                            | SyntaxKind::NFKC_KW
722                            | SyntaxKind::NFKD_KW
723                    ) {
724                        if self.nth_at(2, SyntaxKind::NORMALIZED_KW) {
725                            return true;
726                        }
727                    } else {
728                        if self.nth_at(1, SyntaxKind::NORMALIZED_KW) {
729                            return true;
730                        }
731                    }
732                }
733                return false;
734            }
735            // is not normalized
736            SyntaxKind::IS_NOT_NORMALIZED => {
737                if self.at(SyntaxKind::IS_KW) && self.nth_at(1, SyntaxKind::NOT_KW) {
738                    if matches!(
739                        self.nth(2),
740                        SyntaxKind::NFC_KW
741                            | SyntaxKind::NFD_KW
742                            | SyntaxKind::NFKC_KW
743                            | SyntaxKind::NFKD_KW
744                    ) {
745                        if self.nth_at(3, SyntaxKind::NOT_KW)
746                            && self.nth_at(4, SyntaxKind::NORMALIZED_KW)
747                        {
748                            return true;
749                        }
750                    } else {
751                        if self.nth_at(2, SyntaxKind::NOT_KW)
752                            && self.nth_at(3, SyntaxKind::NORMALIZED_KW)
753                        {
754                            return true;
755                        }
756                    }
757                }
758                return false;
759            }
760            SyntaxKind::NOT_SIMILAR_TO => self.at_composite3(
761                n,
762                SyntaxKind::NOT_KW,
763                SyntaxKind::SIMILAR_KW,
764                SyntaxKind::TO_KW,
765            ),
766            // similar to
767            SyntaxKind::SIMILAR_TO => self.at_composite2(
768                n,
769                SyntaxKind::SIMILAR_KW,
770                SyntaxKind::TO_KW,
771                TrivaBetween::Allowed,
772            ),
773            // https://www.postgresql.org/docs/17/sql-expressions.html#SQL-EXPRESSIONS-OPERATOR-CALLS
774            // TODO: is this right?
775            SyntaxKind::OPERATOR_CALL => self.at_composite2(
776                n,
777                SyntaxKind::OPERATOR_KW,
778                SyntaxKind::L_PAREN,
779                TrivaBetween::Allowed,
780            ),
781            // is json
782            SyntaxKind::IS_JSON => self.at_composite2(
783                n,
784                SyntaxKind::IS_KW,
785                SyntaxKind::JSON_KW,
786                TrivaBetween::Allowed,
787            ),
788            // is not json
789            SyntaxKind::IS_NOT_JSON => self.at_composite3(
790                n,
791                SyntaxKind::IS_KW,
792                SyntaxKind::NOT_KW,
793                SyntaxKind::JSON_KW,
794            ),
795            // is not json object
796            SyntaxKind::IS_NOT_JSON_OBJECT => self.at_composite4(
797                n,
798                SyntaxKind::IS_KW,
799                SyntaxKind::NOT_KW,
800                SyntaxKind::JSON_KW,
801                SyntaxKind::OBJECT_KW,
802            ),
803            // is not json array
804            SyntaxKind::IS_NOT_JSON_ARRAY => self.at_composite4(
805                n,
806                SyntaxKind::IS_KW,
807                SyntaxKind::NOT_KW,
808                SyntaxKind::JSON_KW,
809                SyntaxKind::ARRAY_KW,
810            ),
811            // is not json value
812            SyntaxKind::IS_NOT_JSON_VALUE => self.at_composite4(
813                n,
814                SyntaxKind::IS_KW,
815                SyntaxKind::NOT_KW,
816                SyntaxKind::JSON_KW,
817                SyntaxKind::VALUE_KW,
818            ),
819            // is not json scalar
820            SyntaxKind::IS_NOT_JSON_SCALAR => self.at_composite4(
821                n,
822                SyntaxKind::IS_KW,
823                SyntaxKind::NOT_KW,
824                SyntaxKind::JSON_KW,
825                SyntaxKind::SCALAR_KW,
826            ),
827            // is json object
828            SyntaxKind::IS_JSON_OBJECT => self.at_composite3(
829                n,
830                SyntaxKind::IS_KW,
831                SyntaxKind::JSON_KW,
832                SyntaxKind::OBJECT_KW,
833            ),
834            // is json array
835            SyntaxKind::IS_JSON_ARRAY => self.at_composite3(
836                n,
837                SyntaxKind::IS_KW,
838                SyntaxKind::JSON_KW,
839                SyntaxKind::ARRAY_KW,
840            ),
841            // is json value
842            SyntaxKind::IS_JSON_VALUE => self.at_composite3(
843                n,
844                SyntaxKind::IS_KW,
845                SyntaxKind::JSON_KW,
846                SyntaxKind::VALUE_KW,
847            ),
848            // is json scalar
849            SyntaxKind::IS_JSON_SCALAR => self.at_composite3(
850                n,
851                SyntaxKind::IS_KW,
852                SyntaxKind::JSON_KW,
853                SyntaxKind::SCALAR_KW,
854            ),
855            // <=
856            SyntaxKind::LTEQ => self.at_composite2(
857                n,
858                SyntaxKind::L_ANGLE,
859                SyntaxKind::EQ,
860                TrivaBetween::NotAllowed,
861            ),
862            // <=
863            SyntaxKind::GTEQ => self.at_composite2(
864                n,
865                SyntaxKind::R_ANGLE,
866                SyntaxKind::EQ,
867                TrivaBetween::NotAllowed,
868            ),
869            SyntaxKind::CUSTOM_OP => {
870                // TODO: is this right?
871                if self.at_ts(OPERATOR_FIRST) {
872                    return true;
873                }
874                return false;
875            }
876            // TODO: we probably shouldn't be using a _ for this but be explicit for each type?
877            _ => self.inp.kind(self.pos + n) == kind,
878        }
879    }
880
881    /// Returns the kind of the current token.
882    /// If parser has already reached the end of input,
883    /// the special `EOF` kind is returned.
884    #[must_use]
885    pub(crate) fn current(&self) -> SyntaxKind {
886        self.nth(0)
887    }
888
889    /// Lookahead operation: returns the kind of the next nth
890    /// token.
891    #[must_use]
892    fn nth(&self, n: usize) -> SyntaxKind {
893        assert!(n <= 3);
894
895        let steps = self.steps.get();
896        assert!(
897            (steps as usize) < PARSER_STEP_LIMIT,
898            "the parser seems stuck"
899        );
900        self.steps.set(steps + 1);
901
902        self.inp.kind(self.pos + n)
903    }
904}