Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor advancing token to avoid duplication, avoid borrow checker issues #1618

Merged
merged 3 commits into from
Dec 27, 2024

Conversation

alamb
Copy link
Contributor

@alamb alamb commented Dec 24, 2024

@davisp made some great improvements to the Parser API to avoid copies, but now the API for managing tokens is a bit unwieldy. Before we release a new version I would like to improve the API

Speicfically some of the APIs take a &mut self to advance index but return a read only reference to the token. This means the borrow checker is overly stringent and will sometimes think the parser has a mutable borrow outstanding when it doesnt.

I think we can make the APIs easier to use (and thus more likely to use) with a bit of finagling and documentation

See definitions of previous/current/next on #1617

I am hoping that we can get the API in shape a bit more and then deprecate some of the older style APIs.

Changes:

  1. Introduce advance_token() to advance to the next token and reduce redundancy
  2. Introduce get_current_token(), get_next_token() get_prev_token
  3. Introduce current_token_index
  4. Remove next_token_ref_with_index and next_token_ref in favor of the above

@@ -1276,7 +1276,9 @@ impl<'a> Parser<'a> {

let dialect = self.dialect;

let (next_token, next_token_index) = self.next_token_ref_with_index();
self.advance_token();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has two benefits:

  1. I think it is more explicit
  2. It doesn't not result in a mut borrow of self(this is the key difference)

@@ -3641,22 +3670,31 @@ impl<'a> Parser<'a> {
#[must_use]
pub fn parse_keyword(&mut self, expected: Keyword) -> bool {
if self.peek_keyword(expected) {
self.next_token_ref();
self.advance_token();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is nicer too as it makes clear the token is unused (it is just being advanced)

///
/// # Notes:
/// OK to call repeatedly after reaching EOF.
pub fn next_token_ref_with_index(&mut self) -> (&TokenWithSpan, usize) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note thse APIs were added in #1587 (so not yet released) so this isn't a breaking API change

@alamb alamb marked this pull request as ready for review December 24, 2024 23:08
Copy link
Contributor

@iffyio iffyio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! Thanks @alamb!

src/parser/mod.rs Outdated Show resolved Hide resolved
Copy link
Contributor Author

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @iffyio -- I will try and find time to refine the parse_keyword_token_ref function over the next day or two

src/parser/mod.rs Outdated Show resolved Hide resolved
Co-authored-by: Andrew Lamb <[email protected]>
@iffyio iffyio merged commit 6daa4b0 into apache:main Dec 27, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants