sky*_*ing 13 java grammar language-lawyer java-7
JLS v7 第18章中的语法似乎与文档中其他地方的结构不同,但对我来说似乎存在差异.特别是在第15章中,规则是:
RelationalExpression:
ShiftExpression
RelationalExpression < ShiftExpression
RelationalExpression > ShiftExpression
RelationalExpression <= ShiftExpression
RelationalExpression >= ShiftExpression
RelationalExpression instanceof ReferenceType
Run Code Online (Sandbox Code Playgroud)
这使得foo instanceof Bar一个RelationalExpression(因此也就是一个EqualityExpresson)可以在EqualityExpression规则中用作LHS,该规则产生foo instanceof Bar == false一个EqualityExpression.
但是在查看第18章中的语法时,他们对它进行了简化:
Expression2:
Expression3 [Expression2Rest]
Expression2Rest:
{ InfixOp Expression3 }
instanceof Type
Run Code Online (Sandbox Code Playgroud)
这看起来很奇怪,这意味着我们可以将Expression3二进制运算符链接在一起,或者我们可以检查一个类型Expression3.具体现在foo instanceof Bar是一个Expression2,但我没有看到使用Expression2平等比较的LHS 是有效的.
我是否错过了第18章的语法中的某些内容foo instanceof Bar == false?请注意,根据第15章中的规则并根据我的编译器,它是一个有效的表达式.
这个问题值得一个很好的答案,所以让我们仔细看看。
仅基于第 18 章中的语法:
任何带有InfixOp 的东西(例如==)要么适合Expression2Rest,要么什么都不适合。而Expression2Rest只属于Expression2内部。因此,如果foo instanceof Bar == false是合法的 Java,则意味着它foo instanceof Bar必须是Expression3。
表达式2 :
表达式3 [表达式2Rest]Expression2Rest:
{InfixOp Expression3}
实例 类型
但foo instanceof Bar不是Expression3。没有PrefixOp也没有强制转换,因此要成为Expression3,它必须是Primary。但它就是不适合。
表达式 3:
PrefixOp 表达式 3
( (表达式|类型) ) 表达式 3
主 { 选择器 } { PostfixOp }主要:
文字
ParExpression
this [Arguments]
super SuperSuffix
new Creator
NonWildcardTypeArguments (ExplicitGenericInitationSuffix | this Arguments)
Identifier { . 标识符 } [IdentifierSuffix]
BasicType { [] }* .class
void.class
结论:仅基于第 18 章中介绍的语法,foo instanceof Bar == false不是合法的 Java 表达式。!?!?!
当然这是废话。foo instanceof Bar产生一个布尔结果,并且该结果当然可以与 进行比较false。表达式编译并运行。
更好的结论:第 18 章并不具有权威性,但本书的其余部分具有权威性。
第 2.3 节指出
第 4、6-10、14 和 15 章给出了 Java 编程语言的语法语法。...第 18 章还给出了 Java 编程语言的语法语法,它更适合于实现而不是阐述。
根据第15章给出的语法规则,foo instanceof Bar == false 是一个合法的Java表达式。但请查看第 15.20.1 节之前的最后一句:“关系表达式的类型始终是boolean。” 这与 15.20 中的RelationalExpression规则本身直接冲突。(特别是,它意味着 LHS 必须instanceof计算为boolean。)这不可能是真的。
最佳结论:这本书有问题。如果你想知道某个东西是否是合法的 Java,你必须编译并运行它,最好是在 Oracle 的参考实现上。即使这样也可能存在错误。毕竟,它只是软件。
我认为如果他们稍微改变一下Expression2规则,第 18 章可能是正确的。就像这样:
*表达式 2 :
表达式 3 [类型 实例 ]
表达式 2 {InfixOp 表达式 3}
但谁知道,这可能会导致其他问题。无论如何,它在 Java 8 中得到了修复。
| 归档时间: |
|
| 查看次数: |
341 次 |
| 最近记录: |