Add some useful comments to Parser::look_ahead
.
This commit is contained in:
parent
04cf6b4ac5
commit
e8f733370f
@ -1052,33 +1052,48 @@ pub fn bump(&mut self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Look-ahead `dist` tokens of `self.token` and get access to that token there.
|
/// Look-ahead `dist` tokens of `self.token` and get access to that token there.
|
||||||
/// When `dist == 0` then the current token is looked at.
|
/// When `dist == 0` then the current token is looked at. `Eof` will be
|
||||||
|
/// returned if the look-ahead is any distance past the end of the tokens.
|
||||||
pub fn look_ahead<R>(&self, dist: usize, looker: impl FnOnce(&Token) -> R) -> R {
|
pub fn look_ahead<R>(&self, dist: usize, looker: impl FnOnce(&Token) -> R) -> R {
|
||||||
if dist == 0 {
|
if dist == 0 {
|
||||||
return looker(&self.token);
|
return looker(&self.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tree_cursor = &self.token_cursor.tree_cursor;
|
|
||||||
if let Some(&(_, delim, span)) = self.token_cursor.stack.last()
|
if let Some(&(_, delim, span)) = self.token_cursor.stack.last()
|
||||||
&& delim != Delimiter::Invisible
|
&& delim != Delimiter::Invisible
|
||||||
{
|
{
|
||||||
|
// We are not in the outermost token stream, and the token stream
|
||||||
|
// we are in has non-skipped delimiters. Look for skipped
|
||||||
|
// delimiters in the lookahead range.
|
||||||
|
let tree_cursor = &self.token_cursor.tree_cursor;
|
||||||
let all_normal = (0..dist).all(|i| {
|
let all_normal = (0..dist).all(|i| {
|
||||||
let token = tree_cursor.look_ahead(i);
|
let token = tree_cursor.look_ahead(i);
|
||||||
!matches!(token, Some(TokenTree::Delimited(_, Delimiter::Invisible, _)))
|
!matches!(token, Some(TokenTree::Delimited(_, Delimiter::Invisible, _)))
|
||||||
});
|
});
|
||||||
if all_normal {
|
if all_normal {
|
||||||
|
// There were no skipped delimiters. Do lookahead by plain indexing.
|
||||||
return match tree_cursor.look_ahead(dist - 1) {
|
return match tree_cursor.look_ahead(dist - 1) {
|
||||||
Some(tree) => match tree {
|
Some(tree) => {
|
||||||
TokenTree::Token(token, _) => looker(token),
|
// Indexing stayed within the current token stream.
|
||||||
TokenTree::Delimited(dspan, delim, _) => {
|
match tree {
|
||||||
looker(&Token::new(token::OpenDelim(*delim), dspan.open))
|
TokenTree::Token(token, _) => looker(token),
|
||||||
|
TokenTree::Delimited(dspan, delim, _) => {
|
||||||
|
looker(&Token::new(token::OpenDelim(*delim), dspan.open))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => looker(&Token::new(token::CloseDelim(delim), span.close)),
|
None => {
|
||||||
|
// Indexing went past the end of the current token
|
||||||
|
// stream. Use the close delimiter, no matter how far
|
||||||
|
// ahead `dist` went.
|
||||||
|
looker(&Token::new(token::CloseDelim(delim), span.close))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We are in a more complex case. Just clone the token cursor and use
|
||||||
|
// `next`, skipping delimiters as necessary. Slow but simple.
|
||||||
let mut cursor = self.token_cursor.clone();
|
let mut cursor = self.token_cursor.clone();
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let mut token = Token::dummy();
|
let mut token = Token::dummy();
|
||||||
|
Loading…
Reference in New Issue
Block a user