Parsing 使用lex/yacc替代方案的原因?

Parsing 使用lex/yacc替代方案的原因?,parsing,antlr,multilingual,yacc,lex,Parsing,Antlr,Multilingual,Yacc,Lex,大约一年一次,我必须开发或至少设计一个语法和语法分析器——这在我的工作生涯中一直都是如此 每一次我面对这个任务,因此大约一年,我,相当一个Lex/YACC(Flex / BISEN RESP)家伙,考虑或重新考虑替代Lex/YACC的选择,并且经过一些沉思和尝试之后,我回到原来的Lex/YACC。 因为我在应用程序的中心有一个CORBA服务器,我可以从几乎所有语言编写的解析器中调用它,所以这次我看了一下 antlr4(Java)和antlr3(Java,但其他语言有RT) SableCC(爪哇

大约一年一次,我必须开发或至少设计一个语法和语法分析器——这在我的工作生涯中一直都是如此

每一次我面对这个任务,因此大约一年,我,相当一个Lex/YACC(Flex / BISEN RESP)家伙,考虑或重新考虑替代Lex/YACC的选择,并且经过一些沉思和尝试之后,我回到原来的Lex/YACC。

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

  • antlr4(Java)和antlr3(Java,但其他语言有RT)
  • SableCC(爪哇)
  • Parse::EBNF、Parse::Yapp和Marpa(Perl)
  • 和SimpleParse(Python)
对我来说,带有antlrworks的串联式antlr4看起来是最有希望的候选者,但我还不相信花在它上面的时间最终会被摊销


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

为什么这些替代方案会比使用普通的lex/yacc更容易完成我的任务呢?

the在“whipituptude”方面有很大的改进,包括它本身是用Marpa编写的。你可以考虑从Marpa开始,进行“原型化”。Marpa是高度声明性的,使用干净的BNF。如果迁移,您可以将大部分工作转移到新的解析器。Marpa在错误处理和检测方面无与伦比,在原型阶段也非常方便


Marpa解析线性时间中列出的其他解析器解析的所有语法类,其灵活性无与伦比。它的最新功能允许您从Marpa来回切换到您自己的解析代码。所以你甚至可以留在这里。我的博客有可能是介绍MARPA的最好方法。

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

此外,它的错误恢复要好得多,并且产生了许多更干净的错误。有多种方法使使用ANTLR语法变得非常简单(ANTLRWorks、IntelliJ插件、VisualStudio代码扩展等)。你可以用相同的语法生成不同语言(C,C++,C,java和更多)的解析器(除非你在语法中有语言特定的动作,你在你的问题中已经提到过了)。当我们谈到动作时:由于底层解析器中的求值原则(移位标记、移位标记、将它们减少为新标记并移位它等),动作很容易在那里引起麻烦,例如执行多次等等。对于ANTLR生成的解析器,情况并非如此


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

我认为这是一个类似“我应该使用哪种编程语言”的问题,不太可能吸引到如此客观的答案。因此,投票以非建设性方式结束。然而,您的问题是:您对lex/flex/yacc/bison的哪些方面不满意?这至少会给你一个关于寻找什么特征的线索。如果只是“我想尝试一些新东西”,那么掷硬币:)这是不可比的。如果所有生成器都会生成相同的解析器,我同意,但是结果完全不同,这取决于解析器生成器。谢谢您的深入回复,Jeffrey!请。以SQL DDL为例。为什么Marpa会比lex&yacc做得更好呢?有了Marpa,你只需输入BNF(amy BNF),它就会运行。有了yacc的经验,你知道LALR就不那么容易了。Marpa也知道并可以随时准确地报告它在解析中的位置,从而使错误检测、调试和维护更加容易。Marpa中当前的SQL(或子集)实现是专有的(唉),但测试套件中有一个片段。我不是在使用SQL cmd shell,这只是一个著名语法的示例,它在结构上与我的语法有一些相似之处,但我认为你提到的“Marpa也知道并且可以随时准确地报告它在解析中的位置”这一壮举是一个剩余值。谈到“键入BNF”——这意味着在Perl结构中混合嵌入关键字、分隔符、操作等。是否有简单的方法可以以文档友好的形式提取纯语法?我不能100%确定我是否理解这个问题,但如果使用Marpa的SLIF接口,语法的形式将已经接近BNF/EBNF,这就是“文档准备”的目的。有关SLIF的示例,请参见中的概要。