Ami*_*mit -1 c token c-preprocessor
我正在阅读关于令牌和计算程序中令牌数量的内容.
以前我在某处读过预处理器命令不算作令牌.但是当我在Geeksforgeeks上阅读有关令牌时,它会在"特殊符号"部分中给出:
预处理器(#):预处理器是一个宏处理器,编译器会在实际编译之前自动转换程序.
所以我很困惑,在一个程序中,如果我们写#define它将是一个令牌吗?
例如:
#include<stdio.h>
#define max 100
int main()
{
printf("max is %d", max);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个例子中有多少个令牌.
链接的文章充满了基本错误,不应该依赖.
解析C或C++的过程定义为一系列转换:1
if是适当语言的IF标记,但只是预处理器的IDENT标记.你的示例程序
#include<stdio.h>
#define max 100
int main()
{
printf("max is %d", max);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
将在转换3之后成为23系列预处理令牌:
PUNCT:# IDENT:include INCLUDE-ARG:<stdio.h>
PUNCT:# IDENT:define IDENT:max PP-NUMBER:100
IDENT:int IDENT:main PUNCT:( PUNCT:)
PUNCT:{
IDENT:printf PUNCT:( STRING:"max is %d" PUNCT:, IDENT:max PUNCT:) PUNCT:;
IDENT:return PP-NUMBER:0 PUNCT:;
PUNCT:}
Run Code Online (Sandbox Code Playgroud)
指令仍然存在于此阶段.请注意,#include并且#define每个令牌都是两个:#和指令名称是分开的.有些人喜欢#if用第1列中的哈希标记编写复杂的嵌套,但是指令名称缩进.
但是,在转换5之后,指令消失了,我们有了这个16 + n令牌系列:
[ ... some large volume of tokens produced from the contents of stdio.h ... ]
INT IDENT:main LPAREN RPAREN
LBRACE
IDENT:printf LPAREN STRING:"max is %d" COMMA DECIMAL-INTEGER:100 RPAREN SEMICOLON
RETURN DECIMAL-INTEGER:0 SEMICOLON
RBRACE
Run Code Online (Sandbox Code Playgroud)
然而,'n'中有很多令牌来自stdio.h.
预处理指令(#include,#define,#if等)都始终从令牌流中删除,也许用别的东西代替,所以你永远不会有改造后6令牌可以直接从指令行的文字结果.但是你通常会有每个指令的效果产生的令牌,例如内容stdio.h和DECIMAL-INTEGER:100替换IDENT:max.
最后,C和C++ 几乎完成了这一系列的操作,但并不完全相同,并且规范是正式独立的.您通常可以依赖预处理操作在两种语言中表现相同,只要您只使用预处理器执行简单操作,这无论如何都是最佳实践.
1您有时会看到人们谈论翻译阶段,这是C和C++标准正式描述这一系列操作的方式.我的清单不是翻译阶段的清单; 它包含了标准分组为单个阶段的某些内容的单独项目符号,并省略了与此讨论无关的几个步骤.