递减/递增运算符的Java表达式解释规则

时间:2016-03-17 12:55:09

标签: java syntax lexer decrement interpretation

这是一个纯粹的理论问题,为了清楚起见,我不会正常编写这段代码。

为什么这个含糊不清的陈述是合法的

int a = 1, b = 2;
int c = a---b; // a=0, b=2, c=-1

(它被解释为a-- -b

这个人不是吗?

int c = a-----b;

第一个语句可以也被解释为a- --b,而第二个语句显然只有一个逻辑解释a-- - --b

另一个好奇的人:

int c = a--- -b; // a=0, b=2, c=3

int c = a----b; 不是

如何在Java中定义表达式解释?我试过搜索JLS,但还没有找到答案。

2 个答案:

答案 0 :(得分:2)

要回答这个问题,我们必须看看Javas operators precendence

这个例子的重要规则是:

  • 表达式从左到右评估
  • expr-- Postfix运算符的优先级高于a-b添加运算符。

因此,a-----b这样的表达式将按如下方式进行评估:((a--)--)-b 非法

您可以在声明中使用大括号绕过这些规则:(a--)-(--b)将是一份法律声明。

答案 1 :(得分:2)

简介

要正确理解这一点,需要认识到所有现代编译器都有两个级别来识别源语言,词汇级别和句法级别。

词法级别(“词法分析器”)将源代码分成标记:文字(字符串/数字/字符),运算符,标识符和词法语法的其他元素。这些是编程语言的“单词”和“标点符号”。

语法级别(“解析器”)涉及将这些低级词汇标记解释为语法,通常由语法树表示。

词法分析器是需要知道令牌是“减号”令牌(-)还是“减量”(--)令牌的级别。 (减去令牌是一元还是二元减号,或者递减令牌是一个后置还是预递减令牌是在句法层面确定的)

优先级,从左到右,从右到左等事物只存在于句法层面。但是,a---ba -- - b还是a - -- b是否在词汇层面确定。

答案

Java Language Specification section 3.2 "Lexical Translations"

中描述了为什么a---b变为a -- - b
  

最长可能的翻译用于每一步,即使是   结果最终没有做出正确的计划而另一个   词汇翻译会。

因此形成了最长的词汇标记。

对于a---b,它会使令牌a--(最长)成为唯一可能的下一个令牌-,然后是b

如果是a-----b,则会将其翻译为a-----b,没有语法上的有效。

进一步引用:

词汇翻译过程分为3个步骤,在这种情况下,上述情况适用于本案例中的步骤3:

  

原始Unicode字符流被转换为序列   令牌,使用以下三个词汇翻译步骤,即   依次申请:

     
      
  1. Unicode原始流中Unicode转义(§3.3)的转换   字符到相应的Unicode字符。一个Unicode转义   形式\ uxxxx,其中xxxx是十六进制值,表示   UTF-16代码单元,其编码为xxxx。此转换步骤允许   任何只用ASCII字符表示的程序。

  2.   
  3. 将步骤1产生的Unicode流转换为   输入字符和行终止符流(§3.4)。

  4.   
  5. 输入字符流和行终止符的转换   从第2步到输入元素(§3.5)的序列,其中,   在白色空间(§3.6)和注释(§3.7)被丢弃之后,包括   令牌(§3.5)是句法的终结符号   语法(§2.3)。

  6.   

(“输入元素”是“令牌”)