首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GCC和Clang解析器真的是手写的吗?

GCC和Clang解析器真的是手写的吗?
EN

Stack Overflow用户
提问于 2011-06-11 23:15:49
回答 6查看 36.7K关注 0票数 98

GCC和LLVM-Clang似乎都在使用手写递归下降解析器,以及机器生成的、基于Bison的、自下而上的解析。

请这里的人确认一下是这样的吗?如果是这样的话,为什么主流编译器框架使用手写解析器呢?

更新这里有关于这个主题的有趣博客

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-06-11 23:47:52

是:

  • GCC曾经使用过yacc (野牛)解析器,但在3.x系列的某个时候,它被手写的递归下降解析器所取代:有关补丁提交的链接,请参见解析器
  • Clang还使用了一个手写的递归下降解析器:参见靠近C++末尾的“C、目标C、C++和目标的单一统一解析器”一节。
票数 83
EN

Stack Overflow用户

发布于 2011-06-12 05:28:30

有一个民间定理说C很难解析,而C++本质上是不可能的。

这不是真的.

确实,C和C++很难使用LALR(1)解析器来解析,而不需要侵入解析机制和处理符号表数据。GCC实际上是用YACC和其他类似的黑客来解析它们的,是的,它是丑陋的。现在GCC用的是手写解析器,但仍然带有符号表黑客。Clang从未有过使用自动解析器生成器的尝试;Clang解析器AFAIK一直是手工编码的递归下降。

事实是,C和C++相对容易使用更强的自动生成解析器(例如,GLR解析器 )进行解析,并且不需要任何黑客攻击。埃尔萨 C++解析器就是一个例子。我们的C++前端是另一个(就像我们所有的“编译器”前端一样,GLR是非常棒的解析技术)。

我们的C++前端没有GCC的快,当然也比Elsa慢;我们很少投入精力对其进行仔细的调整,因为我们还有其他更紧迫的问题(然而,它已经被用于数百万行C++代码中)。埃尔莎可能会比GCC慢一些,原因很简单,因为它更笼统。考虑到现在处理器的速度,这些差异在实践中可能并不重要。

但是,今天广为传播的“真正的编译器”植根于10年或20年前的编译器。效率低下更重要,没有人听说过GLR解析器,所以人们做了他们知道如何做的事情。Clang当然是最近才出现的,但是民间定理在很长一段时间内保持了他们的“说服力”。

你不用再那样做了。您可以非常合理地使用GLR和其他类似的解析器作为前端,同时提高编译器的可维护性。

事实是,要获得一个与友好的邻里编译器行为相匹配的语法是很困难的。虽然几乎所有的C++编译器都实现了(大多数)原始标准,但它们也往往有许多黑暗的扩展,例如MS编译器中的DLL规范等等。如果您有一个强大的解析引擎,您可以花费时间尝试获得最终的语法以满足实际情况,而不是试图弯曲语法以满足解析器生成器的限制。

2012年11月编辑:自从编写这个答案以来,我们改进了C++前端,以处理完整的C++11,包括ANSI、GNU和MS变体方言。虽然有很多额外的内容,但我们不需要更改解析引擎;我们只是修改了语法规则。我们确实需要更改语义分析;C++11在语义上非常复杂,这项工作阻碍了使解析器运行的工作。

2015年2月编辑:.现在处理完整的C++14。(关于GLR对简单代码的解析,以及C++臭名昭著的“最烦人的解析”,请参见从c++代码中获取人类可读的AST )。

编辑2017年4月:现在处理(草稿) C++17。

票数 119
EN

Stack Overflow用户

发布于 2011-06-17 06:28:27

Clang的解析器是一个手写的递归下降解析器,其他几个开源和商业C和C++前端也是如此。

Clang使用递归下降解析器有以下几个原因:

  • performance :手写解析器允许我们编写一个快速解析器,根据需要优化热点路径,并且我们始终控制着该性能。有了一个快速的解析器,Clang就可以在其他开发工具中使用,这些工具通常不使用“真正的”解析器,例如,在IDE中使用语法突出显示和代码完成。
  • 诊断和错误恢复:由于您完全可以使用手写的递归下降解析器来控制,所以很容易添加一些特殊情况来检测常见的问题,并使用自动生成的解析器提供很好的诊断和错误恢复(例如,参见http://clang.llvm.org/features.html#expressivediags),因此您只能使用生成器的功能。
  • Simplicity:递归下降解析器易于编写、理解和调试。您不需要成为解析专家,也不需要学习新的工具来扩展/改进解析器(这对于开源项目特别重要),但是仍然可以获得很好的结果。

总的来说,对于C++编译器来说,这并不重要: C++的解析部分并不简单,但它仍然是比较容易的部分之一,所以保持简单是值得的。语义分析--特别是名称查找、初始化、重载解析和模板实例化--比解析更加复杂。如果您想要证明,请检查代码的分发,并在Clang的"Sema“组件(用于语义分析)和它的"Parse”组件(用于解析)中提交。

票数 36
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6319086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档