I’m looking at pragmatically translating huge amounts of relatively simple TSQL code to Groovy code. There are a number of reasons sure, but the driving reason is just to see if it can be done and in the process learn about compilers/grammers/ etc.
Antlr4 seems like the ideal tool for this problem (Java is a plus).
Tokenizing / parsing the TSQL (using a grammar file), and reading the tree using the generated Listener/Visitor is pretty straight forward.
I know I could just create the string representation of the Groovy code inside of my inherited visitor, but coupling the matching Groovy token values with my TSQLVisitor doesn’t seem like the cleanest solution.
What would be considered the best practice here? and in general for mapping one language to another in Antlr4 ?
Things I’m considering:
- Using StringTemplate, and defining my groovy code in an STG file (my TSQLVisitor would use these templates and return the full string representation of the Groovy code).
- Switch to Antlr3 which supports adding StringTemplate logic directly into the Grammar file.
Best practices depends on your objective. Where the conversion must not introduce or must minimize any added technical baggage or performance or maintenance overhead, then Ira's comments control.
If, however, performance and maintenance are not essential issues, the conversion is close to 1:1 semantically, and you have the ability to add run-time support code in the target environment, then an Antlr4 style conversion becomes possible. Of course, the greater the semantic differences between the source and target languages the more difficult it becomes - the size and complexity of the target run-time support lib becomes counter-productive. And, it only takes one deep-seated difference to drive a requirement for an analysis tool like Ira has developed.
Presuming an adequate Groovy lib has been developed, production of the target code is reduced to near one-liner's called for from the visitor onEntry and onExit routines. Coupling can be reduced somewhat by abstracting the rendering: