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

问题描述 投票:4回答:2

我正在使用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()。但是,我不想要求用户明确指出这一点。推断我正在解析什么类型的代码的最佳方法是什么?

java parsing compiler-construction antlr antlr4
2个回答
1
投票

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

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

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

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


1
投票

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

算法

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

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

Demo

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

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

© www.soinside.com 2019 - 2024. All rights reserved.