为什么预处理器区分数字和字符标记?

Why does the preprocessor distinguish between number and character tokens?

根据语言规范,词法元素是这样定义的:

token:
    keyword
    identifier

    constant

    string-literal
    operator
    punctuator

preprocessing-token:
    header-name
    identifier

    pp-number
    character-constant

    string-literal
    operator
    punctuator

    each non-white-space character that cannot be one of the above

为什么在预处理token层面有数字和字符之分,而在token层面只有常量?我看不出这种区别有什么好处。

C文法中的非终结符名称不规范;它们只是为了描述而存在。正确描述行为很重要。语法本身不足以描述语言;它需要与文本一起阅读,这对格式良好的程序施加了进一步的限制。

预处理器标记和程序标记之间没有一对一的关系。存在重叠:预处理器 identifier 可能是关键字,也可能是各种可定义符号类型之一(包括一些常量和 typedef-names)。 pp-number 可能是整数或浮点常量,但也可能是无效的。词法产生式并不都是相互排斥的,词法范畴对程序子串的实际应用需要标准文本中描述的过程,而不是正式语法中描述的过程。

字符常量直接从预处理器传递到程序语法中而无需修改(尽管它们随后被归入 constant 类别)。如果有关于预处理器数字的单个注释(例如,如果它们在预处理器中存活,则它们必须可以转换为实数值常量文字这一事实)是拥有该类别的充分理由。

此外,在 pp-number 的定义中包含 character-constant 会增加什么?您仍然需要两个作品才能描述语言。