Compiler construction 如何标记printf(“结果是%d\n”,a);词汇分析器的陈述

Compiler construction 如何标记printf(“结果是%d\n”,a);词汇分析器的陈述,compiler-construction,lexical-analysis,Compiler Construction,Lexical Analysis,如果词法分析器将“结果为%d\n”作为以下内容中的一个标记: printf(“结果是%d\n”,a); 然后,如何以及在什么阶段将%d和\n分别识别为格式说明符和下一行。libc中的printf代码“手动”逐个字符地自行解析格式字符串。类似地,编译器也会对以下参数进行类型检查。对printf的调用中的文本字符串是一个普通的字符串文本,与程序中的任何其他字符串文本没有区别printf是一个普通函数,其第一个参数应为字符串。不要求printf的第一个参数是字符串文字;它可以是值为字符串指针的任何表达

如果词法分析器将“结果为%d\n”作为以下内容中的一个标记: printf(“结果是%d\n”,a);
然后,如何以及在什么阶段将%d和\n分别识别为格式说明符和下一行。

libc中的
printf
代码“手动”逐个字符地自行解析格式字符串。类似地,编译器也会对以下参数进行类型检查。

printf
的调用中的文本字符串是一个普通的字符串文本,与程序中的任何其他字符串文本没有区别
printf
是一个普通函数,其第一个参数应为字符串。不要求
printf
的第一个参数是字符串文字;它可以是值为字符串指针的任何表达式。(尽管许多样式指南警告您不要这样做。)因此,以下内容完全合法:

const char* fmt = "The result is %d\n";
/* ... */

printf(fmt, a);
在字符串文本中,像
\n
这样的转义序列被转换为它们所表示的特殊字符(本例中为换行符)。因此,
“\n”
是一个包含单个字符的字符串文字

每次调用
printf
,它都会扫描提供的格式字符串以识别格式转换。显然,这是在运行时发生的,而不是在编译程序时


话虽如此,由于
printf
是一个具有良好定义行为的标准库函数,如果在编译时已知format参数,编译器优化对
printf
的调用是合法的。一些编译器利用了这一点。

它是在运行时识别的,而不是在编译期间。