Cleanup grammar
This commit is contained in:
Clément Fournier
committed by
Andreas Dangel
parent
e83ae65dad
commit
1966a7648c
@ -479,6 +479,17 @@ public class JavaParser {
|
||||
}
|
||||
}
|
||||
|
||||
private void forceTypeContext() {
|
||||
Node top = jjtree.peekNode();
|
||||
|
||||
if (top instanceof ASTAmbiguousName) {
|
||||
// see doc on the method
|
||||
Node replacement = ((ASTAmbiguousName) top).forceTypeContext();
|
||||
jjtree.popNode();
|
||||
jjtree.pushNode(replacement);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
PARSER_END(JavaParser)
|
||||
|
||||
@ -2040,13 +2051,6 @@ void ArrayTypeDim():
|
||||
void ReferenceType() #void:
|
||||
{}
|
||||
{
|
||||
|
||||
// TODO TypeVariable is ambiguous with ClassOrInterfaceType
|
||||
// but I think it would be good to have a node for it nevertheless
|
||||
// to help typeres, since TypeVariables have special types (intersection types)
|
||||
// This could be handled in a rewrite phase, which is necessary for
|
||||
// disambiguation. Since type parameters shadow anything, their disambiguation
|
||||
// is stable regardless of classpath config.
|
||||
( PrimitiveType() Dims() ) #ArrayType
|
||||
| ( ClassOrInterfaceType() [ LOOKAHEAD(2) Dims() ] ) #ArrayType(>1)
|
||||
}
|
||||
@ -2059,20 +2063,12 @@ void ReferenceType() #void:
|
||||
void ClassOrInterfaceType() #void:
|
||||
{}
|
||||
{
|
||||
|
||||
|
||||
|
||||
/*
|
||||
FIXME We gobble up all identifiers until we find
|
||||
either type arguments or annotations, because
|
||||
it may be a FQCN, e.g. java.util.List is a single node.
|
||||
|
||||
But java.util.Map.Entry should be two nodes ((java.util.Map).Entry)
|
||||
I would have said this doesn't matter but the other fixme comment just
|
||||
below shows we need a rewrite phase anyway
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
First, gobble up all identifiers until the first type arguments
|
||||
or annotation is found. The name is ambiguous between package or
|
||||
@ -2095,10 +2091,9 @@ void ClassOrInterfaceType() #void:
|
||||
|
||||
/*
|
||||
Now if there are other segments, either the previous segment specified type
|
||||
arguments, or the next has an annotation.
|
||||
|
||||
Each of the following segments is its own ClassOrInterfaceType which encloses the
|
||||
previous one. The resulting structure appears left-recursive, but the parser just
|
||||
arguments, or the next has an annotation. Either way we know that all the
|
||||
following segments is a type name. Each segment is parsed as its own ClassOrInterfaceType
|
||||
which encloses the previous one. The resulting structure appears left-recursive, but the parser just
|
||||
executes a loop. That scheme preserves the position of type arguments and annotations.
|
||||
See #1150.
|
||||
*/
|
||||
@ -2111,14 +2106,7 @@ void ClassOrInterfaceType() #void:
|
||||
[ LOOKAHEAD( "<" ) TypeArguments() ]
|
||||
) #ClassOrInterfaceType
|
||||
)*
|
||||
{
|
||||
Node top = jjtree.peekNode();
|
||||
if (top instanceof ASTAmbiguousName) {
|
||||
Node replacement = ((ASTAmbiguousName) top).forceTypeContext();
|
||||
jjtree.popNode();
|
||||
jjtree.pushNode(replacement);
|
||||
}
|
||||
}
|
||||
{ forceTypeContext(); }
|
||||
}
|
||||
|
||||
|
||||
@ -2231,19 +2219,7 @@ void Expression() #AssignmentExpression(>1):
|
||||
AssignmentOp AssignmentOperator() #void:
|
||||
{}
|
||||
{
|
||||
( "="
|
||||
| "*="
|
||||
| "/="
|
||||
| "%="
|
||||
| "+="
|
||||
| "-="
|
||||
| "<<="
|
||||
| ">>="
|
||||
| ">>>="
|
||||
| "&="
|
||||
| "^="
|
||||
| "|="
|
||||
)
|
||||
( "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|=" )
|
||||
{return AssignmentOp.fromImage(getToken(0).getImage());}
|
||||
}
|
||||
|
||||
@ -3232,8 +3208,10 @@ String VoidName() #void:
|
||||
}
|
||||
|
||||
// This is used to get JJTree to generate a node.
|
||||
// Since variable references are most of the time ambiguous, they're
|
||||
// not created directly by the parser
|
||||
// Variable references are always ambiguous
|
||||
// when they're parsed, so they're not created
|
||||
// normally by jjtree, but rather by the disambiguation
|
||||
// hooks spread across the parser
|
||||
//noinspection JavaCCJccUnusedProduction
|
||||
void VariableReference():
|
||||
{}
|
||||
|
@ -39,8 +39,9 @@ import net.sourceforge.pmd.lang.java.xpath.SemanticAmbiguityChecker;
|
||||
*
|
||||
* <blockquote>
|
||||
* A name is syntactically classified as an ExpressionName in these contexts:
|
||||
* ...
|
||||
* - As the qualifying expression in a qualified class instance creation expression (§15.9)*
|
||||
* ...
|
||||
* - As the qualifying expression in a qualified class instance creation
|
||||
* expression (§15.9)
|
||||
* </blockquote>
|
||||
*
|
||||
* We don't know at the moment the name is parsed that it will be
|
||||
@ -49,13 +50,15 @@ import net.sourceforge.pmd.lang.java.xpath.SemanticAmbiguityChecker;
|
||||
* expression. In that case, the name can be reclassified, and e.g. if
|
||||
* it's a simple name be promoted to {@link ASTVariableReference}. This
|
||||
* type of immediate disambiguation is carried out by the {@link AbstractJavaNode#jjtClose()}
|
||||
* method of those nodes that can be pushed.
|
||||
* method of those nodes that do force a specific context on their
|
||||
* left-hand side. See also {@link LeftRecursiveNode}.
|
||||
*
|
||||
* <p>Another mechanism is {@link #forceExprContext()} and {@link #forceTypeContext()},
|
||||
* which are called by the parser to promote an ambiguous name to an
|
||||
* expression or a type when it's sure they must be one.
|
||||
* expression or a type when exiting from the {@link JavaParser#PrimaryExpression()}
|
||||
* production or {@link JavaParser#ClassOrInterfaceType()}.
|
||||
*
|
||||
* <p>These two mechanisms perform the first classification step, the
|
||||
* <p>Those two mechanisms perform the first classification step, the
|
||||
* one that only depends on the syntactic context and not on semantic
|
||||
* information. A second pass on the AST after building the symbol tables
|
||||
* would allow us to remove all the remaining ambiguous names.
|
||||
@ -100,6 +103,7 @@ public final class ASTAmbiguousName extends AbstractJavaTypeNode implements ASTR
|
||||
return getImage();
|
||||
}
|
||||
|
||||
|
||||
public List<String> getSegments() {
|
||||
return Arrays.asList(getImage().split("\\."));
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ package net.sourceforge.pmd.lang.java.ast;
|
||||
*
|
||||
* <p>This is only relevant to node construction and is package private.
|
||||
*
|
||||
*
|
||||
* @author Clément Fournier
|
||||
*/
|
||||
interface LeftRecursiveNode {
|
||||
|
@ -30,12 +30,7 @@ public final class SemanticAmbiguityChecker {
|
||||
|
||||
}
|
||||
|
||||
public static SemanticAmbiguityResult semanticCheck(Node node) {
|
||||
if (!(node instanceof ASTAmbiguousName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ASTAmbiguousName name = (ASTAmbiguousName) node;
|
||||
public static SemanticAmbiguityResult semanticCheck(ASTAmbiguousName name) {
|
||||
|
||||
if (name.jjtGetParent() instanceof ASTExpression) {
|
||||
|
||||
|
Reference in New Issue
Block a user