Antlr4 使用Antlr 4和stringtemplate 4将PL/SQL代码转换为Java

Antlr4 使用Antlr 4和stringtemplate 4将PL/SQL代码转换为Java,antlr4,code-translation,stringtemplate-4,Antlr4,Code Translation,Stringtemplate 4,我正在尝试构造一个转换器,它可以使用Antlr 4和StringTemplate 4将PL/SQL代码转换为Java。我有PL/SQl语法,并且已经为PL/SQl构建了一个解析器,但是我不知道如何进一步解决这个问题。 我发现许多使用antlr和stringtemplate进行语言翻译的文章,但它们都使用antlr 3或antlr 2。因此,当使用Antlr 4和Stringtemplate作为PL/SQL的解析器进行翻译时,有什么区别吗?使用Antlr 4的PL/SQL解析器与使用Antlr 3

我正在尝试构造一个转换器,它可以使用Antlr 4和StringTemplate 4将PL/SQL代码转换为Java。我有PL/SQl语法,并且已经为PL/SQl构建了一个解析器,但是我不知道如何进一步解决这个问题。 我发现许多使用antlr和stringtemplate进行语言翻译的文章,但它们都使用antlr 3或antlr 2。因此,当使用Antlr 4和Stringtemplate作为PL/SQL的解析器进行翻译时,有什么区别吗?使用Antlr 4的PL/SQL解析器与使用Antlr 3的有一些区别


我对编程语言翻译完全陌生,不知道是否有更好的方法来解决这个问题

v4之前的ANTLR具有对StringTemplate的内在支持(您可以指定语法输出为ST)。从v4开始,此支持似乎已被放弃

一种选择是使用监听器或访问者界面手动构建模板。在这种情况下,访问者可能更有用。

我目前正在研究的另一个选项是将ParseTree(解析结果)作为参数分配给模板。我对ParserRuleContext使用自定义ModelAdapter,以便可以从模板访问子上下文

例如: 我假设您正在使用PL/SQL语法。然后您可以有一个模板组,如:

现在,您可以执行以下操作:

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());

希望这有帮助

您能否提供一个示例,例如一个语法/模板片段,它可以与antlr2/3一起使用,但不能与antlr4一起使用?您是在使用porcelli解析器,还是自己编写的?ANTLR3和Antlr4语法的主要区别在于删除了语法谓词refere:。不,我编写了自己的解析器,Ref:您是否使用了与v4兼容的现有语法文件?如果是的话,你能分享链接吗?当然,在这里-你能给出一个使用Listener或visitor界面或与ParseTree一起使用的例子吗?谢谢!你真棒!多么惊人的回答!投票不够。我已经停止在任务中使用侦听器,我已经切换到这个。我注意到侦听器方法最终还是ST的代理。马林,关于这种方法,你还有什么其他的建议吗?再次感谢。
    @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());