我正在尝试构建一个能使用Antlr 4和StringTemplate 4将PL/SQL代码转换为Java的翻译器。我有PL/SQl的语法,并且已经为PL/SQL构建了一个解析器,但是我不知道如何进一步解决这个问题。我发现许多使用antlr和articles模板的语言翻译文章,但它们都使用ANTLR 3或ANTLR 2。因此,使用Antlr 4作为PL/SQL的解析器使用Antlr 4进行翻译时是否与Antlr3有一些差异?
我对编程语言翻译完全陌生,不知道是否有更好的方法来解决这个问题。
发布于 2014-02-17 23:20:12
在v4之前,ANTLR对StringTemplate有内在的支持(您可以指定语法输出为ST)。从v4开始,这种支持似乎被放弃了。
一种选择是使用侦听器或访问者接口手动构造模板。在这种情况下,访问者可能更有用。
我目前正在研究的另一个选项是将ParseTree (解析的结果)指定为模板的参数。我对ModelAdapter使用自定义ParserRuleContext,这样我就可以从模板中访问子上下文。
示例:我假设您使用的是PL/SQL语法。然后,您可以有一个模板组,如:
Plsql_block(块) ::= <<{ < ::= (block.declare_section)> }>>声明(Ds) ::=““itemDecl(id) ::= "”varDecl(vd) ::= " ;“body(b)::= "”“
您还需要ModelAdapter用于ParserRuleContext (这只是其中唯一方法的一个例子):
@Override
public Object getProperty(Interpreter interpreter, ST seld, Object o, Object property, String propertyName) throws STNoSuchPropertyException
{
Method m = null;
try {
String mn = "get" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
m = o.getClass().getMethod(mn);
} catch (Exception e) {
}
if (m == null)
try {
m = o.getClass().getDeclaredMethod(propertyName);
} catch (Exception e) {
}
if (m != null) try {
return m.invoke(o);
} catch (Exception e) {
throw new STNoSuchPropertyException(e, property, propertyName);
}
else
throw new STNoSuchPropertyException(null, property, propertyName);
}现在您可以执行以下操作:
ANTLRInputStream input = new ANTLRInputStream(new FileInputStream("block_test.sql"));
PLSQLLexer lexer = new PLSQLLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
PLSQLParser parser = new PLSQLParser(tokens);
parser.setBuildParseTree(true);
ParseTree tree = parser.plsql_block();
STGroupFile stg = new STGroupFile("test.stg");
stg.registerModelAdaptor(ParserRuleContext.class, new ContextModelAdapter());
ST t = stg.getInstanceOf("plsql_block");
t.add("block", tree);
System.out.println(t.render());希望这能有所帮助!
https://stackoverflow.com/questions/20541073
复制相似问题