【问题标题】:How does a Java compiler parse typecasts?Java 编译器如何解析类型转换?
【发布时间】:2008-12-30 17:19:38
【问题描述】:

一个简单的表达式

(x) - y

根据x 是否为类型名称,解释不同。如果x 不是类型名称,则(x) - y 只是从x 中减去y。但如果 x 是类型名称,(x) - y 会计算 y 的负数并将结果值转换为类型 x

在典型的 C 或 C++ 编译器中,x 是否是类型的问题是可以回答的,因为解析器会在处理 typedef 或 struct 声明后立即将此类信息传达给词法分析器。 (我认为这种要求违反级别是 C 设计中最讨厌的部分。)

但在 Java 中,x 可能要等到源代码的后面才会定义。 Java 编译器如何消除这种表达式的歧义?

很明显,Java 编译器需要多次传递,因为 Java 不需要在使用前声明。但这似乎意味着第一遍必须在解析表达式上做一个非常草率的工作,然后在后面的一遍中做另一个更准确的表达式解析。这似乎很浪费。

有没有更好的方法?

【问题讨论】:

    标签: java parsing compiler-construction casting


    【解决方案1】:

    我想我已经找到了令我满意的解决方案。感谢 mmyers,我意识到我需要检查类型转换语法的正式规范。

    歧义是由+- 既是一元运算符又是二元运算符引起的。 Java通过这个语法解决了这个问题:

    CastExpression:
            ( PrimitiveType Dimsopt ) UnaryExpression
            ( ReferenceType ) UnaryExpressionNotPlusMinus
    

    (见http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#238146

    因此,'+''-' 在转换的 ')' 之后立即被明确禁止,除非转换使用原始类型——编译器先验地知道这些类型。

    【讨论】:

    • 我懒得去查规范(反正我也不知道去哪里看)。 +1
    【解决方案2】:

    我刚刚测试了一下,这段代码:

    Double y = new Double(0.1);
    System.out.println((Double)-y);
    

    给出编译错误:

    operator - cannot be applied to Double, java.lang.Double.

    在 -y 周围加上括号使它编译得很好。显然,Java 通过简单地在语法中不允许它来解决这个问题(如果这是正确的术语;我不是编译器专家)。

    【讨论】:

    • 我没有投反对票,但如果你使用双精度而不是双精度,编译器会允许它,因为 operator - 可以应用于双精度。我相信它因不精确而被否决。
    • 从 Java 1.5 开始,您可以将任何算术运算符与 Doubles、Floats 等一起使用(因为自动装箱)。正如我所说,添加括号使其编译没有错误。
    • +1,因为我看不出有任何理由将这个答案投反对票
    猜你喜欢
    • 1970-01-01
    • 2017-12-30
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    相关资源
    最近更新 更多