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

Implement left-recursive rule optimization #1399

Closed
wants to merge 2 commits into from

Conversation

sharwell
Copy link
Member

@sharwell sharwell commented Nov 23, 2016

Fixes #1398
Fixes #994

📝 For #1323 I'm observing a 10,000:1 performance improvement. Yeah, that much! 🎉 /cc @sufail

}

// Require all return states to return back to the same rule
// that p is in.
Copy link
Member Author

Choose a reason for hiding this comment

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

📝 We are eliminating lookahead for one outgoing edge. This will affect all of the ATN configurations represented by the prediction context graph, so we need to verify that all of the configurations are affected by the ambiguity, hence why we verify the target of all return states.

if (i == 0 && p.getStateType() == ATNState.STAR_LOOP_ENTRY && ((StarLoopEntryState)p).isPrecedenceDecision) {
boolean suppress = !config.context.isEmpty();
int limit = config.context.size();
if (config.context.hasEmptyPath()) {
Copy link
Member Author

Choose a reason for hiding this comment

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

❗️ This is likely a bug. If we have an empty path we should automatically not suppress the edge.

Copy link
Member Author

Choose a reason for hiding this comment

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

➡️ Fixed

}

if (!suppress) {
break;
Copy link
Member Author

Choose a reason for hiding this comment

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

❗️ Should be the following (copy paste error):

if (suppress) {
  continue;
}

continue;
}

ATNState returnState = atn.states.get(config.context.getReturnState(j));
Copy link
Member Author

Choose a reason for hiding this comment

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

💡 No need to get the ATNState if we just need the state number.

@sharwell
Copy link
Member Author

@qwerppoo I ran your unit test from #994 using this branch. I had to modify it to use System.nanoTime() and increase the number of iterations to 2000, but it seems overall you're looking at an average ratio of ~1.03. Iteration 2000 completed in 14ms.

@parrt parrt changed the title Implement dynamic disambiguation Implement left-recursive rule optimization Nov 23, 2016
continue;
}

int returnStateNumber = config.context.getReturnState(j);
Copy link
Member

Choose a reason for hiding this comment

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

This can move out of inner loop.

Copy link
Member

Choose a reason for hiding this comment

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

Don't bother fixing as I've pulled and factored into separate method...

// Further check to make sure this isn't a 0-precedence entry.
// See antlr/antlr4#679.
if (suppress) {
RuleStopState ruleStopState = atn.ruleToStopState[p.ruleIndex];
Copy link
Member

Choose a reason for hiding this comment

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

Can't we test something simpler here? Perhaps we verify that all returnStateNumber values are the same after checking they are in the same rule? Why bother with FOLLOW edges?

continue;
}

if (((EpsilonTransition)transition).outermostPrecedenceReturn() != p.ruleIndex) {
Copy link
Member

Choose a reason for hiding this comment

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

Can you help me understand why precedence DFA stuff comes into play here?

Copy link
Member Author

Choose a reason for hiding this comment

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

outermostPrecedenceReturn labels edges in the ATN which return from an LR rule invocation where the precedence was 0. All the return edges for non-zero precedence go to the block end state that we're looking for.

@parrt
Copy link
Member

parrt commented Nov 24, 2016

I'm closing after manually pulling most of this into my own version (that is easy for my brain to handle ha!). #1404

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