Translation of PL/SQL code to Java using Antlr 4 and stringtemplate 4
Asked Answered
C

1

6

I am trying to construct a translator that could convert PL/SQL code to Java using Antlr 4 and StringTemplate 4. I have the grammar of PL/SQl and have already build a parser for PL/SQL but i have no idea how to approach the problem further. I found many articles of language translation using antlr and stringtemplate but they all use ANTLR 3 or ANTLR 2 . So is there any difference when using Antlr 4 to translate along with Stringtemplate as the parser for PL/SQL using Antlr 4 had some differences than Antlr3

I am completely new to Programming language translation and don't know if there is any better way to approach the problem.

Cusk answered 12/12, 2013 at 10:35 Comment(4)
Could you provide an example, for instance a grammar / template snippet that works with antlr2/3 but not with antlr4? Are you using the porcelli parser, or did you write your own?Trowbridge
The main difference between ANTLR3's and ANTLR 4' grammar is removal of syntactic predicates Refer: #18431658. No, I wrote my own parser, Ref: github.com/developeron29/Antlr-4-PLSQL-Parser---AST-GeneratorCusk
did you use existing grammar file which is compatible with v4? if so can you share the linkSanfo
Yeah sure, Its here - github.com/developeron29/PLSQLParser/blob/master/PLSQL.g4Cusk
O
10

ANTLR prior to v4 had intrinsic support for StringTemplate (you could specify that your grammar output is ST). As of v4, this support seems to be dropped.

One option is to use Listener or Visitor interfaces to manually construct your templates. Visitor is likely more useful in this context.

The other option I'm currently investigating is assigning ParseTree (result from parsing) as a parameter to the template. I use custom ModelAdapter for ParserRuleContext so I can access sub-contexts from the templates.

Example: I'm assuming you are using grammar for PL/SQL. Then you could have a template group like:

plsql_block(block)   ::= <<{  
   <declarations(block.declare_section)>
   <body(block.body)> 
}>>

declarations(ds)     ::= "<ds.item_declaration:itemDecl()>"
itemDecl(id)         ::= "<id.variable_declaration:varDecl()>" 
varDecl(vd)          ::= "<vd.datatype.text> <vd.ID>;"

body(b)              ::= "<b.text>"

You would also need ModelAdapter for ParserRuleContext (this is just an example of the only method in it):

    @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);
}

Now you can do the following:

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

Hope this helps!

Osteoplastic answered 17/2, 2014 at 23:20 Comment(2)
Can you please give an example of using Listener or visitor interface or using with ParseTree?Cusk
What an amazing answer! Can't upvote enough. I've stopped using a listener for my task and I've switched to this. I noticed that the listener methods ended up being proxies to ST anyway. Any other tips you can provide about this approach Marin? Thanks again.Angelo

© 2022 - 2024 — McMap. All rights reserved.