Skip to content

Commit a6d47b5

Browse files
authored
Properly skip comments when parsing (#332)
1 parent e3e1627 commit a6d47b5

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

partiql-parser/src/lexer.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,46 @@ impl<'input> fmt::Display for Token<'input> {
830830
}
831831
}
832832

833+
/// A lexer that wraps another lexer and skips comments.
834+
pub(crate) struct CommentSkippingLexer<'input, L>
835+
where
836+
L: Iterator<Item = LexResult<'input>>,
837+
{
838+
lexer: L,
839+
}
840+
841+
impl<'input, L> CommentSkippingLexer<'input, L>
842+
where
843+
L: Iterator<Item = LexResult<'input>>,
844+
{
845+
/// Creates a new CommentSkippingLexer wrapping `lexer`
846+
#[inline]
847+
pub fn new(lexer: L) -> Self {
848+
Self { lexer }
849+
}
850+
}
851+
852+
impl<'input, L> Iterator for CommentSkippingLexer<'input, L>
853+
where
854+
L: Iterator<Item = LexResult<'input>>,
855+
{
856+
type Item = LexResult<'input>;
857+
858+
#[inline(always)]
859+
fn next(&mut self) -> Option<Self::Item> {
860+
'next_tok: loop {
861+
let next = self.lexer.next();
862+
if matches!(
863+
next,
864+
Some(Ok((_, Token::CommentBlock(_) | Token::CommentLine(_), _)))
865+
) {
866+
continue 'next_tok;
867+
}
868+
return next;
869+
}
870+
}
871+
}
872+
833873
#[cfg(test)]
834874
mod tests {
835875
use super::*;

partiql-parser/src/parse/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod parser_state;
77

88
use crate::error::{ParseError, UnexpectedTokenData};
99
use crate::lexer;
10+
use crate::lexer::CommentSkippingLexer;
1011
use crate::parse::parser_state::{IdGenerator, ParserState};
1112
use crate::preprocessor::{PreprocessingPartiqlLexer, BUILT_INS};
1213
use lalrpop_util as lpop;
@@ -63,6 +64,7 @@ fn parse_partiql_with_state<'input, Id: IdGenerator>(
6364
) -> AstResult<'input> {
6465
let mut offsets = LineOffsetTracker::default();
6566
let lexer = PreprocessingPartiqlLexer::new(s, &mut offsets, &BUILT_INS);
67+
let lexer = CommentSkippingLexer::new(lexer);
6668

6769
let result: LalrpopResult = grammar::QueryParser::new().parse(s, &mut state, lexer);
6870

@@ -520,6 +522,15 @@ mod tests {
520522
fn select_with_at_and_cross_join_and_at() {
521523
parse!(r#"SELECT * FROM a AS a AT b CROSS JOIN c AS c AT q"#);
522524
}
525+
526+
#[test]
527+
fn multiline_with_comments() {
528+
parse!(
529+
r#"SELECT * FROM hr.employees -- T1
530+
UNION
531+
SELECT title FROM engineering.employees -- T2"#
532+
);
533+
}
523534
}
524535

525536
mod set_ops {

0 commit comments

Comments
 (0)