使用flex/yacc编写C++编译器需要多长时间?

Mad*_*dhu 17 c++ compiler-construction yacc bison flex-lexer

使用lex/yacc编写C++编译器需要多长时间?

我在哪里可以开始使用它?

Omn*_*ous 21

bison/yacc解析器无法解析许多解析规则(例如,在某些情况下区分声明和函数调用).另外,有时令牌的解释需要来自解析器的输入,特别是在C++ 0x中.>>例如,字符序列的处理关键取决于解析上下文.

这两个工具是解析C++的非常糟糕的选择,你必须放入许多特殊情况,这些特殊情况逃脱了这些工具所依赖的基本框架,以便正确地解析C++.这需要很长时间,即使这样,你的解析器也可能会有奇怪的错误.

yacc和bison是LALR(1)解析器生成器,它们不够复杂,无法有效地处理C++.正如其他人所指出的那样,大多数C++编译器现在使用递归下降解析器,其他几个答案指出了编写自己的解决方案的好方法.

C++模板不适合处理字符串,甚至是常量字符串(尽管这可能在C++ 0x中修复,我没有仔细研究过),但是如果它们是,你可以很容易地在C++模板中编写一个递归下降解析器语言.我觉得这很有趣.

  • @Martin York,实际上bison/yacc解析器被gcc-3.4中的递归下降解析器替换 - http://gcc.gnu.org/gcc-3.4/changes.html (8认同)
  • 如果我没有弄错的话,gcc在3.x系列的某个时候切换到使用递归下降解析器. (2认同)
  • 递归下降解析器也更容易理解。事实上,如果您对语言开发感兴趣,我可能建议您从手动生成相对简单的语法的递归下降解析器开始。 (2认同)
  • @kyoryu:递归下降解析器并不比纯语法更容易理解,特别是对于C++规模的工件.你真的想要一个根据BNF规则从语言定义驱动的解析器生成器.说C++难以解析的人是使用YACC(和变体)的人以及那些通过解析纠缠名称/类型解析的人.GLR解析器生成器允许您使用BNF规则构建一个非常好的解析器,并隔离名称/类型解析; 这个独立使每个任务变得更容易(虽然不容易).在这里看到我的答案. (2认同)

Tod*_*lin 10

它可能需要数年时间,您可能会在此过程中切换到其他一些解析器生成器.

解析C++非常容易出错.语法不完全是LR可解析的,因为许多部分都是上下文敏感的.你将无法在flex/yacc中正常工作,或者至少它实现起来真的很尴尬.我知道只有两个前端正确.您最好的选择是使用其中之一并专注于编写后端.无论如何,这就是有趣的东西:-).

现有的C++前端:

  1. EDG前端被大多数商业供应商(使用英特尔,波特兰集团等)在它们的编译器.这需要花钱,但它非常彻底.人们为此付出了巨大的代价,因为他们不想处理编写自己的C++解析器的痛苦.

  2. GCC的C++前端对于生产代码足够透彻,但您必须弄清楚如何将其集成到您的项目中.我认为将它与GCC分开是相当复杂的.这也是GPL,但我不确定这对你来说是否有问题.您可以通过gcc_xml在项目中使用GCC前端,但这只会为类,函数,命名空间和typedef提供XML.它不会为您提供代码的语法树.

  3. 另一种可能性是使用clang,但他们的C++支持目前很不稳定.很高兴看到他们得到了所有的错误,但如果你看看他们的C++状态页面,你会注意到有不止一些测试用例仍然存在.注意 - 铿锵是一个很大的项目.如果要花费这些时间来实现C++前端,那么你需要更长的时间.

  4. 其他人提到了ANTLR,并且有可用的C++语法,但我持怀疑态度.我没有听说过任何主要编译器中使用的ANTLR前端,但我确实认为它在NetBeans IDE中使用过.它可能适合IDE,但我怀疑你能否在生产代码上使用它.


kyo*_*ryu 10

听起来你是解析/编译器创建的新手.如果是这种情况,我强烈建议不要从C++开始.它是一种语言的怪物.

要么发明自己的琐碎玩具语言,要么做一些更小更简单的事情.我看到了一个lua解析器,其中语法定义大约有一页长.作为一个起点,这将更加合理.


Dig*_*oss 6

很长一段时间,而lex和yacc也无济于事

如果您具备为这么大的语言编写编译器的技能,那么您将不需要lex和yacc为您提供的少量帮助.事实上,虽然lex是可以的,但是使用yacc可能需要更长的时间,因为它对C或C++来说并不是非常强大,并且你最终可以花费更多的时间来使它正常工作而不是只需编写一个递归血统解析器.

我相信lex和yacc最适合用于简单的语法,或者当需要额外的努力来获得一个可读的语法文件时,可能是因为语法是实验性的并且可能会发生变化.

就此而言,整个解析器可能不是您工作的主要部分,具体取决于您对代码生成器的确切目标.

  • 马丁:事实并非如此."bison/yacc解析器被gcc-3.4中的递归下降解析器替换" (7认同)
  • 我认为重点不在于flex/yacc是否是好工具,而是指出它们只是整个问题的一小部分.太棒了,你已经将文件解析成一些中间表示(AST /无论如何) - *现在是什么?* (5认同)