简化AST / LinkedList表达式

时间:2017-10-07 19:25:10

标签: java recursion abstract-syntax-tree simplify

我正在研究一种简化和AST表达的方法。但是,我的AST树结构如下:

例如,5 + 6 * sin(y)

父节点不具有指向左右子节点的两个链接,而是具有指向包含其子节点的列表的链接。因此,上面的例子是这样的:

Parent:[+] Children [5, \*], Parent:[\*] Children [6,sin()], Parent:[sin()] Children [y] 

我的代码已经成功简化了只包含已分配的数字或数字和变量的表达式。但是,它不会简化包含数字和未定义变量的表达式 我将定义的变量存储在Map中 每当我输入(1+1)*(2+4*(1+1))1 + a + bab定义的内容时,我都会得到正确答案。但是,当未定义变量时,我的simplify()方法失败。

例如,表达式1 + 1 + a + 2 * 4。调用simplify()时,预期结果类似于2 + a + 8a + 10,但实际结果只是1 + 1 + a + 2 * 4。 Simplify()根本不简化。任何人都可以建议一种方法来改进我的代码来处理未定义的变量案例吗?非常感谢任何帮助。谢谢。

private static AstNode simplifyHelper(IDictionary<String, AstNode> variables, AstNode node) {
        if (node.isNumber()) {
            return node;
        } else if (node.isVariable()) {
            if (!variables.containsKey(node.getName())) {
                return node;
            } else {
                return simplifyHelper(variables, variables.get(node.getName()));
            }
        } else {
            String name = node.getName();

            AstNode one = simplifyHelper(variables, node.getChildren().get(0));
            AstNode two = null;
            if (node.getChildren().size() > 1) {
                two = simplifyHelper(variables, node.getChildren().get(1));
            }

            if (one.isNumber() && (two != null ? two.isNumber() : true)) {
                if (name.equals("+")) {
                    node = new AstNode(one.getNumericValue() + two.getNumericValue());
                } else if (name.equals("-")) {
                    node = new AstNode(one.getNumericValue() - two.getNumericValue());
                } else if (name.equals("*")) {
                    node = new AstNode(one.getNumericValue() * two.getNumericValue());
                } else if (name.equals("^")) {
                    node = new AstNode(Math.pow(one.getNumericValue(), two.getNumericValue()));
                } else if (name.equals("negate")) {
                    node = new AstNode(-one.getNumericValue());
                } else if (name.equals("sin")) {
                    node.getChildren().set(0, new AstNode(one.getNumericValue()));
                } else if (name.equals("cos")) {
                    node.getChildren().set(0, new AstNode(one.getNumericValue()));
                } else if (name.equals("/")) {
                    node.getChildren().set(0, new AstNode(one.getNumericValue()));
                    node.getChildren().set(1, new AstNode(two.getNumericValue()));
                }
            }
        }
        return node;
    }

0 个答案:

没有答案