【问题标题】:print(instead of printf()) in c/c++ program is detected by which part of compilerc/c++程序中的print(而不是printf())是由编译器的哪个部分检测的
【发布时间】:2016-09-02 17:03:11
【问题描述】:

假设我写了一个 c 程序,我写的是 print 而不是 printf
现在我的问题是编译器的哪一部分会检测到这个?

【问题讨论】:

  • 可能是解析器尝试标记您的语句时。
  • @Jonathan 为什么你从那个问题中删除了c++ 标签?没有它,这个问题如何有意义?
  • @πάνταῥεῖ:因为标题是关于 C 程序的。如果您愿意,可以将其放回原处;只要您在问题中添加一些关于 C++ 的内容,而不仅仅是标签,我不会对重新编辑提出异议。就目前而言,除了关于 C++ 的标签外,什么都没有,这使得 C++ 的标签毫无意义。
  • @πάνταῥεῖ:因为标题和问题主体都告诉我们 OP 使用的是 C 而不是 C++。所以c++不适用。
  • @BenVoigt 嗯,嗯。可能是@Ricky 是在正确的道路上。这是一个可怕的问题,真的。

标签: c++ c syntax compiler-errors semantics


【解决方案1】:

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

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

x = 5;

x 以前不存在时。

【讨论】:

    【解决方案2】:

    严格来说,假设print会以token的形式表示:

    { token type = Identifier, token value = 'print' }
    

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

    为了完成更高级别的工作,我们调用了较低级别的例程,所以现在假设您有使用get_token 的函数parse_declarationparse_declaration 负责识别程序中的声明(使用解析算法完成,例如recursive descent)如果声明被识别,它将在符号表中保存token value,并带有类型信息和属性。

    现在,假设您有函数parse_expression,它将调用get_token,如果token typeIdentifier,它将执行name lookup。这意味着它将在符号表中搜索token value。如果搜索不成功,它将打印错误消息(类似于"token value : undeclared identifier")。

    当然这个概念是简化的。在实践中,词法分析、解析、语义(语言如何“表现”、名称查找是语言语义的一部分)有相当复杂的逻辑,并且该逻辑应尽可能相互独立(分离)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-16
      • 1970-01-01
      • 2015-06-23
      • 1970-01-01
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多