C编译器如何解析下面的C语句?
考虑以下几行:C编译器如何解析下面的C语句?,c,compiler-construction,printf,lexical-analysis,C,Compiler Construction,Printf,Lexical Analysis,考虑以下几行: int i; printf("%d",i); 词法分析器将进入字符串以将%和d作为单独的标记进行分析,还是将“%d”作为一个标记进行分析?字符串文本是单个标记。上述代码将按如下方式标记: int keyword "int" i identifier ; semicolon printf identifier ( open paren "%d" string literal , comma i ident
int i;
printf("%d",i);
词法分析器将进入字符串以将
%
和d
作为单独的标记进行分析,还是将“%d”作为一个标记进行分析?字符串文本是单个标记。上述代码将按如下方式标记:
int keyword "int"
i identifier
; semicolon
printf identifier
( open paren
"%d" string literal
, comma
i identifier
) closing paren
; semicolon
这里有两个解析器在工作:首先是C编译器,它将解析C文件并基本上忽略字符串的内容(尽管现代C编译器也将解析字符串以帮助捕获格式错误的字符串,
%
转换说明符与传递给printf()的相应参数之间不匹配)
待转换)
下一个解析器是内置于C运行时库中的字符串格式解析器。当您调用printf
时,将在运行时调用它来解析格式字符串。相比之下,这个解析器当然非常简单
我没有检查,但我想帮助检查错误格式字符串的C编译器将实现类似于printf
的解析器作为后处理步骤(即使用自己的lexer)。%d
是字符串文本,它将被和编译器视为一个标记,我们可以通过进入第6.4节6.4
词汇元素来了解这一点,它定义了以下标记:
token:
keyword
identifier
constant
string-literal
punctuator
preprocessing-token:
header-name
identifier
pp-number
character-constant
string-literal
punctuator
each non-white-space character that cannot be one of the above
以及以下预处理令牌:
token:
keyword
identifier
constant
string-literal
punctuator
preprocessing-token:
header-name
identifier
pp-number
character-constant
string-literal
punctuator
each non-white-space character that cannot be one of the above
并说:
标记是翻译中语言的最小词汇元素
第7和第8阶段。令牌的类别为:关键字、标识符、,
常量、字符串文本和标点符号。需要一个预处理令牌
翻译阶段3中语言的最小词汇元素
到6。预处理标记的类别为:标题名称,
标识符、预处理数字、字符常量、字符串
文字、标点符号和单个非空白字符
在词汇上与其他预处理标记类别不匹配。58)[…]
第5.1.1.2节
翻译阶段介绍了不同的翻译阶段,我将在这里重点介绍一些相关的翻译阶段:
[……]
3将源文件分解为预处理标记和
空白字符(包括注释)
[……]
连接6个相邻的字符串文字标记
7个分隔标记的空格字符不再有效每个
预处理令牌被转换为令牌。生成的令牌是
从语法和语义上分析并翻译为一个翻译单元
[……]
预处理器令牌和令牌之间的区别似乎无关紧要,但我们可以看到,至少在一种情况下,例如在相邻的字符串文本中,例如
%d”“\n
您将有两个预处理器令牌,而在阶段6
之后,只有一个令牌。词法分析器将识别%d”
作为竞争字符串。编译器“语法”和“语义”的下一个阶段是识别缺少的参数和类型检查。如果编译代码(printf中没有i
),您将收到警告“由于“语法”和“语义”检查,格式“%d”需要匹配的“int”参数”
。如果字符串未单独解析为标记,语法分析如何发现错误?“语法分析”是“词法”之后的下一阶段。编译器首先生成令牌流(如sepp2k的答案所示),然后进一步解析TOKE流(使用语法)并在下一阶段进行语义检查。在您的PC上尝试。您将收到第二行打印的警告,但不会收到str=“%d”
的警告,这意味着编译器只解析%d”
当它在printf中时-这表示在词法相位测量之后完成了工作,我认为OP想知道更多关于“%d”将生成长度为1或2的字符数组(即“\n”将生成长度为1的字符数组)--我认为他寻找的答案是,它将是一个包含两个不同字符的字符串文字(然后在运行时通过*printf方法进一步解析)。