【问题标题】:Java Grammar variable declaration production rulesJava Grammar 变量声明产生规则
【发布时间】:2017-11-30 17:37:02
【问题描述】:

如果我尝试使用大括号初始化不是数组的变量,则会出现编译错误。

例如:

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 规范文件尝试了这个)。 为什么这可能?有什么我忽略的吗?

谢谢。

【问题讨论】:

  • @ElliottFrisch 这是来自官方 Java 规范的语法。我想我们可以假设它没有错。
  • @sepp2k 我的意思是说 OP(不存在)的实现必须不完整。

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


【解决方案1】:

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

“猪在天上飞。”是一个符合语法的英语句子,但它没有意义。

您已经编写了一个语法 Java 语句,但编译失败了,因为编译不仅仅是匹配语法,类型也必须匹配(还有很多其他事情)。这里,= 的左侧是双类型变量,右侧是 double[] 类型的表达式。这两种类型都不能隐式转换,所以代码编译失败。

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2011-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-25
        • 1970-01-01
        • 2016-02-18
        • 2019-02-04
        相关资源
        最近更新 更多