Skip to content

Commit f3cbaa1

Browse files
committed
Introduce peek_prev_nth_token_no_skip helper
- and use it for `expect_previously_only_whitespace_until_newline` so that can be simplified accordingly
1 parent d18a8d5 commit f3cbaa1

File tree

1 file changed

+54
-20
lines changed

1 file changed

+54
-20
lines changed

src/parser/mod.rs

+54-20
Original file line numberDiff line numberDiff line change
@@ -3954,6 +3954,26 @@ impl<'a> Parser<'a> {
39543954
})
39553955
}
39563956

3957+
/// Return nth previous token, possibly whitespace
3958+
/// (or [`Token::EOF`] when before the beginning of the stream).
3959+
pub fn peek_prev_nth_token_no_skip(&self, n: usize) -> TokenWithSpan {
3960+
// 0 = next token, -1 = current token, -2 = previous token
3961+
let peek_index = self.index.saturating_sub(1).saturating_sub(n);
3962+
if peek_index == 0 {
3963+
return TokenWithSpan {
3964+
token: Token::EOF,
3965+
span: Span::empty(),
3966+
};
3967+
}
3968+
self.tokens
3969+
.get(peek_index)
3970+
.cloned()
3971+
.unwrap_or(TokenWithSpan {
3972+
token: Token::EOF,
3973+
span: Span::empty(),
3974+
})
3975+
}
3976+
39573977
/// Return true if the next tokens exactly `expected`
39583978
///
39593979
/// Does not advance the current token.
@@ -4070,16 +4090,13 @@ impl<'a> Parser<'a> {
40704090
)
40714091
}
40724092

4073-
/// Look backwards in the token stream and expect that there was only whitespace tokens until the previous newline
4074-
pub fn expect_previously_only_whitespace_until_newline(&mut self) -> Result<(), ParserError> {
4075-
let mut look_back_count = 2;
4093+
/// Look backwards in the token stream and expect that there was only whitespace tokens until the previous newline or beginning of string
4094+
pub(crate) fn expect_previously_only_whitespace_until_newline(&mut self) -> Result<(), ParserError> {
4095+
let mut look_back_count = 1;
40764096
loop {
4077-
let prev_index = self.index.saturating_sub(look_back_count);
4078-
if prev_index == 0 {
4079-
break;
4080-
}
4081-
let prev_token = self.token_at(prev_index);
4097+
let prev_token = self.peek_prev_nth_token_no_skip(look_back_count);
40824098
match prev_token.token {
4099+
Token::EOF => break,
40834100
Token::Whitespace(ref w) => match w {
40844101
Whitespace::Newline => break,
40854102
// special consideration required for single line comments since that string includes the newline
@@ -4091,18 +4108,10 @@ impl<'a> Parser<'a> {
40914108
}
40924109
_ => look_back_count += 1,
40934110
},
4094-
_ => {
4095-
let current_token = self.get_current_token();
4096-
if prev_token == current_token {
4097-
// if we are at the start of the statement, we can skip this check
4098-
break;
4099-
}
4100-
4101-
self.expected(
4102-
&format!("newline before current token ({})", current_token),
4103-
prev_token.clone(),
4104-
)?
4105-
}
4111+
_ => self.expected(
4112+
&format!("newline before current token ({})", self.get_current_token()),
4113+
prev_token.clone()
4114+
)?,
41064115
};
41074116
}
41084117
Ok(())
@@ -15379,6 +15388,31 @@ mod tests {
1537915388
})
1538015389
}
1538115390

15391+
#[test]
15392+
fn test_peek_prev_nth_token_no_skip() {
15393+
all_dialects().run_parser_method("SELECT 1;\n-- a comment\nRAISERROR('test', 16, 0);", |parser| {
15394+
parser.index = 1;
15395+
assert_eq!(
15396+
parser.peek_prev_nth_token_no_skip(0),
15397+
Token::EOF
15398+
);
15399+
assert_eq!(parser.index, 1);
15400+
parser.index = 7;
15401+
assert_eq!(
15402+
parser.token_at(parser.index - 1).token,
15403+
Token::Word(Word {
15404+
value: "RAISERROR".to_string(),
15405+
quote_style: None,
15406+
keyword: Keyword::RAISERROR,
15407+
})
15408+
);
15409+
assert_eq!(
15410+
parser.peek_prev_nth_token_no_skip(2),
15411+
Token::Whitespace(Whitespace::Newline)
15412+
);
15413+
});
15414+
}
15415+
1538215416
#[cfg(test)]
1538315417
mod test_parse_data_type {
1538415418
use crate::ast::{

0 commit comments

Comments
 (0)