java - 测试新的Java解析器

标签 java parsing testing javaparser

纯粹是自学练习,我试图使用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)。我们所满足的是测试答案是否自洽,然后对大型代码进行大量的长期经验测试。

我们的解决方案是:

  • (使用我们可以获得的最强大的解析技术来构建解析器(GLR)。这意味着我们可以识别某些其他解析技术(LL,LR,...)不容易识别的构造,从而生成其他解析器的AST节点(这很重要。请参阅下面的评论,其中的示例很重要。即使如此,we produce AST nodes in way that avoids completely our having to hand-code AST node construction也是大多数其他解析技术所要求的;它倾向于产生与手工编码有所不同的AST)。
  • 解析很多Java代码(产生AST),以确保我们没有解析错误。 [JDK是一个很好的大小示例,很容易获得]
  • 我们的工具可以使用AST并重新生成(prettyprint)源代码,并带有注释,但布局可能有所不同。我们验证
    解析然后美化的代码也会解析。我们重新打印解析后的 pretty-print 版本;这应该与prettyprinted版本相同,因为我们总是产生相同的布局。此测试很好地表明了我们的AST设计和实现不会丢失任何有关源代码
  • 的信息
  • 构建符号表,解决名称的含义,并根据我们的前端验证合法的Java程序进行类型检查。除了足够好(实际上已经足够好!)之外,这没有告诉您任何有关AST性质的信息。因为类型检查任务非常复杂(请检查您的本地Java标准),所以它也很漂亮脆弱的。如果您没有正确的选择,那么将其应用于大量代码时,类型检查可能会失败。同样,JDK对此进行了很好的测试。注意:没有名称和类型解析的Java解析器在实践
  • 中不是很有用
  • 产生类似于JavaDoc的交叉引用,这些交叉引用包含上述结果中的超链接源代码。这意味着很容易手动检查位代码以查看名称解析(因此AST构造)是合理的。
  • 实时显示结果,将前端​​应用于各种程序
    分析和代码转换。我们发现了偶发的问题并进行了修复。

  • 要做到这一点很难。您必须保持密切联系并持续承受测试压力,尤其是因为Java语言不断发展。
    (我们使用Java 8,而Java 9受到威胁)。底线:构建这样的解析器并检查其健全性是一项繁重的工作。

    我们希望有一套独立的测试,但我们还没有野外见过。我希望这些测试(如果存在)(我假设Oracle和IBM都有)真的不会直接测试解析和名称解析,而是测试一些代码是否可以编译并运行以产生已知结果。由于我们没有构建编译器,因此如果拥有这些测试,我们将无法运行它们。我们将能够进行名称解析和类型一致性检查,这将有所帮助。

    [我们实际上是针对多种语言的前端进行的。您认为Java很难,请与C++一起尝试]

    关于java - 测试新的Java解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39687634/

    相关文章:

    parsing - 在 Haskell 中评估解析的表达式

    java - 如何摆脱 fmt :message tags in JSPs in Intellij 中的 "Cannot resolve property key"

    Java 卡 检测到与智能卡的通信错误

    file - 在lua中解析文件的二进制文件

    testing - 如何更新工作服徽章图像以反射(reflect)实际覆盖百分比?

    php - 使用 PHP 衡量(和改进)性能的最佳方法?

    unit-testing - 用 jest 测试 Vue 过滤器

    java - Jena/ARQ : Difference between Model, 图形和数据集

    java - 对于 Jackson,如何安全地共享 ObjectMapper ?有没有不可变的ObjectMapper?

    java - 在 Java 中,如何将单个字段的多个值解析为 String 数组?