我目前正在开始一个自动化的软件分析项目,我正处于研究阶段.我对解析非常陌生,很难找到关于主要Java解析选项之间的比较的参考资料.我知道JavaParser是使用JavaCC创建的,它包含哪些JavaCC不包含的功能?在决定使用哪个解析器时,我需要注意的主要区别是什么.类似地,与这两个相比,Eclipse JDT包含的哪些功能可能对我有用?感谢您提前给我答复.

推荐答案

这并不是一个详尽的回答,只是对你的问题的具体部分进行了一点澄清,并就更一般的问题提出了我的5点看法.我假设您想要分析Java代码.

我还假设这是将代码作为数据使用的一种练习 语法/解析器.否则,code analysis字段本身就是巨大的,有非常特定的利基,比如查找错误或判断代码的线程安全.

一般来说,有大量的工具可用于此目的,但如果我们将它们限制在用Java编写的工具上,开源领域中最大的鱼似乎就在这里.有关更完整的列表,请参阅一些JavaParser作者的this blogthis以了解该主题的一般介绍.也许也值得看看他们关于总体上有些重叠的language development主题的material .

在事后的观点中,这些问题潜伏在这一回应的背景中:

  • 您首先需要解析吗?例如,获取单词或行数将不需要全面的解析.如果您想获得所有字符串常量或标识符,则可以使用Regexscanner(通常是解析的第一个阶段).
  • 这是一种交互式(IDE)设置,需要大量反馈、编辑支持和后台连续incremental compilation吗?
  • 您需要处理不完整或(暂时)损坏的代码吗?
  • 您是否必须处理超出解析范围的事情,例如类型判断?
  • 这也只是关于分析或转型吗?
  • 在给定的时间限制下,要处理的代码的大小是多少?更通用的工具不会给您提供最快的处理速度.
  • 您是否需要一个紧凑的独立工具,或者您可以忍受大量的依赖关系吗?
  • 输出的 struct 与其预期操作的匹配程度如何?对于给定的一段代码,所有工具都会给出abstract syntax tree (AST)分,但每个AST都是不同的(将在下面讨论).

让我们从具体到一般:

Javparser解析一段静态的Java代码(注意:仅限Java,仅限静态),并给出AST.该包还有SymbolResolver,它试图确定符号的Java类型.它被称为JavaParser,但它不仅仅是一个解析器,它支持用于查询的Java流,并带有AST操作和代码生成功能.主要支持者是一家意大利公司BTW.

Eclipse JDT相当庞大,org.eclipse.jdt.core.dom.ASTParser为您提供了AST.但与JavaParser相反,一切都是为了在交互开发环境中处理Java(仅限).因为Eclipse可以执行重构,所以它必须能够分析和操作AST,这里是an example(作为this POST的一部分),here是重构API的综合示例.如果您正在构建一些支持代码编写的集成功能,那么无论如何,这都将是您的首选.如果您想要一些compile-on-the-fly-and-give-feedback-as-the-code-gets-typed功能,就需要某种形式的eclipse JDTsupports增量编译.

我还使用了spoon库(由法国一所大学开发),它与JavaParser具有相同的关注点,也可以进行符号解析,但具有不同的查询机制.它构建在org.eclipse.jdt.core之上.这些工具中的每一个都会为相同的Java代码提供不同的AST,以反映它们的预期用例,Spoon是这样描述的:

一种编程语言可以有不同的元模型.抽象语法树(AST)或模型是元模型的实例.每个元模型以及相应的每个AST都或多或少 根据手头的任务进行适当调整.例如,Java元数据 Sun的编译器模型(Javac)已经设计并优化用于 编译为字节码,而Java元的主要用途是 模型的Eclipse IDE(JDT)是为了支持不同的任务 以集成方式进行软件开发(代码完成、快速 修复编译错误、调试等).

哪种框架适合您的需求在很大程度上取决于您的用例.例如,如果你需要符号解析,你可能会被那些提供它的选项所束缚.我try try Java代码转换程序,发现Java Parser元模型比Spoon的模型更合适,并且喜欢它的少量依赖项.

在AST获得句柄的一般(尽管非增量)方法是一个解析器生成器,如JavaCC(Read:编译器编译器(又名编译器生成器),用Java编写,可以为您有语法的任何东西创建解析器)或ANTLR.如果你想解析SQL,你给他们一个SQL语法,如果你想解析Java代码,你给他们this one(ANTLR格式)或this one(JavaCC格式).结果将是一个解析器,它可以为您提供一段给定代码的AST和一个访问者类.

除了一般性之外,我认为这种方法的理由是更严格的控制,以及根据需要调整Java语法的可能性,例如引入额外的非终端 node .或者,如果您想try 一下,可以使用它来解析嵌入的非Java代码片段,例如SQL查询字符串.

顺便说一句.ANTLR可以处理语法中的直接左递归,而JavaCC不能,例如,对于像在exp := exp + exp中这样的二元运算符的算术表达式

如果您的目标是在开发人员编写代码时支持他们的活动,则必须处理损坏或不完整的代码.虽然我没有使用它的JDT,但我希望它能够优雅地处理这种情况,并提供合理的反馈.此外,如果可能,ANTLR将从语法错误中恢复,并为您提供未被 destruct 的所有内容的AST.我不记得Spoon和JavaParser在出错的情况下做了什么,我想,他们希望代码在语法上是正确的.

Java相关问答推荐

一般类型和kotlin阴影Java函数的问题

将@ManyToOne JPA Composite Key用作Id保存实体添加额外参数

try Dockerize Maven应用程序,但发布版本21不支持"

那么比较似乎不是词典学的,尽管doctor 这么说

为什么接口中的主函数而不是类中的主函数在Java 17中编译和运行没有问题?

如何使用Java API在Oracle ODI中运行模拟?

H2弹簧靴试验跌落台

将不受支持的时区UT重写为UTC是否节省?

如何创建同一类的另一个对象,该对象位于变量中?

为什么在maven中,getLast方法不适用于List?

每次FXMLLoader调用ApplationConext.getBean(类)时创建@Component的新实例

如何在代码中将行呈现在矩形前面?

如何在 spring 数据的MongoDB派生查询方法中使用$EXISTS

将stringBuilder + forloop转换为stream + map

在Java中将.GRF转换为图像文件

将BlockingQueue+守护程序线程替换为执行器

验证没有';t work on Hibernate Entity';s字段

Cucumber中第二个网页的类对象未初始化

双对象供应商

什么是;u〃;平均值;jdku;在java开发工具包中?