JLS语法如何匹配简单的字段访问(obj.f)?
How does the JLS grammar match simple field accesses (obj.f)?
我正在查看 JLS Chapter 19 grammar 试图弄清楚如何解析简单的字段访问:
obj.field
在我看来,可能涉及 FieldAccess 生产的第一个变体
FieldAccess:
Primary .
Identifier
super
.
Identifier
TypeName .
super
.
Identifier
然后 Primary 应该参与解析 obj
部分。 Primary 似乎不涉及解析像 ExpressionName 这样的简单引用。这似乎是通过 PostfixExpression.
达到的
PostfixExpression:
Primary
ExpressionName
PostIncrementExpression
PostDecrementExpression
并且,AFAICT,PostfixExpression 不是左递归的 Primary。
我是不是漏掉了什么?
有没有其他方法可以让 Primary 在 ExpressionName 或 AmbiguousName 上触底?
编辑:
我对语法中非终结符之间的关系做了一个DOT→SVG graph。如果一条边是蓝色的,那么在箭头头部之后的非终结符的开头,非终结符会进行左递归使用。
好吧,正如您已经指出的,obj
不是 Primary,因此,产生式 Primary.
标识符不适用于obj.field
。由于不涉及 super
键,其他替代方案也不适用,因此整个 FieldAccess 不适用。
这没什么好担心的,因为这只是一个命名语法规则,并不是让 Java 源代码访问字段的必要条件。
正如您还注意到的,PostfixExpression 包括 Primary,但不仅如此,它还包括 ExpressionName:
ExpressionName:
Identifier
AmbiguousName . Identifier
AmbiguousName:
Identifier
AmbiguousName . Identifier
所以 obj.field
匹配 ExpressionName,因此匹配 PostfixExpression。现在,有一个从 Expression 到 PostfixExpression 的长链,合并了整个运算符优先级规则,但简单地说,一个 PostfixExpression 在任何地方都允许,其中 Expression 是允许的。
有一个明显的分歧,作业:
Assignment:
LeftHandSide AssignmentOperator Expression
LeftHandSide:
ExpressionName
FieldAccess
ArrayAccess
赋值是表达式,因此它们也可能出现在赋值的右侧,但是左侧比较特殊。在那里,我们看到 FieldAccess,obj.field
(不直观地)不属于它,以及 ExpressionName,obj.field
比赛。
也许记住它会有所帮助,当 obj.field
被解析时,解析器不知道它是一个字段访问。 obj
是一个包,field
是一个 class 名称,或者 obj
是一个 class 名称,而 field
是一个内部 class 名称。它是周围的上下文,需要它被解析为字段(并且它仍然可以是 class obj
中的 static
字段)。
FieldAccess 产品列出了那些明确是字段访问的情况,在解析时可识别,无需查看其周围上下文。
我正在查看 JLS Chapter 19 grammar 试图弄清楚如何解析简单的字段访问:
obj.field
在我看来,可能涉及 FieldAccess 生产的第一个变体
FieldAccess:
Primary
.
Identifier
super
.
Identifier
TypeName.
super
.
Identifier
然后 Primary 应该参与解析 obj
部分。 Primary 似乎不涉及解析像 ExpressionName 这样的简单引用。这似乎是通过 PostfixExpression.
PostfixExpression:
Primary
ExpressionName
PostIncrementExpression
PostDecrementExpression
并且,AFAICT,PostfixExpression 不是左递归的 Primary。
我是不是漏掉了什么?
有没有其他方法可以让 Primary 在 ExpressionName 或 AmbiguousName 上触底?
编辑:
我对语法中非终结符之间的关系做了一个DOT→SVG graph。如果一条边是蓝色的,那么在箭头头部之后的非终结符的开头,非终结符会进行左递归使用。
好吧,正如您已经指出的,obj
不是 Primary,因此,产生式 Primary.
标识符不适用于obj.field
。由于不涉及 super
键,其他替代方案也不适用,因此整个 FieldAccess 不适用。
这没什么好担心的,因为这只是一个命名语法规则,并不是让 Java 源代码访问字段的必要条件。
正如您还注意到的,PostfixExpression 包括 Primary,但不仅如此,它还包括 ExpressionName:
ExpressionName:
Identifier
AmbiguousName . Identifier
AmbiguousName:
Identifier
AmbiguousName . Identifier
所以 obj.field
匹配 ExpressionName,因此匹配 PostfixExpression。现在,有一个从 Expression 到 PostfixExpression 的长链,合并了整个运算符优先级规则,但简单地说,一个 PostfixExpression 在任何地方都允许,其中 Expression 是允许的。
有一个明显的分歧,作业:
Assignment:
LeftHandSide AssignmentOperator Expression
LeftHandSide:
ExpressionName
FieldAccess
ArrayAccess
赋值是表达式,因此它们也可能出现在赋值的右侧,但是左侧比较特殊。在那里,我们看到 FieldAccess,obj.field
(不直观地)不属于它,以及 ExpressionName,obj.field
比赛。
也许记住它会有所帮助,当 obj.field
被解析时,解析器不知道它是一个字段访问。 obj
是一个包,field
是一个 class 名称,或者 obj
是一个 class 名称,而 field
是一个内部 class 名称。它是周围的上下文,需要它被解析为字段(并且它仍然可以是 class obj
中的 static
字段)。
FieldAccess 产品列出了那些明确是字段访问的情况,在解析时可识别,无需查看其周围上下文。