Skip to content

Commit d2b15df

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 bc55f6f commit d2b15df

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
@@ -3949,6 +3949,26 @@ impl<'a> Parser<'a> {
39493949
})
39503950
}
39513951

3952+
/// Return nth previous token, possibly whitespace
3953+
/// (or [`Token::EOF`] when before the beginning of the stream).
3954+
pub fn peek_prev_nth_token_no_skip(&self, n: usize) -> TokenWithSpan {
3955+
// 0 = next token, -1 = current token, -2 = previous token
3956+
let peek_index = self.index.saturating_sub(1).saturating_sub(n);
3957+
if peek_index == 0 {
3958+
return TokenWithSpan {
3959+
token: Token::EOF,
3960+
span: Span::empty(),
3961+
};
3962+
}
3963+
self.tokens
3964+
.get(peek_index)
3965+
.cloned()
3966+
.unwrap_or(TokenWithSpan {
3967+
token: Token::EOF,
3968+
span: Span::empty(),
3969+
})
3970+
}
3971+
39523972
/// Return true if the next tokens exactly `expected`
39533973
///
39543974
/// Does not advance the current token.
@@ -4065,16 +4085,15 @@ impl<'a> Parser<'a> {
40654085
)
40664086
}
40674087

4068-
/// Look backwards in the token stream and expect that there was only whitespace tokens until the previous newline
4069-
pub fn expect_previously_only_whitespace_until_newline(&mut self) -> Result<(), ParserError> {
4070-
let mut look_back_count = 2;
4088+
/// Look backwards in the token stream and expect that there was only whitespace tokens until the previous newline or beginning of string
4089+
pub(crate) fn expect_previously_only_whitespace_until_newline(
4090+
&mut self,
4091+
) -> Result<(), ParserError> {
4092+
let mut look_back_count = 1;
40714093
loop {
4072-
let prev_index = self.index.saturating_sub(look_back_count);
4073-
if prev_index == 0 {
4074-
break;
4075-
}
4076-
let prev_token = self.token_at(prev_index);
4094+
let prev_token = self.peek_prev_nth_token_no_skip(look_back_count);
40774095
match prev_token.token {
4096+
Token::EOF => break,
40784097
Token::Whitespace(ref w) => match w {
40794098
Whitespace::Newline => break,
40804099
// special consideration required for single line comments since that string includes the newline
@@ -4086,18 +4105,13 @@ impl<'a> Parser<'a> {
40864105
}
40874106
_ => look_back_count += 1,
40884107
},
4089-
_ => {
4090-
let current_token = self.get_current_token();
4091-
if prev_token == current_token {
4092-
// if we are at the start of the statement, we can skip this check
4093-
break;
4094-
}
4095-
4096-
self.expected(
4097-
&format!("newline before current token ({})", current_token),
4098-
prev_token.clone(),
4099-
)?
4100-
}
4108+
_ => self.expected(
4109+
&format!(
4110+
"newline before current token ({})",
4111+
self.get_current_token()
4112+
),
4113+
prev_token.clone(),
4114+
)?,
41014115
};
41024116
}
41034117
Ok(())
@@ -15540,6 +15554,31 @@ mod tests {
1554015554
})
1554115555
}
1554215556

15557+
#[test]
15558+
fn test_peek_prev_nth_token_no_skip() {
15559+
all_dialects().run_parser_method(
15560+
"SELECT 1;\n-- a comment\nRAISERROR('test', 16, 0);",
15561+
|parser| {
15562+
parser.index = 1;
15563+
assert_eq!(parser.peek_prev_nth_token_no_skip(0), Token::EOF);
15564+
assert_eq!(parser.index, 1);
15565+
parser.index = 7;
15566+
assert_eq!(
15567+
parser.token_at(parser.index - 1).token,
15568+
Token::Word(Word {
15569+
value: "RAISERROR".to_string(),
15570+
quote_style: None,
15571+
keyword: Keyword::RAISERROR,
15572+
})
15573+
);
15574+
assert_eq!(
15575+
parser.peek_prev_nth_token_no_skip(2),
15576+
Token::Whitespace(Whitespace::Newline)
15577+
);
15578+
},
15579+
);
15580+
}
15581+
1554315582
#[cfg(test)]
1554415583
mod test_parse_data_type {
1554515584
use crate::ast::{

0 commit comments

Comments
 (0)