使用lex / yacc替代品的原因?

时间:2013-05-13 15:49:46

标签: parsing antlr multilingual yacc lex

大约每年一次,我必须开发或至少设计一个语法和解析器 - 这似乎是我工作生涯中不变的。

每次我面对这个任务,大约一年,我,相当一个lex / yacc(flex / bison resp。)的家伙,考虑或重新考虑普通lex / yacc的替代品,并且,经过一些沉思并试着回到普通的lex / yacc。

因为我在应用程序的中心有一个CORBA服务器,我可以用几乎所有语言编写的解析器调用,所以这次我看看

  • antlr4(Java)和antlr3(Java但其他语言的RT),
  • SableCC(Java),
  • Parse :: EBNF,Parse :: Yapp和Marpa(Perl),
  • 和SimpleParse(Python),

对我而言,带有antlrworks的串联antlr4看起来是最有希望的候选人,但我还不相信花在其上的时间最终会摊销。


我必须开发的语法类似于SQL DDL(在结构方面,而不是在主题方面)。

为什么任何替代方案都会使我的任务比使用普通lex / yacc更容易?

2 个答案:

答案 0 :(得分:9)

您还应该考虑的是各种解析器生成器生成完全不同的解析器。 Yacc / bison生成自下而上的解析器,这些解析器通常难以理解,难以调试并且会产生奇怪的错误消息。例如,ANTLR生成一个递归下降自上而下的解析器, 更容易理解,你实际上可以轻松地调试它,你只能使用子规则进行解析操作(例如只是解析表达式而不是完整的式语言)。

此外,它的错误恢复方式更好,并产生更多更清晰的错误。有许多IDEs/plugins/extensions可以很容易地使用ANTLR语法(ANTLRWorks,IntelliJ插件,Visual Studio代码扩展等)。你可以用相同的语法生成不同语言(C,C ++,C#,Java等)的解析器(除非你的语法中有特定于语言的动作,你已经在你的问题中提到了这一点)。虽然我们谈到了行动:由于底层解析器中的评估原则(移位令牌,移位令牌,将它们缩减为新令牌并将其移位等),因此操作很容易在那里引起麻烦,例如:执行不止一次等等。使用ANTLR生成的解析器不是这样。

多年来我也尝试了各种解析器生成器,甚至编写了我自己的解析器生成器,但我随时都会推荐使用ANTLR作为首选工具。

答案 1 :(得分:5)

latest Marpa is Marpa::R2,它在“whipituptude”方面有很大改进,包括a very convenient new DSL interface,它本身就是用Marpa写的。您可以考虑从Marpa开始,进行“原型设计”。 Marpa是高度声明性的,使用干净的BNF。如果您迁移,您可以将大部分工作用于新的解析器。 Marpa在错误处理和检测方面无与伦比,在原型设计阶段也非常方便。

Marpa解析由线性时间列出的其他解析器解析的所有语法类,并且其灵活性无与伦比。它的最新功能允许您从Marpa来回切换到您自己的解析代码。所以你甚至可能会坚持下去。有a website,我的博客有a series of tutorials,这可能是介绍给Marpa的最佳方式。