17

大约每年一次,我必须开发或至少设计一个语法和解析器——这似乎是我工作生活的常态。

每次我面临这项任务时,大约一年一次,我,一个相当喜欢 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 更容易?

4

2 回答 2

13

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

此外,它的错误恢复要好得多,并且会产生更清晰的错误。有各种IDE/插件/扩展使使用 ANTLR 语法变得非常容易(ANTLRWorks、IntelliJ 插件、Visual Studio Code 扩展等)。您可以从相同的语法生成不同语言(C、C++、C#、Java 等)的解析器(除非您的语法中有特定于语言的操作,否则您已经在问题中提到了这一点)。当我们谈到动作时:由于底部解析器中的评估原则(移位令牌,移位令牌,将它们减少为新令牌并将其移位等),动作很容易在那里造成麻烦,例如执行多次等。ANTLR 生成的解析器并非如此。

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

于 2013-05-14T12:40:09.420 回答
5

最新的Marpa 是 Marpa::R2,它在“whipituptude”上有很大的改进,包括一个非常方便的新 DSL 接口,它本身是用 Marpa 编写的。您可以考虑从 Marpa 开始,用于“原型设计”。Marpa 是高度声明性的,使用干净的 BNF。如果您迁移出去,您可以将大部分工作交给新的解析器。Marpa 在错误处理和检测方面无与伦比,在原型设计阶段也非常方便。

Marpa 解析所有其他解析器以线性时间列出的语法类别,并且其灵活性无与伦比。它的最新功能允许您从 Marpa 来回切换到您自己的解析代码。所以你甚至可以坚持下去。有一个网站,我的博客有一系列教程,这可能是了解 Marpa 的最佳方式。

于 2013-05-13T16:37:26.777 回答