[java] Make new java expression grammar stricter#1855
Merged
Conversation
adangel
approved these changes
Jun 16, 2019
adangel
left a comment
Member
There was a problem hiding this comment.
Nice job! 👍
I've tried to update https://github.com/pmd/pmd/wiki/PMD-7.0.0-Java
I tested the parser on the spring framework and the JDK 12 sources
Sounds like we should add openjd12 sources some time to pmd-regression-tester...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This makes the grammar of expressions much stricter than what it is currently on this branch. Currently eg
foo()()"parses", but the jjtClose of ASTMethodCall fails, so we get a very undescriptive error message. Other absurdities likea::b[0]::care parsed and end up in the final tree... Now we get regular syntax errors.It also optimises the lookaheads in primary expression, although from what I measured:
I tested the parser on the spring framework and the JDK 12 sources, and added some test cases when I found a few bugs (actually #1843 comes from JDK 12). It can parse those with no problem now.
I didn't add any negative tests, maybe we should do that
Details:
The change doesn't touch many things apart from the parser. I made it so though, that we rely less on jjtClose hooks and more on the parser directly. Some more nodes are LeftRecursiveNodes, but that just means that they get injected with some additional children to their left (the interface name has become not really descriptive).
We can also most of the time avoid using
jjtree.extendLeft()and only use regular jjtree nodes with a definite number of children (but the the node needs to implement LeftRecursiveNode to fix the tokens).The change to the parser boils down to making PrimarySuffix much dumber. It can actually only be a field access, method call, array access or method reference now. When the first method reference is parsed, we stop the iteration, to make eg.
expr::foo.barimpossible.PrimaryPrefix is split into two steps for readability. The production takes care of any start token that is not an ambiguous name. If the expression starts with an ambiguous name though (and only then), we follow to the next step, as still more options are possible than in primary suffix. Then we start iterating PrimarySuffix.