Java7 规范中的语法真的等同吗?

Is the grammars in Java7 spec really equivalent?

JLS v7 chapter 18 中的语法似乎与文档中其他地方的结构不同,但对我来说似乎存在差异。具体在第 15 章中的规则是:

RelationalExpression:
  ShiftExpression
  RelationalExpression < ShiftExpression
  RelationalExpression > ShiftExpression
  RelationalExpression <= ShiftExpression
  RelationalExpression >= ShiftExpression
  RelationalExpression instanceof ReferenceType

这使得 foo instanceof Bar 成为一个 RelationalExpression(因此成为一个 EqualityExpresson),它又可以在 EqualityExpression 规则中用作 LHS,这使得 foo instanceof Bar == false 成为一个 EqualityExpression。

但是在查看第 18 章中的语法时,他们对其进行了一些简化:

Expression2:
  Expression3 [Expression2Rest]

Expression2Rest:
  { InfixOp Expression3 }
  instanceof Type

这看起来很奇怪,这意味着我们可以用二元运算符将 Expression3 链接在一起,或者我们可以检查一个 Expression3 的类型。具体来说,现在 foo instanceof BarExpression2,但我认为使用 Expression2 作为相等比较的 LHS 是无效的。

我是否遗漏了第 18 章语法中使 foo instanceof Bar == false 成为有效表达式的内容?请注意,根据第 15 章中的规则和我的编译器,它是一个有效的表达式。

这个问题值得好好回答,让我们仔细看看。

仅基于第 18 章中的语法:

任何带有 InfixOp(例如 ==)的东西要么适合 Expression2Rest,要么什么都不适合。而 Expression2Rest 只属于 Expression2。所以,如果 foo instanceof Bar == false 是合法的 Java,那意味着 foo instanceof Bar 必须是 Expression3.

Expression2 :
Expression3 [Expression2Rest]

Expression2Rest:
{InfixOp Expression3}
instanceof Type

但是 foo instanceof Bar 不是 Expression3。没有 PrefixOp 也没有转换,所以要成为 Expression3,它必须是 Primary。但是就是不合适。

Expression3:
PrefixOp Expression3
( (Expression | Type) ) Expression3
Primary { Selector } { PostfixOp }

Primary:
Literal
ParExpression
this [Arguments]
super SuperSuffix
new Creator
NonWildcardTypeArguments (ExplicitGenericInvocationSuffix | this Arguments)
Identifier { . Identifier } [IdentifierSuffix]
BasicType { [] }* .class
void.class

结论:仅根据第 18 章中介绍的语法,foo instanceof Bar == false 不是合法的 Java 表达式。 !?!?!

当然是废话。 foo instanceof Bar 产生一个布尔结果,并且该结果当然可以与 false 进行比较。表达式编译并 运行s.

更好的结论:第 18 章不是权威,但本书的其余部分是。

第 2.3 节指出

A syntactic grammar for the Java programming language is given in Chapters 4, 6-10, 14, and 15. ... Chapter 18 also gives a syntactic grammar for the Java programming language, better suited to implementation than exposition.

根据第15章的文法规则,foo instanceof Bar == false一个合法的Java表达式。但是请查看第 15.20.1 节之前的最后一句话:"The type of a relational expression is always boolean." 这与 15.20 中的 RelationalExpression 规则本身直接冲突。 (特别是,它暗示 instanceof 的 LHS 必须计算为 布尔值 。)这不可能是真的。

最佳结论:这本书有问题。如果你想知道某个东西是否合法Java,你必须编译并运行它,最好是在Oracle的参考实现上。即便如此,也可能存在错误。毕竟,它只是软件。

而且我认为,如果他们稍微更改 Expression2 规则,第 18 章可能是正确的。像这样:

*Expression2 :
Expression3 [ instanceof Type ]
Expression2 {InfixOp Expression3}

但谁知道呢,这可能会导致其他问题。无论如何,它已固定在 Java 8.