【问题标题】:How does gcc/clang parse c++ if it can't be parsed by a LR(1) parser?如果 LR(1) 解析器无法解析 c++,gcc/clang 如何解析它?
【发布时间】:2020-08-27 18:09:09
【问题描述】:

GCC/Clang 是手写解析器。我读过一篇文章说 LR(1) 解析器 (Why can't C++ be parsed with a LR(1) parser?) 无法解析 C++。如果是这样,当 LR(1) 比递归下降更强大时,GCC/Clang 怎么会是手写的递归下降解析器?

【问题讨论】:

  • 你如何定义权力?
  • @user4581301 -- LR(1) 可以解析更多递归下降的语法。
  • “LR(1) 可以解析更多递归下降的语法”在手写解析器上您可以使其解析任何语法,因为您可以根据上下文更改解析器的状态。在完全指定的 LR(1) 上,您不能这样做 - 您必须正式指定完整的语法。
  • 您指向的链接似乎回答了这个问题,只是不在接受的最高答案中。此外,您似乎在问两个不同的问题:(1) GCC/Clang 如何使用手写解析器解析 C++,以及 (2) 为什么 GCC/Clang 是手写解析器。
  • 这能回答你的问题吗? Why can't C++ be parsed with a LR(1) parser?

标签: c++ parsing grammar recursive-descent lr


【解决方案1】:

GCC/Clang 不是严格的递归下降解析器;它们允许回溯(解析任意长的文本),以及与理论纯度的其他偏差。回溯解析器严格来说比非回溯解析器更强大(但代价是不再是线性时间)。

当问题以这种方式表达时,解析 C++ 的真正复杂性就消失了。如果您将 C++ 剥离为附录 A 中 BNF 描述的超集,那么您基本上只需要准备好考虑几种替代解析。您可以通过回溯来做到这一点——尝试一种可能性,然后如果失败,尝试其他一些可能性——或者通过并行探索,使用 GLR/GLL 或其他一些变体;没什么太痛苦的。但真正的工作还是要面对的:

  • 预处理器,不是特别复杂,但无法用任何类似于正式解析框架的东西来描述;

  • 模板实例化,将语义分析混合到解析过程中(需要进行以发现正确的解析);

  • 名称解析,有些人可能不认为它是解析的一部分,但是在您知道特定标识符所指的语法对象之前,您不会继续下一步。 (如果您认为名称解析很简单,请重新阅读第 6.5 节(名称查找)中 C++ 标准的 13 页密集页面,然后继续阅读第 12 节中关于解析重载名称的 35 页。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-19
    • 2020-01-17
    • 2020-08-23
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多