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。细节算法的步骤如下所示:
- 使用以下规则解析输入Objective-C代码片段
translationUnit
implementationDefinitionList
interfaceDeclarationList
expression
compoundStatement
- 如果某个规则的解析结果不包含任何错误,则立即返回此规则。
- 选择最接近结束解析错误的规则。
- 如果有两个或多个规则具有最接近结束错误位置的规则,请选择具有最小语法错误数的规则。
Demo
有些测试代码示例使用不同的解析规则进行解析:
translationUnit
:http://swiftify.me/clye5zimplementationDefinitionList
:http://swiftify.me/fpaszainterfaceDeclarationList
:http://swiftify.me/13rv2jcompoundStatement
:http://swiftify.me/4cpl9n
即使输入不正确,我们的算法也能够检测到合适的解析规则:
compoundStatement
有错误:http://swiftify.me/13rv2j/1
以上是关于ANTLR - 如何确定哪种解析树“最适合”某些代码的主要内容,如果未能解决你的问题,请参考以下文章