所以,我目前正在使用ANTLR和Java进行DSL实现。到目前为止,我已经基于ANTLR语法创建了自己的AST层次结构。为什么?因为不幸的是,ANTLR v4不支持output = AST。
无论如何,层次结构可以简化如下:
Expressions
-> BinaryExpressions(Expressions, Expressions)
-> Multiplication(Expression, Expression)
-> Addition(Expression, Expression)
-> Greater_Equal(Expression, Expression)
-> Less_Equal(Expression, Expression)
然后列表继续。无论如何,鉴于此,我到目前为止生成了一个组织良好的层次结构。所以例如3 +(2 * 3)会产生类似的东西:
Addition(Integer(3), Multiplication(Integer(2), Integer(3))
其中对象的类是添加的。
无论如何,鉴于此,我如何遍历这个层次结构?上面的例子只是对整体复杂性的快速概述,但是我如何通过使用递归函数迭代这个?因为,例如,定义(ASTNode节点:someNode)不起作用,因为ASTNode的对象(顶级类 - 所有类的母亲)不能被迭代。
谢谢!
答案 0 :(得分:1)
这取决于你想要做什么,真的。
例如,如果要评估刚刚解析的公式,可以通过定义接口为每个AST节点赋予eval()
方法:
public interface Evaluable {
Something eval();
}
此时,您可以为所有节点定义操作,例如:
public class Integer implements Evaluable {
@Override
public Something eval() {
return value;
}
private final Something value;
}
然后:
public class Multiplication implements Evaluable {
@Override
public Something eval() {
return left.eval().product(right.eval());
}
private final Expression left;
private final Expression right;
}
等等。
此时,您在根节点上调用.eval()
,将以递归方式传播呼叫,并将结果传播回顶部。
这只是一个快速的解决方案。更精细(和复杂)的依赖于双间接模式,其中eval方法传递Evaluator
,它为每种类型定义了一个重载的eval
方法并封装了操作,从而将它们与AST节点。