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

2022-09-04 23:26:18

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

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

它产生了一个关系表达式(因此是一个相等表达式),而它反过来又可以用作相等表达式规则中的LHS,该规则产生一个相等表达式。foo instanceof Barfoo instanceof Bar == false

但是当查看第18章中的语法时,他们将其简化了一点:

Expression2:
  Expression3 [Expression2Rest]

Expression2Rest:
  { InfixOp Expression3 }
  instanceof Type

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

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


答案 1

这个问题值得一个好的答案,所以让我们仔细看看。

仅基于第18章中的语法:

任何带有 InfixOp 的东西(例如)要么适合 Expression2Rest,要么什么都不适合。而 Expression2Rest 只属于 Expression2 内部。因此,如果是合法的Java,这意味着它必须是Expression3==foo instanceof Bar == falsefoo instanceof Bar

表达式2 :
表达式3 [表达式2Rest]

Expression2Rest:
{InfixOp Expression3}
instanceof Type

但不是表达式3。没有 PrefixOp,也没有强制转换,因此要成为 Expression3,它必须是主表达式 3。但它就是不合适。foo instanceof Bar

表达式 3:
前缀Op 表达式 3
(表达式 |类型) 表达式3
主 { 选择器 } { 后缀操作 }

Primary:
Literal
ParExpression
this [Arguments]
super SuperSendfix
new Creator
NonWildcardTypeArguments (ExplicitGenericInvocationSendix |参数)
标识符 {Identifier } [IdentifierSendix]
BasicType { [] }* .class
void.class

结论:仅基于第18章中提出的语法,不是合法的Java表达式。!?!?!foo instanceof Bar == false

当然,这是无稽之谈。 产生布尔结果,该结果当然可以与 进行比较。表达式将编译并运行。foo instanceof Barfalse

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

第2.3节规定:

Java 编程语言的语法在第 4、6-10、14 和 15 章中给出。...第18章还给出了Java编程语言的语法语法,比阐述更适合实现。

根据第15章中提出的语法规则,一个合法的Java表达式。但请查看第 15.20.1 节之前的最后一句话:“关系表达式的类型始终是布尔值。这与15.20中的关系表达式规则本身直接冲突。(特别是,它意味着 的 LHS 必须计算为布尔值。这不可能是真的。foo instanceof Bar == falseinstanceof

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

我认为,如果他们稍微改变一下Expression2规则,第18章可能是正确的。这样:

*表达式 2 :
表达式 3 [ 实例类型 ]
表达式 2 {InfixOp 表达式3}

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


答案 2

推荐