纯粹是自学练习,我试图使用Parse::RecDescent
模块在Perl中编写Java解析器。稍后我可能会使用其他工具(如Antlr,野牛等)重新实现解析器。
但是,根据Java语言规范,我如何确保我的解析器确实生成了正确的解析器?含义,它对悬挂的else
的正确处理,运算符的关联性和-precedence等。
一种方法是通过使两个解析器都针对大量测试Java程序生成AST,然后将我的解析器与已知的,无错误的解析器进行比较,然后比较两组AST。
如果这确实是唯一的方法,那么在哪里可以找到涵盖整个Java语言规范的大量测试Java程序套件?
我看过JavaParser,但似乎没有详尽的测试数据集。
当然,另一种方法是自己编写成千上万的测试Java程序,这对我来说是不切实际的,不仅要及时而且要确保其详尽无遗!
最佳答案
要确定您是否有正确答案,理想情况下,您必须与某种标准进行比较。对于计算机语言来说这很难。
比较AST会很困难,因为尚无标准。每个构建AST的解析器都会构建一个AST,其结构是由对解析器进行编码的人员设计的。
这意味着,如果您构建了一个AST产生的解析器,并且得到了其他人的AST产生的解析器,则会发现您选择的AST节点与另一个AST不匹配。现在,您必须构建一个从AST到另一个AST的映射(以及如何知道该映射是有效的?)。您可以尝试使您的解析器从另一个解析器生成AST,但是您将发现所生成的AST受所用解析技术的影响。
我们公司生产的Java前端也有类似的问题(如果您想了解更多,请参阅bio)。我们所满足的是测试答案是否自洽,然后对大型代码进行大量的长期经验测试。
我们的解决方案是:
解析然后美化的代码也会解析。我们重新打印解析后的 pretty-print 版本;这应该与prettyprinted版本相同,因为我们总是产生相同的布局。此测试很好地表明了我们的AST设计和实现不会丢失任何有关源代码
分析和代码转换。我们发现了偶发的问题并进行了修复。
要做到这一点很难。您必须保持密切联系并持续承受测试压力,尤其是因为Java语言不断发展。
(我们使用Java 8,而Java 9受到威胁)。底线:构建这样的解析器并检查其健全性是一项繁重的工作。
我们希望有一套独立的测试,但我们还没有野外见过。我希望这些测试(如果存在)(我假设Oracle和IBM都有)真的不会直接测试解析和名称解析,而是测试一些代码是否可以编译并运行以产生已知结果。由于我们没有构建编译器,因此如果拥有这些测试,我们将无法运行它们。我们将能够进行名称解析和类型一致性检查,这将有所帮助。
[我们实际上是针对多种语言的前端进行的。您认为Java很难,请与C++一起尝试]
关于java - 测试新的Java解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39687634/