【问题标题】:Operator precedence or Maximal Munch Rule comes first for Unary Operators一元运算符优先考虑运算符优先级或最大蒙克规则
【发布时间】:2014-02-25 12:03:47
【问题描述】:

这里我有以下代码:

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的上述行为是因为运算符的优先级 ++还是因为最大咀嚼规则

【问题讨论】:

  • 因为吃得最多。
  • @devnull,JVM 规范或 JLS 中是否提到过,或者您对此有何解释?
  • 不应该是 3 吗? a=1, b=1,那么你做 (a++) + b = (1+1)+1 是 3?
  • @CodeChimp a++ 递增 a 但返回其原始值。 ++a 将返回递增值。
  • @Zeeshan 是的,它在规范中被引用。

标签: java operator-precedence unary-operator


【解决方案1】:

引用Lexical Translations:

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

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

这可以解释原因

x=a+++b

被解析为

x=(a++)+b

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

【讨论】:

  • 您好,downvoter,请您留言以便改进答案吗?
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    一元运算符“++”仅在“++”左侧有变量时才被识别。当你写 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-03-25
      • 2022-12-04
      • 2011-07-07
      • 2023-03-07
      • 2011-01-09
      • 1970-01-01
      • 2010-12-19
      相关资源
      最近更新 更多