我正在用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()
。但是,我不想要求用户明确指出这一点。推断我正在解析什么类型的代码的最佳方法是什么?
答案 0 :(得分:1)
不是试图猜测有效的语法规则入口点来解析未知范围的语言片段,而是逐步将范围包装器添加到源文本,直到实现有效的顶级规则解析。
也就是说,随着每个连续的解析失败,逐步添加虚拟包,类和&方法语句作为源文本包装器。
无论添加哪个包装器来实现成功的解析,都将是已知数量。因此,可以很容易地识别表示原始源文本的分析树节点。
可能想要使用快速失败的解析器;使用BailErrorStrategy
构造解析器以获得此行为。
答案 1 :(得分:1)
我们在Swiftify中的算法尝试从定义的规则集中选择最合适的解析规则。此Web服务将Objective-C代码片段转换为Swift,您可以立即估算转换质量。
我们使用开源ObjectiveC grammar。细节算法步骤如下:
translationUnit
implementationDefinitionList
interfaceDeclarationList
expression
compoundStatement
有些测试代码示例使用不同的解析规则进行解析:
translationUnit
:http://swiftify.me/clye5z implementationDefinitionList
:http://swiftify.me/fpasza interfaceDeclarationList
:http://swiftify.me/13rv2j compoundStatement
:http://swiftify.me/4cpl9n 即使输入错误,我们的算法也能够检测到合适的解析规则:
compoundStatement
错误:http://swiftify.me/13rv2j/1