如何计算这棵树中的表达式?

发布于 2025-01-04 05:29:45 字数 2183 浏览 1 评论 0原文

这是我正在使用的已解析 xml 文件的示例,该文件将其标记为树形形式,

commandList

  assign
    variable
      #text[a]
    expression-int
      #text[1]

  assign
    variable
      #text[b]
    expression-int
      #text[2]

  assign
    variable
      #text[c]
    expression-operation
      operator
        #text[OP_SET]
      arguments
        expression-variable
          variable
            #text[a]
        expression-variable
          variable
            #text[b]

  assign
    variable
      #text[d]
    expression-operation
      operator
        #text[OP_SET]
      arguments
        expression-operation
          operator
            #text[OP_TUPLE]
          arguments
            expression-int
              #text[1]
            expression-int
              #text[2]
        expression-operation
          operator
            #text[OP_TUPLE]
          arguments
            expression-int
              #text[3]
            expression-int
              #text[4]

我希望此输入不难理解。以下是未从 XML 文件解析时的正常情况:

a := 1;
b := 2;
c := {1,2};
d := {(1,2),(3,4)};

等等...

所有赋值对(即值和变量)都将存储在哈希图中,以便可以通过以下方式查找该值:它是可变的并在后面的表达式中使用。我将使用递归下降求值器(我认为?)来根据语法求解表达式。

在过去的 24 小时里,我已经用谷歌搜索了各种各样的东西,并且看到了很多用于基本算术的树评估器(例如 2 + 3 * 8 等),但还没有看到这对我的特定情况如何工作树。

到目前为止,我编写的代码只需找到变量名称(a、b、c、d、e 等),但我无法开始考虑如何编写递归代码,从而为变量提供正确的值。哈希映射。

public void evaluate(Node node){
    HashMap<String, String> assignments = new HashMap<String, String>();
    NodeList assignment = node.getChildNodes();
    for (int i=0; i < assignment.getLength(); i++){ //1 to 13
        Node assign = assignment.item(i);
        Node variable = this.getChild(assign, 0);
        Node varValNode = this.getChild(variable, 0);
        String varVal = varValNode.getNodeValue();

        Node expression = this.getChild(assign, 1);

我的树的文档、节点和节点列表类很不寻常,因为它们不允许使用“getChild”方法,我认为这会节省大量时间。有人知道这是为什么吗?

这里确实是随机问题,我希望它有意义。请让我详细说明任何不清楚的地方,我会尽力而为。我并不是在寻找任何人来为我解决问题,而只是指导我如何决定如何编写这个递归算法。

编辑: 另外,我上面放置的第二个“输入”实际上是输出。本来应该是这样的:

a := 1;
b := 2;
c := @set(a,b);
d := @set(@tuple(1,2),@tuple(3,4));

Here is an example of a parsed xml file I'm working with that tabs it into a tree form

commandList

  assign
    variable
      #text[a]
    expression-int
      #text[1]

  assign
    variable
      #text[b]
    expression-int
      #text[2]

  assign
    variable
      #text[c]
    expression-operation
      operator
        #text[OP_SET]
      arguments
        expression-variable
          variable
            #text[a]
        expression-variable
          variable
            #text[b]

  assign
    variable
      #text[d]
    expression-operation
      operator
        #text[OP_SET]
      arguments
        expression-operation
          operator
            #text[OP_TUPLE]
          arguments
            expression-int
              #text[1]
            expression-int
              #text[2]
        expression-operation
          operator
            #text[OP_TUPLE]
          arguments
            expression-int
              #text[3]
            expression-int
              #text[4]

I hope this input isn't difficult to understand. Here is what it looks like normally when not parsed from an XML file:

a := 1;
b := 2;
c := {1,2};
d := {(1,2),(3,4)};

etc...

All of the assignment pairs (that is, a value and a variable) are to be stored in a hashmap so that the value can be looked up by it's variable and used in later expressions. I'm to use a recursive descent evaluator (I think?) to solve down the expressions according to the grammar.

I've googled all sorts of things for the past 24 hours now and have seen a lot of tree evaluators for basic arithmetic (e.g. 2 + 3 * 8, etc) but haven't been able to see how that would work for my specific tree.

Code I've written so far goes as low as finding the the variable names (a,b,c,d,e etc) but I can't begin to think of how to code the recursion which will provide the right values for the hash map.

public void evaluate(Node node){
    HashMap<String, String> assignments = new HashMap<String, String>();
    NodeList assignment = node.getChildNodes();
    for (int i=0; i < assignment.getLength(); i++){ //1 to 13
        Node assign = assignment.item(i);
        Node variable = this.getChild(assign, 0);
        Node varValNode = this.getChild(variable, 0);
        String varVal = varValNode.getNodeValue();

        Node expression = this.getChild(assign, 1);

The document, node and nodelist classes for my tree are unusual in that they don't allow a 'getChild' method which I think would save a lot of time. Does anybody know why this is?

Really random problem here and I hope it made sense. Please ask me to elaborate on anything that is unclear and I will try the best that I can. I'm not looking for anyone to solve the problem for me but merely instruct me on how to decide how to code this recursive algorithm.

EDIT:
Also, the second 'input' I put above was actually the output. It should have been this:

a := 1;
b := 2;
c := @set(a,b);
d := @set(@tuple(1,2),@tuple(3,4));

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

Oo萌小芽oO 2025-01-11 05:29:45

假设所有值都是整数类型,您应该创建一个 HashMap 来存储变量值,并将其传递给您的 evaluate 方法:

public static void main(String[] args) {
    NodeList commandList = ... // get your XML from somewhere
    Map<string,Integer> vars = new HashMap<string,Integer>();
    for (Node node : commandList) {
        evaluate(node, vars);
    }
    // At this point, vars contains values of all variables assigned in commands
    // from the command list
}

评估应该变得相对简单:

private static Integer evaluate(Node node, Map<string,Integer> vars) {
    if (node is an assignment) {
        String varName = ... // get variable name from node
        Node expr = ... // get the node representing expression being assigned
        Integer value = evaluate(expr, vars);
        vars.put(varName, value);
        return value;
    }
    if (node is a variable reference) {
        String varName = ... // get variable name from node
        return vars.get(varName);
    }
    if (node is an integer constant) {
        String constVal = ... // Get the representation from XML
        return Integer.decode(constVal);
    }
    if (node is a binary expression) {
        Node lhs = ... // Get the left-hand side expression from the node
        Node rhs = ... // Get the right-hand side expression from the node
        Integer lhsVal = evaluate(lhs, vars); 
        Integer rhsVal = evaluate(rhs, vars);
        if (operator is plus) {
            return new Integer(((int)lhsVal) + ((int)rhsVal));
        }
        if (operator is minus) {
            return new Integer(((int)lhsVal) - ((int)rhsVal));
        }
        if (operator is multiply) {
            return new Integer(((int)lhsVal) * ((int)rhsVal));
        }
        if (operator is divide) {
            return new Integer(((int)lhsVal) / ((int)rhsVal));
        }
        // ... and so on
    }
    // ... and so on
}

Assuming that all your values are of integer type, you should create a HashMap<string,Integer> to store variable values, and pass it to your evaluate method:

public static void main(String[] args) {
    NodeList commandList = ... // get your XML from somewhere
    Map<string,Integer> vars = new HashMap<string,Integer>();
    for (Node node : commandList) {
        evaluate(node, vars);
    }
    // At this point, vars contains values of all variables assigned in commands
    // from the command list
}

The evaluation should become relatively straightforward:

private static Integer evaluate(Node node, Map<string,Integer> vars) {
    if (node is an assignment) {
        String varName = ... // get variable name from node
        Node expr = ... // get the node representing expression being assigned
        Integer value = evaluate(expr, vars);
        vars.put(varName, value);
        return value;
    }
    if (node is a variable reference) {
        String varName = ... // get variable name from node
        return vars.get(varName);
    }
    if (node is an integer constant) {
        String constVal = ... // Get the representation from XML
        return Integer.decode(constVal);
    }
    if (node is a binary expression) {
        Node lhs = ... // Get the left-hand side expression from the node
        Node rhs = ... // Get the right-hand side expression from the node
        Integer lhsVal = evaluate(lhs, vars); 
        Integer rhsVal = evaluate(rhs, vars);
        if (operator is plus) {
            return new Integer(((int)lhsVal) + ((int)rhsVal));
        }
        if (operator is minus) {
            return new Integer(((int)lhsVal) - ((int)rhsVal));
        }
        if (operator is multiply) {
            return new Integer(((int)lhsVal) * ((int)rhsVal));
        }
        if (operator is divide) {
            return new Integer(((int)lhsVal) / ((int)rhsVal));
        }
        // ... and so on
    }
    // ... and so on
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文