19.1.1 Problem #1: Names Too Specific

Consider the two groups of productions:

PackageName:
Identifier
PackageName . Identifier
TypeName:
Identifier
PackageName . Identifier

and:

MethodName:
Identifier
AmbiguousName . Identifier
AmbiguousName:
Identifier
AmbiguousName . Identifier

Now consider the partial input:

class Problem1 { int m() { hayden.

When the parser is considering the token hayden, with one-token lookahead to symbol ".", it cannot yet tell whether hayden should be a PackageName that qualifies a type name, as in:

hayden.Dinosaur rex = new Hayden.Dinosaur(2);

or an AmbiguousName that qualifies a method name, as in:

hayden.print("Dinosaur Rex!");

Therefore, the productions shown above result in a grammar that is not LALR(1). There are also other problems with drawing distinctions among different kinds of names in the grammar.

The solution is to eliminate the nonterminals PackageName, TypeName, ExpressionName, MethodName, and AmbiguousName, replacing them all with a single nonterminal Name:

Name:
SimpleName
QualifiedName
SimpleName:
Identifier
QualifiedName:
Name
. Identifier

A later stage of compiler analysis then sorts out the precise role of each name or name qualifier.

For related reasons, these productions in §4.3:

ClassOrInterfaceType:
ClassType
InterfaceType
ClassType:
TypeName
InterfaceType:
TypeName

were changed to:

ClassOrInterfaceType:
Name
ClassType:
ClassOrInterfaceType
InterfaceType:
ClassOrInterfaceType