【问题标题】:Traversing a json abstract syntax tree to build boolean expression遍历 json 抽象语法树构建布尔表达式
【发布时间】:2013-05-23 02:49:25
【问题描述】:

在对 google 和堆栈溢出进行数小时研究后,我得出结论,以下 JSON 结构正确地描述了布尔表达式。我不是非常热衷于算法,但是在英语(和/或 javascript)中,您将如何递归遍历树来重建表达式,因此在本例中,表达式将显示为:

13 或 14 或(18 和 20 和 19)

var booleanExpression = {
    op   : 'or',
    left : {
        op  : 'or',
        left: {
            op   : 'or',
            left : {
                op   : 'literal',
                value: '14'
            },
            right: {
                op   : 'and',
                left : {
                    op   : 'and',
                    left : {
                        op   : 'literal',
                        value: '20'
                    },
                    right: {
                        op   : 'literal',
                        value: '19'
                    }
                },
                right: {
                    op   : 'literal',
                    value: '18'
                }
            }
        }
    },
    right: {
        op   : 'literal',
        value: '13'
    }
};

【问题讨论】:

    标签: javascript json tree boolean


    【解决方案1】:

    Recursion 是评估表达式树的朋友。您需要做的就是处理各个操作类型并推迟对其子项的递归评估。通常,解析/评估事物的困难部分是将其变成基于树的结构。之后递归遍历树就很容易了:

    function eval_expr(expr) {
      if( !expr ) { return false; }
      var op = expr.op;
      if( op == 'literal' ) {
        return expr.value;
      } else if( op == 'or' ) {
        return "(" + eval_expr(expr.left) + ") or (" + eval_expr(expr.right) + ")";
      } else if( op == 'and' ) {
        return "(" + eval_expr(expr.left) + ") and (" + eval_expr(expr.right) + ")";
      }
      console.error("Unhandled op:" + expr.op);
    }
    
    
    > eval_expr(booleanExpression);
    "(((14) or (((20) and (19)) and (18))) or (false)) or (13)"
    

    请注意,此函数将非零“文字”类型值视为真,零值视为假。

    【讨论】:

    • 我不是在尝试评估树,我只是想将树结构重建为字符串。
    • @ThinkingInBits 代码看起来是一样的——只是评估的结果是连接,而不是得出数字结果,例如return eval_expr(expr.left) + " OR " + eval_expr(expr.right);(和处理括号等)
    • 您还需要包含括号。否则,一旦“字符串化”,运算符优先级将不正确。
    • sehrope:如何在此处包含括号?
    • 有什么方法可以不包括根节点的 or (false))?
    猜你喜欢
    • 2011-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 2021-11-09
    • 2019-05-20
    相关资源
    最近更新 更多