-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Open
Labels
Description
Ambiguity of statement/expression
and localVariableDeclaration
LocalVariableDeclaration.java is an example that demonstrates an error in the current Antlr grammar.
import java.util.ArrayList;
public class LocalVariableDeclaration {
public static void main(String[] args)
{
ArrayList<Integer> myList = new ArrayList<Integer>();
myList.add(2);
var myVal = myList.get(0);
}
}
This input can be parsed two ways: one as a statement/expression
, and the other as a localVariableDeclaration
.
../examples/LocalVariableDeclaration.java.d=128.a=1: (compilationUnit (importDeclaration (IMPORT "import") (qualifiedName (identifier (IDENTIFIER "java")) (DOT ".") (identifier (IDENTIFIER "util")) (DOT ".") (identifier (IDENTIFIER "ArrayList"))) (SEMI ";")) (typeDeclaration (classOrInterfaceModifier (PUBLIC "public")) (classDeclaration (CLASS "class") (identifier (IDENTIFIER "LocalVariableDeclaration")) (classBody (LBRACE "{") (classBodyDeclaration (modifier (classOrInterfaceModifier (PUBLIC "public"))) (modifier (classOrInterfaceModifier (STATIC "static"))) (memberDeclaration (methodDeclaration (typeTypeOrVoid (VOID "void")) (identifier (IDENTIFIER "main")) (formalParameters (LPAREN "(") (formalParameterList (formalParameter (typeType (classOrInterfaceType (typeIdentifier (IDENTIFIER "String"))) (LBRACK "[") (RBRACK "]")) (variableDeclaratorId (identifier (IDENTIFIER "args"))))) (RPAREN ")")) (methodBody (block (LBRACE "{") (blockStatement (localVariableDeclaration (typeType (classOrInterfaceType (typeIdentifier (IDENTIFIER "ArrayList")) (typeArguments (LT "<") (typeArgument (typeType (classOrInterfaceType (typeIdentifier (IDENTIFIER "Integer"))))) (GT ">")))) (variableDeclarators (variableDeclarator (variableDeclaratorId (identifier (IDENTIFIER "myList"))) (ASSIGN "=") (variableInitializer (expression (NEW "new") (creator (createdName (identifier (IDENTIFIER "ArrayList")) (typeArgumentsOrDiamond (typeArguments (LT "<") (typeArgument (typeType (classOrInterfaceType (typeIdentifier (IDENTIFIER "Integer"))))) (GT ">")))) (classCreatorRest (arguments (LPAREN "(") (RPAREN ")"))))))))) (SEMI ";")) (blockStatement (statement (expression (expression (primary (identifier (IDENTIFIER "myList")))) (DOT ".") (methodCall (identifier (IDENTIFIER "add")) (arguments (LPAREN "(") (expressionList (expression (primary (literal (integerLiteral (DECIMAL_LITERAL "2")))))) (RPAREN ")")))) (SEMI ";"))) (blockStatement (localVariableDeclaration (VAR "var") (identifier (IDENTIFIER "myVal")) (ASSIGN "=") (expression (expression (primary (identifier (IDENTIFIER "myList")))) (DOT ".") (methodCall (identifier (IDENTIFIER "get")) (arguments (LPAREN "(") (expressionList (expression (primary (literal (integerLiteral (DECIMAL_LITERAL "0")))))) (RPAREN ")"))))) (SEMI ";")) (RBRACE "}")))))) (RBRACE "}")))) (EOF ""))
../examples/LocalVariableDeclaration.java.d=128.a=3: (compilationUnit (importDeclaration (IMPORT "import") (qualifiedName (identifier (IDENTIFIER "java")) (DOT ".") (identifier (IDENTIFIER "util")) (DOT ".") (identifier (IDENTIFIER "ArrayList"))) (SEMI ";")) (typeDeclaration (classOrInterfaceModifier (PUBLIC "public")) (classDeclaration (CLASS "class") (identifier (IDENTIFIER "LocalVariableDeclaration")) (classBody (LBRACE "{") (classBodyDeclaration (modifier (classOrInterfaceModifier (PUBLIC "public"))) (modifier (classOrInterfaceModifier (STATIC "static"))) (memberDeclaration (methodDeclaration (typeTypeOrVoid (VOID "void")) (identifier (IDENTIFIER "main")) (formalParameters (LPAREN "(") (formalParameterList (formalParameter (typeType (classOrInterfaceType (typeIdentifier (IDENTIFIER "String"))) (LBRACK "[") (RBRACK "]")) (variableDeclaratorId (identifier (IDENTIFIER "args"))))) (RPAREN ")")) (methodBody (block (LBRACE "{") (blockStatement (statement (expression (expression (expression (expression (primary (identifier (IDENTIFIER "ArrayList")))) (LT "<") (expression (primary (identifier (IDENTIFIER "Integer"))))) (GT ">") (expression (primary (identifier (IDENTIFIER "myList"))))) (ASSIGN "=") (expression (NEW "new") (creator (createdName (identifier (IDENTIFIER "ArrayList")) (typeArgumentsOrDiamond (typeArguments (LT "<") (typeArgument (typeType (classOrInterfaceType (typeIdentifier (IDENTIFIER "Integer"))))) (GT ">")))) (classCreatorRest (arguments (LPAREN "(") (RPAREN ")")))))) (SEMI ";"))) (blockStatement (statement (expression (expression (primary (identifier (IDENTIFIER "myList")))) (DOT ".") (methodCall (identifier (IDENTIFIER "add")) (arguments (LPAREN "(") (expressionList (expression (primary (literal (integerLiteral (DECIMAL_LITERAL "2")))))) (RPAREN ")")))) (SEMI ";"))) (blockStatement (localVariableDeclaration (VAR "var") (identifier (IDENTIFIER "myVal")) (ASSIGN "=") (expression (expression (primary (identifier (IDENTIFIER "myList")))) (DOT ".") (methodCall (identifier (IDENTIFIER "get")) (arguments (LPAREN "(") (expressionList (expression (primary (literal (integerLiteral (DECIMAL_LITERAL "0")))))) (RPAREN ")"))))) (SEMI ";")) (RBRACE "}")))))) (RBRACE "}")))) (EOF ""))
The incorrect parse, where ArrayList<Integer> myList = new ArrayList<Integer>();
is parsed as a statement/expression
, interprets the <
and >
in the type declaration as comparison operators.
This must be corrected. There are probably several ways to fix this. One is to use a hack that recognizes a template.