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

标签 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,但没有找到答案。

最佳答案

介绍

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

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

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

词法分析器是需要知道标记是“减号”标记 (-) 还是“递减”(--) 标记的级别。 (minus token是一元还是binary minus,或者decrement token是后减token还是pre decrement token在句法层面判断)

诸如优先级和从左到右与从右到左之类的东西只存在于句法层面。但是 a---ba -- - b 还是 a - -- b 是由词法层面决定的。

回答

为什么 a---b 变成 a -- - bJava Language Specification section 3.2 "Lexical Translations" 中有描述:

The longest possible translation is used at each step, even if the result does not ultimately make a correct program while another lexical translation would.

这样就形成了最长可能的词法记号。

a---b 的情况下,它使标记 a--(最长)然后是唯一可能的下一个标记 -,然后是 b

a-----b的情况下,它会被翻译成a--- --b,这在语法上是无效的。

进一步引用:

词汇翻译过程有3个步骤,在本例中,以上适用于本例中的第3步:

A raw Unicode character stream is translated into a sequence of tokens, using the following three lexical translation steps, which are applied in turn:

  1. A translation of Unicode escapes (§3.3) in the raw stream of Unicode characters to the corresponding Unicode character. A Unicode escape of the form \uxxxx, where xxxx is a hexadecimal value, represents the UTF-16 code unit whose encoding is xxxx. This translation step allows any program to be expressed using only ASCII characters.

  2. A translation of the Unicode stream resulting from step 1 into a stream of input characters and line terminators (§3.4).

  3. A translation of the stream of input characters and line terminators resulting from step 2 into a sequence of input elements (§3.5) which, after white space (§3.6) and comments (§3.7) are discarded, comprise the tokens (§3.5) that are the terminal symbols of the syntactic grammar (§2.3).

(“输入元素”是“标记”)

关于自减/自增运算符的Java表达式解释规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36061185/

相关文章:

java - java程序员用什么文本编辑器?

javascript - 简单的ajax无法工作,可能是语法错误

MySQL触发器用户声明变量

javascript - 我可以使用Python从javascript代码获取[变量名称,值]表吗?

parsing - 更改 antlr lexer 解析器以支持 "and"和 "or"关键字

java - 如何在接口(interface)中定义构造函数签名?

java - 逐行比较文本文件与动态变量

java - 更新 CardLayout 的子级(面板)

php - PDO错误:SQLSTATE[42000]: Syntax error or access violation: 1064

c - 编写 C 编译器时应该如何解析关键字?