I was looking at the JLS Chapter 19 grammar trying to figure out how a simple field access is parsed:
obj.field
It looks to me like the fir
Well, as you already noted, obj
is not a Primary, hence, the production Primary.
Identifier does not apply to obj.field
. Since no super
key is involved, the other alternatives don’t apply either, so the entire FieldAccess does not apply.
This is nothing to worry, as this is only a named grammar rule, not a necessary requirement for letting Java source code access a field.
As you also noted, PostfixExpression includes Primary, but not only that, it also includes ExpressionName:
ExpressionName:
Identifier
AmbiguousName . Identifier
AmbiguousName:
Identifier
AmbiguousName . Identifier
So obj.field
matches ExpressionName, thus, matches PostfixExpression. Now, there is a long chain of productions from Expression to PostfixExpression, incorporating the entire operator precedence rules, but simply said, a PostfixExpression is allowed everywhere, where an Expression is allowed.
There’s one notable divergence, assignments:
Assignment:
LeftHandSide AssignmentOperator Expression
LeftHandSide:
ExpressionName
FieldAccess
ArrayAccess
Assignments are expressions, so they may also appear on the right-hand side of an assignment, however, the left-hand side is special. There, we see FieldAccess, to which obj.field
(unintuitively) not belongs, as well as ExpressionName, which obj.field
matches.
Maybe it helps to keep in mind, that when obj.field
is parsed, the parser doesn’t know that it is a field access. It might also be the case that obj
is a package and field
is a class name or that obj
is a class name and field
is an inner class name. It is the surrounding context that will require it to be resolved to field (and it still could be a static
field in a class obj
).
The FieldAccess production lists those cases that unambiguously are a field access, recognizable at parsing time, without looking at its surrounding context.