从抽象语法树生成前缀表达式

时间:2013-10-01 13:29:32

标签: java algorithm

我正在使用一个Java库:给定一个中缀表达式(1 + 3) + 4,它可以构建一个AST,如下所示:

                              BinaryIntegerExpression  
                              /          |            \
              IntegerExpression          op         IntegerExpression
                      |                  |                  |
           BinaryIntegerExpression       +           IntegerConstant
           /          |            \                        |
   IntegerExpression  op      IntegerExpression             4
          |           |             |
    IntegerConstant   +       IntegerConstant
          |                         |
          1                         3

基本上,BinaryIntegerExpression和IntegerConstant是IntegerExpression的子类。 该库有一个抽象类Visitor,它允许您覆盖preVisit和postVisit来遍历树。除了那之外,我无法触及任何东西。

这是我的尝试。我尝试使用简单的递归来生成前缀表达式。它适用于小例子。

public void preVisit(BinaryIntegerExpression expr) {

        if(stop == true)
            return;

        PrefixVisitor left = new PrefixVisitor();
        left.preVisit(expr.getLeft());

        PrefixVisitor right = new PrefixVisitor();
        right.preVisit(expr.getRight());

        str = "( " + expr.getOp().toString() + " " + left.getExpression() + " " + right.getExpression() + " )";
        stop = true;
    }

public void preVisit(IntegerConstant expr) {

        if(stop == true)
            return;

        str = " " + expr.toString() + " ";
    }

但是,我必须处理大小超过100MB的表达式,所以我的内存和性能都有问题。因此,我想使用堆栈优化此过程。任何人都可以给我一个提示吗?感谢。

========================
编辑:表达式是复杂分析的结果,我只是得到结果来处理它,并且无法从开始构建结果。

1 个答案:

答案 0 :(得分:4)

目前尚不清楚您要做什么,但我会从一开始就将表达式构建到单个StringBuilder中。这会更快,但不会使用更少的内存。一个100 MB的文本文件使用200 MB来加载另外200 MB来操作一个字符串,另外你的表达式建议你想要几GB的内存。

如果您仍在使用太多内存,我建议将表达式流式传输到文件中。处理此问题的一般方法是使用Appender这是StringBuilder和PrintWriter的接口。

提示:考虑如何在不创建任何对象的情况下构建文本表达式(至少不直接)。如果你这样做会更快。

最简单的解决方案是确保您有足够的堆并使用CPU和内存分析器来提高效率。