介绍
要正确理解这一点,需要认识到所有现代编译器都具有两个级别的源语言识别,即词汇级别和句法级别。
词汇级别(“词法分析器”)将源代码拆分为标记:文字(字符串/数字/字符)、运算符、标识符和词汇语法的其他元素。这些是编程语言的“单词”和“标点符号”。
句法级别(“解析器”)负责将这些低级词汇标记解释为句法,通常由句法树表示。
词法分析器是需要知道标记是“减”标记(-
)还是“减量”(--
)标记的级别。(减号是一元减号还是二元减号,减量记号是后减记号还是前减记号在句法级别确定)
诸如优先级和从左到右与从右到左之类的东西只存在于句法级别。但是否a---b
是a -- - b
或是a - -- b
在词汇层面决定的。
回答
为什么a---b
会a -- - b
在Java 语言规范第 3.2 节“词法翻译”中描述:
每一步都使用尽可能长的翻译,即使结果最终不会产生正确的程序,而另一个词汇翻译会。
这样就形成了可能最长的词法标记。
在 的情况下a---b
,它使标记a
, --
(最长)然后是唯一可能的下一个标记-
, 然后b
。
在 的情况下a-----b
,它将被翻译成a
, --
, --
, -
, b
, 这在语法上是无效的。
进一步引用:
词法翻译过程有 3 个步骤,在本例中,上述适用于本例中的第 3 步:
使用以下三个词汇翻译步骤将原始 Unicode 字符流翻译成一系列标记,依次应用:
将 Unicode 字符的原始流中的 Unicode 转义(第 3.3 节)翻译成相应的 Unicode 字符。\uxxxx 形式的 Unicode 转义,其中 xxxx 是十六进制值,表示编码为 xxxx 的 UTF-16 代码单元。此转换步骤允许任何程序仅使用 ASCII 字符来表示。
将步骤 1 产生的 Unicode 流转换为输入字符和行终止符流(第 3.4 节)。
将步骤 2 产生的输入字符流和行终止符转换为输入元素序列(第 3.5 节),在丢弃空格(第 3.6 节)和注释(第 3.7 节)之后,这些元素组成了标记(第 3.5 节)它们是句法文法的终结符号(第 2.3 节)。
(“输入元素”是“令牌”)