ANTLR - 如何确定哪种解析树“最适合”某些代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ANTLR - 如何确定哪种解析树“最适合”某些代码相关的知识,希望对你有一定的参考价值。

我正在使用ANTLR构建一个程序,我要求用户输入一些Java代码,然后它会发出相应的C#代码。在我的程序中,我要求用户输入一些Java代码然后解析它。到目前为止,我一直在假设他们将输入一些可以自行解析为有效编译单元的东西,例如:就像是

package foo;

class A { ... }
class B { ... }
class C { ... }

然而,情况并非总是如此。他们可能只是从类的内部输入代码:

public void method1() {
    ...
}

public void method2() {
    ...
}

或者方法的内部:

System.out.print("hello ");
System.out.println("world!");

甚至只是一个表达:

context.getSystemService(Context.ACTIVITY_SERVICE)

如果我尝试通过调用parser.compilationUnit()来解析这些片段,它将无法正常工作,因为大多数代码都被解析为错误节点。我需要根据代码的性质调用正确的方法,例如parser.expression()parser.blockStatements()。但是,我不想要求用户明确指出这一点。推断我正在解析什么类型的代码的最佳方法是什么?

答案

而不是试图猜测有效的语法规则入口点来解析未知范围的语言片段,而是逐步将范围包装器添加到源文本,直到实现有效的顶级规则解析。

也就是说,随着每个连续的解析失败,逐步添加虚拟包,类和方法语句作为源文本包装器。

无论添加哪个包装器来实现成功的解析,都将是已知数量。因此,可以容易地识别表示原始源文本的分析树节点。

可能想要使用快速失败的解析器;使用BailErrorStrategy构造解析器以获取此行为。

另一答案

我们在Swiftify中的算法尝试从定义的规则集中选择最合适的解析规则。此Web服务将Objective-C代码片段转换为Swift,您可以立即估算转换质量。

算法

我们使用开源的ObjectiveC grammar。细节算法的步骤如下所示:

  1. 使用以下规则解析输入Objective-C代码片段 translationUnit implementationDefinitionList interfaceDeclarationList expression compoundStatement
  2. 如果某个规则的解析结果不包含任何错误,则立即返回此规则。
  3. 选择最接近结束解析错误的规则。
  4. 如果有两个或多个规则具有最接近结束错误位置的规则,请选择具有最小语法错误数的规则。

Demo

有些测试代码示例使用不同的解析规则进行解析:

即使输入不正确,我们的算法也能够检测到合适的解析规则:

以上是关于ANTLR - 如何确定哪种解析树“最适合”某些代码的主要内容,如果未能解决你的问题,请参考以下文章

Spark SQL源码解析Antlr4解析Sql并生成树

确定哪种方法最适合比较排序算法。小型数据收集的分治或招聘问题

哪种算法最适合在树中查找 LCA?

哪种排序算法最适合重新排序几乎完全排序的列表?

antlr提取代码注释

使用Antlr4和neo4j解析sql生成数据地图