He estado trabajando en un intérprete matemático simple y estoy atascado en un problema.
No puedo averiguar cómo recorrer el objeto en el intérprete. Mis intentos no funcionan en absoluto o causan bucles infinitos hasta que Javascript alcanza su cantidad máxima de memoria.
El resultado del analizador se vería así para un simple 2 + 2 + 3 :
{ "operator": "+", "left": { "operator": "+", "left": { "type": "NUMBER", "value": 2 }, "right": { "type": "NUMBER", "value": 2 } }, "right": { "type": "NUMBER", "value": 3 } }Aquí está uno de los intentos que he hecho.
interpret(node) { node.left = this.parseNode(node.left); node.right = this.parseNode(node.right); return this.parseNum(node.left, node.right, node.operator); } parseNode(node) { let left = node.left; let right = node.right; while (left != null) { left = this.destructure(left); } while (right != null) { right = this.destructure(right); } if (left == null && right == null) { return { ...node }; } else { return { type: "NUMBER", value: this.parseNum(left, right, node.operator), }; } }La función de número de análisis (parseNum) es bastante simple, por lo que no creo que necesite compartirla. Todo lo que hace es tomar el operador y sumar/multiplicar/restar/dividir los dos primeros elementos en función de eso.
Cualquier ayuda será apreciada, gracias.
Lo que quiere es reducir recursivamente cada nodo a un solo valor inspeccionándolo y...
const root = {"operator":"+","left":{"operator":"+","left":{"type":"NUMBER","value":2},"right":{"type":"NUMBER","value":2}},"right":{"type":"NUMBER","value":3}} // Operator functions const operators = { "+": (l, r) => l + r, } // Expression evaluation const evaluate = ({ value: l }, { value: r }, operator) => operators[operator](l, r) const isValueNode = node => "value" in node // Reduce a node to a _value_ node const reducer = (node) => { // Already a value node? Just return it if (isValueNode(node)) return node return { type: "NUMBER", // no idea what this is for ¯\_(ツ)_/¯ value: evaluate( reducer(node.left), // recursively reduce the _left_ node reducer(node.right), // recursively reduce the _right_ node node.operator ) } } console.log(reducer(root))