Java语法变量声明产生式规则

Java Grammar variable declaration production rules

如果我尝试使用大括号初始化一个不是数组的变量,我会收到编译错误。

例如:

public class test1 {
    public static void main(String[] args) {

        double a = {1.5,6.3};

    }
}

使用"javac",我得到这个编译错误:

test1.java:13: error: illegal initializer for double
double a = {1.5,6.3};
           ^
1 error

不过,我正在学习 Java 语法,我发现了以下作品(来自 The Java Language Specification):

VariableDeclarators:
    VariableDeclarator
    VariableDeclarators , VariableDeclarator

VariableDeclarator:
    VariableDeclaratorId
    VariableDeclaratorId = VariableInitializer

VariableDeclaratorId:
    Identifier
    VariableDeclaratorId [ ]

VariableInitializer:
    Expression
    ArrayInitializer

ArrayInitializer:
    { VariableInitializersopt ,opt }

有了这些规则,我可以成功编译上面的代码(我用一个使用 jflex 的编译器和一个指定了语法的 .cup 规范文件试过了)。 为什么这是可能的?有什么我忽略的吗?

谢谢。

是的,语法 正确的,但没有任何意义。

"Pigs are flying in the sky."是一个符合语法的英文句子,但是没有意义。

你写了一个符合语法的 Java 语句,但是编译失败了,因为编译不仅仅是匹配语法,类型也必须匹配(还有很多其他的东西)。这里,= 的左侧是双类型变量,右侧是 double[] 类型的表达式。这 2 种类型不可隐式转换,因此代码无法编译。

为了编译成功,尝试将double改为double[]

使用语法,您可以成功 解析 您的代码,javac 也可以(请注意 javac 的错误消息不会说“[something ] 预期”,这将是它为解析错误生成的消息)。但是编译涉及的不仅仅是解析 - 它还涉及类型检查,当代码不进行类型检查时,它不会编译。

作为另一个例子,语法也允许 int x = "lala";。与您的示例一样,这可以正确解析,但会被类型检查器拒绝。

关于程序何时类型正确的规则也是规范的一部分,但与语法分开。这些规则禁止 double a = {1.5,6.3};int x = "lala";.

之类的事情

编译器在接受程序有效之前通常会经历三个阶段:词法、句法和语义。一段符合形式语法规范的代码仅在词法和句法上有效,但不一定在语义上有效。在这种情况下,将值向量分配给标量变量没有语义意义,因此它在语义上是无效的。