4

在这里,我有以下代码:

int a,b,x;
a=b=1;
x=a+++b;

现在 的值x将是 2,因为a它首先被后递增,然后被添加到b.

以下是编译后的字节码:

 0  iconst_1
 1  dup
 2  istore_2 [b]
 3  istore_1 [a]
 4  iload_1 [a]
 5  iinc 1 1 [a]
 8  iload_2 [b]
 9  iadd
10  istore_3 [x]

所以表达式将等价于x = (a++) + b

现在另一个表达式x=a++++b,由于最大咀嚼规则而无法编译。它将成为x = (a++) ++ b编译错误。

上述行为是x=a+++b由于运算符 ++ 的优先级还是由于最大咀嚼规则

4

3 回答 3

8

引自词汇翻译

每一步都使用尽可能长的翻译,即使结果最终不会产生正确的程序,而另一个词汇翻译会。

因此,输入字符a--b被标记化(第3.5 节)为a--b,这不是任何语法正确程序的一部分,即使标记化a--b在语法上可能是 a 的一部分正确的程序。

这可以解释为什么

x=a+++b

被解析为

x=(a++)+b

另一方面,a++++b被标记为a++++b这会导致错误。

于 2014-02-25T12:16:22.547 回答
0

一元运算符“++”仅在“++”左侧有变量时才被识别。当你写 a+++b 时,第三个加号是二元运算符“add”,而第一个运算符 (++) 是“变量加 1”。当您编写“a++++”时,事情会失败,因为这就像编写a<unary increment variable by 1> <add> <add> 并且第一个运算符缺少参数。第二对加号不被识别为“增量变量”,因为 (a++) 不是变量。

现在有趣的是,Java 编译器目前确实需要空格才能正确识别

z = a++ + ++b;  // this works
z = a+++++b;    // this fails

作为一个老编译器作者,我希望这两个结构在语法上应该被评估为相同的(识别两个一元运算符 ++ 和 ++

于 2014-02-25T12:14:54.837 回答
0

最大咀嚼是在词法分析器中使用的规则,在解析器中使用运算符优先级,并且词法分析器在概念上在解析器之前运行。因此,由于最大咀嚼规则而不是运算符优先级而x=a+++b变成:x=(a++)+b

当词法分析器看到a+++b时会将其转换为标记 [identifier a] [double plus] [plus] [identifier b]。[双加] 标记是由于最大咀嚼(取最长的匹配,并且++比 长+)。然后解析器只能将其转换为 (a++)+b 而不管运算符的优先级如何。

于 2014-02-25T12:20:59.417 回答