Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C编译器如何解析下面的C语句?_C_Compiler Construction_Printf_Lexical Analysis - Fatal编程技术网

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方法进一步解析)。