【发布时间】:2016-09-02 17:03:11
【问题描述】:
假设我写了一个 c 程序,我写的是 print 而不是 printf。
现在我的问题是编译器的哪一部分会检测到这个?
【问题讨论】:
标签: c++ c syntax compiler-errors semantics
假设我写了一个 c 程序,我写的是 print 而不是 printf。
现在我的问题是编译器的哪一部分会检测到这个?
【问题讨论】:
标签: c++ c syntax compiler-errors semantics
我假设 OP 是指编译器的哪个部分在内部,例如词法分析器、解析器、类型分析器、名称分析器、代码生成器等。
如果不具体了解 gcc/llvm,我会假设它是 名称分析器(更具体地说,它通常是“语义分析器”的一部分,它也进行类型分析),如那将无法将“打印”与任何存在的名称相匹配。这与防止以下情况相同:
x = 5;
当x 以前不存在时。
【讨论】:
严格来说,假设print会以token的形式表示:
{ token type = Identifier, token value = 'print' }
从标记中的源字符转换是由词法分析器完成的。假设您有函数get_token,它读取源文件字符并返回令牌(以上述结构的形式)。我们可以说源文件被视为一系列这样的标记。
为了完成更高级别的工作,我们调用了较低级别的例程,所以现在假设您有使用get_token 的函数parse_declaration。 parse_declaration 负责识别程序中的声明(使用解析算法完成,例如recursive descent)如果声明被识别,它将在符号表中保存token value,并带有类型信息和属性。
现在,假设您有函数parse_expression,它将调用get_token,如果token type 是Identifier,它将执行name lookup。这意味着它将在符号表中搜索token value。如果搜索不成功,它将打印错误消息(类似于"token value : undeclared identifier")。
当然这个概念是简化的。在实践中,词法分析、解析、语义(语言如何“表现”、名称查找是语言语义的一部分)有相当复杂的逻辑,并且该逻辑应尽可能相互独立(分离)。
【讨论】: