为什么不能在原始数据类型后省略白色 space?

Why can't one omit white space after primitive data types?

为什么编译器不允许我使用 intmain 而不是 int main?编译器不会在编译时丢弃空格吗?

编译器丢弃多余的 空格。

Word/symbol 仍然需要中断,否则,将无法知道您是指一个名为 intmain 的变量还是正在启动一个函数 int main....

多余的空格主要是多个空格,以及连续符号之间的空格。

编译器如何知道您的 intmain 意味着 int main?为什么不是 in tmainintma in?或者确实只是 intmain?它无法读懂你的想法。

所以,不,他们不会丢弃空格,因为他们不能。

考虑一个例子:

class in{};
in tmain() {return in();}

编译器如何区分此声明和示例中的 intmain? 因此,编译器仅在可区分的标记之间丢弃 space 符号(制表符、白色 spaces、回车符 returns)。

大多数分词器都会丢弃白色 space,因为他们不会为它生成一个分词。但这并不意味着白色 space 完全没有效果:它仍然强制一个标记结束,下一个标记开始。

一种理解方式是分词器具有三个工作:

  1. 将输入文本拆分为词位(子字符串)。
  2. 将每个词位分类到 "identifier" 或 "white space" 等类别中。
  3. 生成包含每个词素的值和分类的标记值流。

作业 1 和作业 2 的工作方式是我们为每种类型的令牌定义规则。然后分词器采用匹配当前输入的最长前缀的规则。然后它生成词素并根据匹配它的规则对其进行分类。

所以当我们说分词器 "ignore" white space 时,我们的意思是作业 3 不会为分类为 white space 的词位生成分词。这不会以任何方式影响工作 1。

为了说明这一点,输入 int main() 的三个作业如下所示:

  1. "int", " ", "main", "(", ")"
  2. KEYWORD_INT, SPACE, IDENTIFIER, OPEN_PAR, CLOSING_PAR
  3. KEYWORD_INT, IDENTIFIER("main"), OPEN_PAR, CLOSING_PAR

对于 intmain(),它看起来像这样:

  1. "intmain", "(", ")"
  2. IDENTIFIER, OPEN_PAR, CLOSING_PAR
  3. IDENTIFIER("main"), OPEN_PAR, CLOSING_PAR

我们得到 intmain 而不是 int, main 的原因是标识符规则在 t.

之后仍然保持匹配

在对您提出的另一个答案的评论中,为什么 int 没有得到优先考虑。这意味着我们改变了作业 1 的逻辑,这样它就不会采用最长匹配的规则,而是总是更喜欢 "keyword int" 规则而不是 "identifier" 规则。这将使得不可能有一个以 "int" 开头的标识符(因为它总是被归类为关键字 int),所以那将是一个非常糟糕的主意。