Skip to content

Commit 2a2928a

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 e5705b9 commit 2a2928a

File tree

1 file changed

+59
-20
lines changed

1 file changed

+59
-20
lines changed

src/parser/mod.rs

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4034,6 +4034,26 @@ impl<'a> Parser<'a> {
40344034
})
40354035
}
40364036

4037+
/// Return nth previous token, possibly whitespace
4038+
/// (or [`Token::EOF`] when before the beginning of the stream).
4039+
pub fn peek_prev_nth_token_no_skip(&self, n: usize) -> TokenWithSpan {
4040+
// 0 = next token, -1 = current token, -2 = previous token
4041+
let peek_index = self.index.saturating_sub(1).saturating_sub(n);
4042+
if peek_index == 0 {
4043+
return TokenWithSpan {
4044+
token: Token::EOF,
4045+
span: Span::empty(),
4046+
};
4047+
}
4048+
self.tokens
4049+
.get(peek_index)
4050+
.cloned()
4051+
.unwrap_or(TokenWithSpan {
4052+
token: Token::EOF,
4053+
span: Span::empty(),
4054+
})
4055+
}
4056+
40374057
/// Return true if the next tokens exactly `expected`
40384058
///
40394059
/// Does not advance the current token.
@@ -4150,16 +4170,15 @@ impl<'a> Parser<'a> {
41504170
)
41514171
}
41524172

4153-
/// Look backwards in the token stream and expect that there was only whitespace tokens until the previous newline
4154-
pub fn expect_previously_only_whitespace_until_newline(&mut self) -> Result<(), ParserError> {
4155-
let mut look_back_count = 2;
4173+
/// Look backwards in the token stream and expect that there was only whitespace tokens until the previous newline or beginning of string
4174+
pub(crate) fn expect_previously_only_whitespace_until_newline(
4175+
&mut self,
4176+
) -> Result<(), ParserError> {
4177+
let mut look_back_count = 1;
41564178
loop {
4157-
let prev_index = self.index.saturating_sub(look_back_count);
4158-
if prev_index == 0 {
4159-
break;
4160-
}
4161-
let prev_token = self.token_at(prev_index);
4179+
let prev_token = self.peek_prev_nth_token_no_skip(look_back_count);
41624180
match prev_token.token {
4181+
Token::EOF => break,
41634182
Token::Whitespace(ref w) => match w {
41644183
Whitespace::Newline => break,
41654184
// special consideration required for single line comments since that string includes the newline
@@ -4171,18 +4190,13 @@ impl<'a> Parser<'a> {
41714190
}
41724191
_ => look_back_count += 1,
41734192
},
4174-
_ => {
4175-
let current_token = self.get_current_token();
4176-
if prev_token == current_token {
4177-
// if we are at the start of the statement, we can skip this check
4178-
break;
4179-
}
4180-
4181-
self.expected(
4182-
&format!("newline before current token ({})", current_token),
4183-
prev_token.clone(),
4184-
)?
4185-
}
4193+
_ => self.expected(
4194+
&format!(
4195+
"newline before current token ({})",
4196+
self.get_current_token()
4197+
),
4198+
prev_token.clone(),
4199+
)?,
41864200
};
41874201
}
41884202
Ok(())
@@ -16704,6 +16718,31 @@ mod tests {
1670416718
})
1670516719
}
1670616720

16721+
#[test]
16722+
fn test_peek_prev_nth_token_no_skip() {
16723+
all_dialects().run_parser_method(
16724+
"SELECT 1;\n-- a comment\nRAISERROR('test', 16, 0);",
16725+
|parser| {
16726+
parser.index = 1;
16727+
assert_eq!(parser.peek_prev_nth_token_no_skip(0), Token::EOF);
16728+
assert_eq!(parser.index, 1);
16729+
parser.index = 7;
16730+
assert_eq!(
16731+
parser.token_at(parser.index - 1).token,
16732+
Token::Word(Word {
16733+
value: "RAISERROR".to_string(),
16734+
quote_style: None,
16735+
keyword: Keyword::RAISERROR,
16736+
})
16737+
);
16738+
assert_eq!(
16739+
parser.peek_prev_nth_token_no_skip(2),
16740+
Token::Whitespace(Whitespace::Newline)
16741+
);
16742+
},
16743+
);
16744+
}
16745+
1670716746
#[cfg(test)]
1670816747
mod test_parse_data_type {
1670916748
use crate::ast::{

0 commit comments

Comments
 (0)