Java语法变量声明生成规则

时间:2017-11-30 17:37:03

标签: java compiler-errors compilation grammar variable-declaration

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

E.g:

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规范文件,其中指定了语法)。 为什么这可能?有什么我忽略的吗?

谢谢。

3 个答案:

答案 0 :(得分:2)

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

"猪在天空中飞翔。"是一个语法英语句子,但它没有意义。

您编写了一个语法Java语句,但编译失败,因为编译不只是匹配语法,类型也必须匹配(在更多其他事情之中)。这里,=的左侧是双类型变量,右侧是类型double[]的表达式。这两种类型不可隐式转换,因此代码无法编译。

要成功编译,请尝试将double更改为double[]

答案 1 :(得分:2)

使用语法,您可以成功解析您的代码,javac也是如此(请注意javac的错误消息并未说明" [预期",这将是它为解析错误产生的消息)。但是编译不仅仅涉及解析 - 它还涉及类型检查,当代码没有进行类型检查时,它就不会编译。

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

程序输入良好的规则也是规范的一部分,但与语法分开。这些规则禁止double a = {1.5,6.3};int x = "lala";等内容。

答案 2 :(得分:1)

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