为什么不能在原始数据类型后省略白色 space?
Why can't one omit white space after primitive data types?
为什么编译器不允许我使用 intmain
而不是 int main
?编译器不会在编译时丢弃空格吗?
编译器丢弃多余的 空格。
Word/symbol 仍然需要中断,否则,将无法知道您是指一个名为 intmain
的变量还是正在启动一个函数 int main...
.
多余的空格主要是多个空格,以及连续符号之间的空格。
编译器如何知道您的 intmain
意味着 int main
?为什么不是 in tmain
或 intma in
?或者确实只是 intmain
?它无法读懂你的想法。
所以,不,他们不会丢弃空格,因为他们不能。
考虑一个例子:
class in{};
in tmain() {return in();}
编译器如何区分此声明和示例中的 intmain
?
因此,编译器仅在可区分的标记之间丢弃 space 符号(制表符、白色 spaces、回车符 returns)。
大多数分词器都会丢弃白色 space,因为他们不会为它生成一个分词。但这并不意味着白色 space 完全没有效果:它仍然强制一个标记结束,下一个标记开始。
一种理解方式是分词器具有三个工作:
- 将输入文本拆分为词位(子字符串)。
- 将每个词位分类到 "identifier" 或 "white space" 等类别中。
- 生成包含每个词素的值和分类的标记值流。
作业 1 和作业 2 的工作方式是我们为每种类型的令牌定义规则。然后分词器采用匹配当前输入的最长前缀的规则。然后它生成词素并根据匹配它的规则对其进行分类。
所以当我们说分词器 "ignore" white space 时,我们的意思是作业 3 不会为分类为 white space 的词位生成分词。这不会以任何方式影响工作 1。
为了说明这一点,输入 int main()
的三个作业如下所示:
"int", " ", "main", "(", ")"
KEYWORD_INT, SPACE, IDENTIFIER, OPEN_PAR, CLOSING_PAR
KEYWORD_INT, IDENTIFIER("main"), OPEN_PAR, CLOSING_PAR
对于 intmain()
,它看起来像这样:
"intmain", "(", ")"
IDENTIFIER, OPEN_PAR, CLOSING_PAR
IDENTIFIER("main"), OPEN_PAR, CLOSING_PAR
我们得到 intmain
而不是 int, main
的原因是标识符规则在 t
.
之后仍然保持匹配
在对您提出的另一个答案的评论中,为什么 int
没有得到优先考虑。这意味着我们改变了作业 1 的逻辑,这样它就不会采用最长匹配的规则,而是总是更喜欢 "keyword int" 规则而不是 "identifier" 规则。这将使得不可能有一个以 "int" 开头的标识符(因为它总是被归类为关键字 int
),所以那将是一个非常糟糕的主意。
为什么编译器不允许我使用 intmain
而不是 int main
?编译器不会在编译时丢弃空格吗?
编译器丢弃多余的 空格。
Word/symbol 仍然需要中断,否则,将无法知道您是指一个名为 intmain
的变量还是正在启动一个函数 int main...
.
多余的空格主要是多个空格,以及连续符号之间的空格。
编译器如何知道您的 intmain
意味着 int main
?为什么不是 in tmain
或 intma in
?或者确实只是 intmain
?它无法读懂你的想法。
所以,不,他们不会丢弃空格,因为他们不能。
考虑一个例子:
class in{};
in tmain() {return in();}
编译器如何区分此声明和示例中的 intmain
?
因此,编译器仅在可区分的标记之间丢弃 space 符号(制表符、白色 spaces、回车符 returns)。
大多数分词器都会丢弃白色 space,因为他们不会为它生成一个分词。但这并不意味着白色 space 完全没有效果:它仍然强制一个标记结束,下一个标记开始。
一种理解方式是分词器具有三个工作:
- 将输入文本拆分为词位(子字符串)。
- 将每个词位分类到 "identifier" 或 "white space" 等类别中。
- 生成包含每个词素的值和分类的标记值流。
作业 1 和作业 2 的工作方式是我们为每种类型的令牌定义规则。然后分词器采用匹配当前输入的最长前缀的规则。然后它生成词素并根据匹配它的规则对其进行分类。
所以当我们说分词器 "ignore" white space 时,我们的意思是作业 3 不会为分类为 white space 的词位生成分词。这不会以任何方式影响工作 1。
为了说明这一点,输入 int main()
的三个作业如下所示:
"int", " ", "main", "(", ")"
KEYWORD_INT, SPACE, IDENTIFIER, OPEN_PAR, CLOSING_PAR
KEYWORD_INT, IDENTIFIER("main"), OPEN_PAR, CLOSING_PAR
对于 intmain()
,它看起来像这样:
"intmain", "(", ")"
IDENTIFIER, OPEN_PAR, CLOSING_PAR
IDENTIFIER("main"), OPEN_PAR, CLOSING_PAR
我们得到 intmain
而不是 int, main
的原因是标识符规则在 t
.
在对您提出的另一个答案的评论中,为什么 int
没有得到优先考虑。这意味着我们改变了作业 1 的逻辑,这样它就不会采用最长匹配的规则,而是总是更喜欢 "keyword int" 规则而不是 "identifier" 规则。这将使得不可能有一个以 "int" 开头的标识符(因为它总是被归类为关键字 int
),所以那将是一个非常糟糕的主意。