首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Antlr 4和SQL模板4将PL/SQL代码转换为Java

使用Antlr 4和SQL模板4将PL/SQL代码转换为Java
EN

Stack Overflow用户
提问于 2013-12-12 10:35:12
回答 1查看 5.7K关注 0票数 6

我正在尝试构建一个能使用Antlr 4和StringTemplate 4将PL/SQL代码转换为Java的翻译器。我有PL/SQl的语法,并且已经为PL/SQL构建了一个解析器,但是我不知道如何进一步解决这个问题。我发现许多使用antlr和articles模板的语言翻译文章,但它们都使用ANTLR 3或ANTLR 2。因此,使用Antlr 4作为PL/SQL的解析器使用Antlr 4进行翻译时是否与Antlr3有一些差异?

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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 (这只是其中唯一方法的一个例子):

代码语言:javascript
复制
    @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);
}

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

代码语言:javascript
复制
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());

希望这能有所帮助!

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20541073

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档