Antlr4语言翻译-将模板逻辑与访客类分开? [英] Antlr4 language translation - separating template logic from visitor class?

查看:116
本文介绍了Antlr4语言翻译-将模板逻辑与访客类分开?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究实用地将大量相对简单的TSQL代码转换为Groovy代码.当然有很多原因,但是驱动原因只是看它是否可以完成,并在此过程中了解编译器/语法/等.

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似乎是解决此问题的理想工具(Java优先).

Antlr4 seems like the ideal tool for this problem (Java is a plus).

标记/解析TSQL(使用语法文件),并使用生成的Listener/Visitor读取树非常简单.

Tokenizing / parsing the TSQL (using a grammar file), and reading the tree using the generated Listener/Visitor is pretty straight forward.

我知道我可以在继承的访问者内部创建Groovy代码的字符串表示形式,但是将匹配的Groovy令牌值与TSQLVisitor耦合似乎不是最干净的解决方案.

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.

什么是最佳实践?以及通常要在Antlr4中将一种语言映射到另一种语言?

我正在考虑的事情:

  1. 使用StringTemplate,并在STG文件中定义我的常规代码 (我的TSQLVisitor将使用这些模板并返回完整的字符串 Groovy代码的表示形式).
  2. 切换到Antlr3, 支持将StringTemplate逻辑直接添加到语法文件中.
  1. 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).
  2. Switch to Antlr3 which supports adding StringTemplate logic directly into the Grammar file.

推荐答案

最佳实践取决于您的目标.如果转换不得引入或必须使增加的技术负担,性能或维护开销最小化,则由Ira的注释控制.

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.

但是,如果性能和维护不是关键问题,则转换在语义上接近1:1,并且您能够在目标环境中添加运行时支持代码,则可以进行Antlr4样式转换.当然,源语言和目标语言之间的语义差异越大,难度就越大-目标运行时支持库的大小和复杂性会适得其反.而且,只需要一个根深蒂固的区别就可以推动对像Ira这样开发的分析工具的需求.

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.

假设已经开发了足够的Groovy库,则访问者onEntry和onExit例程要求将目标代码的生成减少到接近一类的要求.通过抽象化渲染,可以在某种程度上减少耦合:

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:

public class Render {

    private static final String templateDir = "some/path/to/templates";
    private STGroupFile blocksGroup;
    private STGroupFile stmtGroup;

    public Render() {
        blocksGroup = new STGroupFile(Strings.concatAsClassPath(templateDir, "Blocks.stg"));
        stmtGroup = new STGroupFile(Strings.concatAsClassPath(templateDir, "Statements.stg"));
    }

    public String gen(GenType type, String name) {
        return gen(type, name, null);
    }

    /**
     * type is an enum, identifying the group template
     * name is the template name within the group
     * varMap contains the named values to be passed to the template
     */
    public String gen(GenType type, String name, Map<String, Object> varMap) {
        Log.debug(this, name);
        STGroupFile stf = null;
        switch (type) {
            case BLOCK:
                stf = blocksGroup;
                break;
            case STMT:
                stf = stmtGroup;
                break;
        }
        ST st = stf.getInstanceOf(name);
        if (varMap != null) {
            for (String varName : varMap.keySet()) {
                try {
                    st.add(varName, varMap.get(varName));
                } catch (NullPointerException e) {
                    Log.error(this, "Error adding attribute: " + name + ":" + varName + " [" + e.getMessage() + "]");
                }
            }
        }
        return st.render();
    }
}

这篇关于Antlr4语言翻译-将模板逻辑与访客类分开?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆