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

Insert an empty lookahead in the lane table in reduce conflict states #898

Merged
merged 1 commit into from
May 24, 2024

Conversation

dburgener
Copy link
Contributor

We need to make sure the state in the conflict is in the lane table. All the existing test cases happened to have a shift case in the conflict state, even if the shift wasn't part of the actual conflict. In the event of a conflicting state with only reduce actions, we'll need the lookahead store, so we can check it as a successor of the predecessors we found.

fixes #897

We need to make sure the state in the conflict is in the lane table.
All the existing test cases happened to have a shift case in the
conflict state, even if the shift wasn't part of the actual conflict.
In the event of a conflicting state with only reduce actions, we'll need
the lookahead store, so we can check it as a successor of the
predecessors we found.

fixes lalrpop#897
@Pat-Lafon
Copy link
Contributor

Oh wow, it looks like just a simple fix is needed. This seems to also resolve the panic raised in #665 which gives me more confidence in this change. I suspect it is also the same in #391. A long standing bug if so!

Copy link
Contributor

@Pat-Lafon Pat-Lafon left a comment

Choose a reason for hiding this comment

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

I'm motivated to have this merged in but it would be nice to have an additional set of eyes just in case this is somehow "too easy" of a fix.

@dburgener
Copy link
Contributor Author

Wow, yeah, I guess there was quite the history of this. Those bugs do all look like the same issue. It will be good to have it all fixed.

I agree about wanting more eyes. I do think the change makes sense, and the new behavior here seems to agree with the documentation, Niko's lane table blog post, and the original lane table paper as much as I understand them. That said, this is my first time diving deep into the details of the lane table algorithm, so I'm far from a lane table expert.

It would be nice if we could get @nikomatsakis to take a look at this, since he's got to be the maintainer with the most in depth knowledge of the lane table algorithm.

@nikomatsakis
Copy link
Collaborator

This is one of those classic cases -- a one-line diff but maybe big implications :)

@nikomatsakis
Copy link
Collaborator

Man, I had to do quite some work to bring this back into cache. I'm glad that I left as many comments as I did!

I still haven't reconstructed the full algorithm in my head but, from what I can see, this change appears pretty safe and quite reasonable. Adding an empty entry into the conflict table seems like it should basically always be an ok thing to do.

I don't yet see the complete line in the code that leads from this entry not existing to the panic -- I guess that somehow either source or target is otherwise not present in the Map here? I'm not sure where that occurs exactly.

let set1 = self.state_sets[&source];
let set2 = self.state_sets[&target];

Copy link
Collaborator

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

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

OK, I worked this through a bit more in my head and I feel comfortable with this change. Nice work, @dburgener!

@nikomatsakis nikomatsakis added this pull request to the merge queue May 24, 2024
Merged via the queue into lalrpop:master with commit 8536144 May 24, 2024
9 checks passed
@dburgener dburgener deleted the lane_table_reduce_panic branch May 24, 2024 14:23
@dburgener
Copy link
Contributor Author

Thanks, @nikomatsakis!

I don't yet see the complete line in the code that leads from this entry not existing to the panic -- I guess that somehow either source or target is otherwise not present in the Map here? I'm not sure where that occurs exactly.

Not sure if your final comment means you're good on this now, but yes, my understanding is that you are correct here. In the common case, the predecessors of the conflicting state get added with it as successors here. We later start walking the lane table, which gets us to this line, which panics, because the original state is a successor of something else, but was never inserted itself.

In all our previously existing tests, the conflicting state had a reduce/reduce conflict, but there was also a non-conflicting possible shift from that state, which resulted in the state being stored in the lane table. But there's nothing to say there must also be a shift, that was just a coincidence of the provided grammars.

@nikomatsakis
Copy link
Collaborator

nikomatsakis commented May 27, 2024 via email

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.

Lalrpop 0.20.2 exception "no entry found for key"
3 participants