使用Antlr / Stringtemplates编写翻译器

时间:2011-02-09 06:56:30

标签: stringtemplate

我想写一个翻译。我们的想法是将特殊形式的C ++接口转换为C ++ / CLI。我有一个antlr语法解析一切并生成AST。现在我想使用这些信息和一些字符串模板来发出源代码。

我的想法是在某种对象层次结构中使用属性转换AST(例如,包含索引属性方法的接口对象包含方法描述对象。 然后使用根对象提供主字符串模板,并将属性插入正确的位置或将它们传递给子模板。

现在我的问题: 如何编写需要被调用一些未定义次数的字符串模板/属性?示例:接口包含许多方法。这意味着,方法的子模板需要多次调用,每次都使用不同的属性。我怎么能把它写成stringtemplate& amp;索引属性?

感谢您的帮助 托拜厄斯

1 个答案:

答案 0 :(得分:0)

我正在做一些非常相似的事情。基本思想是您的模型必须公开某个对象的列表,并在字符串模板中使用该列表。例如,假设我有一个非常脑死亡的实现。我将使用Java,因为这是我最了解的;你应该明白这个想法。

https://gist.github.com/894632

public class GeneratedClass {
    private String accessModifier;
    private String name;
    private String superClass;
    private List<Method> methods;
}

public class Method {
    private String comments;
    private String name;
    private String accessModifier;
    private Type returnType;
    private List<Argument> arguments;
    private String body;
}

public class Argument {
    private Type type;
    private String name;
}

public class Type {
    private String name;
}

对于我的模板,我可能会有以下内容:

group Java;

class(accessModifier, name, superclass, methods)::=<<

$accessModifier$ class $name$ extends $superclass$ {

    $methods:method(); separator="\n"$

}
>>

method(method)::=<<
/**
 $method.comments$
*/
$method.accessModifier$ $method.returnType.name$ $name$ ($method.arguments:argument(); separator=","$) {
    $method.body$
}
>>

argument(argument)::=<<
$argument.type.name$ $argument.name$
>>

关键是我在功能上为每个方法对象应用了一个模板;这就是$methods:method()的作用。如果我有一个空列表,则根本不会调用任何模板。这可以处理可变大小的问题。我在方法定义中做了类似的事情; ($method.arguments:argument(); separator=","$)。这将在括号之间创建一个以逗号分隔的方法参数列表,就像您期望的那样。