C++ 在c/c+中打印(而不是printf())+;程序由编译器的哪个部分检测

C++ 在c/c+中打印(而不是printf())+;程序由编译器的哪个部分检测,c++,c,syntax,compiler-errors,semantics,C++,C,Syntax,Compiler Errors,Semantics,假设我写了一个c程序,我写了print而不是printf 现在我的问题是编译器的哪个部分会检测到这个 我假设OP是指编译器内部的哪个部分,比如lexer、解析器、类型分析器、名称分析器、代码生成器等等 在不明确了解gcc/llvm的情况下,我会假设它是名称分析器(更具体地说,这是“语义分析器”的一部分,通常也进行类型分析),因为它无法将“打印”与任何存在的名称匹配。这与防止以下情况的发生是一样的: x=5 当x以前不存在时 严格来说,假设打印将由以下形式的令牌表示: { token type =

假设我写了一个c程序,我写了
print
而不是
printf


现在我的问题是编译器的哪个部分会检测到这个

我假设OP是指编译器内部的哪个部分,比如lexer、解析器、类型分析器、名称分析器、代码生成器等等

在不明确了解gcc/llvm的情况下,我会假设它是名称分析器(更具体地说,这是“语义分析器”的一部分,通常也进行类型分析),因为它无法将“打印”与任何存在的名称匹配。这与防止以下情况的发生是一样的:

x=5


x
以前不存在时

严格来说,假设
打印
将由以下形式的令牌表示:

{ token type = Identifier, token value = 'print' }
从标记中的源字符的转换由词法分析器完成。假设您有函数
get_token
,它读取源文件字符并返回token(以上述结构的形式)。我们可以说,源文件被视为一系列这样的标记

为了完成更高级别的工作,我们称之为较低级别的例程,所以现在假设您有使用
get\u令牌的函数
parse\u declaration
parse_声明
负责识别程序中的声明(使用解析算法完成,例如
递归下降
),如果识别到声明,则将
标记值
保存在符号表中,并带有类型信息和属性

现在,假设您有函数
parse_expression
,它将调用
get_token
,如果
token type
Identifier
,它将执行
名称查找
。这意味着它将在符号表中搜索
标记值
。如果搜索不成功,它将打印错误消息(类似于
“令牌值:未声明的标识符”


当然,这个概念被简化了。在实践中,词汇分析、语法分析、语义(语言的“行为”方式、名称查找是语言语义的一部分)都有相当复杂的逻辑,这种逻辑应该是独立的(独立的)尽可能地相互关联。

当解析器试图标记您的语句时,可能是解析器。@Jonathan为什么要从该问题中删除标记?没有它,这个问题有什么意义?@πάνταῥεῖ: 因为标题是关于C程序的。如果你愿意,把它放回去;只要你还添加了关于C++的问题,除了标签之外,我不会再进行修改。正如它所代表的,除了C++的标签外,没有别的东西,这使得C++标签毫无意义。ῥεῖ: 因为标题和问题体都告诉我们OP是用C而不是C++。“所以这是不适用的。”本沃伊特,嗯。也许是在正确的道路上。这真是个可怕的问题。