I have this mathematical expression:
tree = ast.parse('1 + 2 + 3 + x')
which corresponds to this abstract syntax tree:
Module(body=[Expr(value=BinOp(left=BinOp(left=BinOp(left=Num(n=1), op=Add(), right=Num(n=2)), op=Add(), right=Num(n=3)), op=Add(), right=Name(id='x', ctx=Load())))])
and I would like to simplify it - that is, get this:
Module(body=[Expr(value=BinOp(left=Num(n=6), op=Add(), right=Name(id='x', ctx=Load())))])
According to the documentation, I should use the NodeTransformer class. A suggestion in the docs says the following:
Keep in mind that if the node you’re operating on has child nodes you must either transform the child nodes yourself or call the generic_visit() method for the node first.
I tried implementing my own transformer:
class Evaluator(ast.NodeTransformer):
def visit_BinOp(self, node):
print('Evaluating ', ast.dump(node))
for child in ast.iter_child_nodes(node):
self.visit(child)
if type(node.left) == ast.Num and type(node.right) == ast.Num:
print(ast.literal_eval(node))
return ast.copy_location(ast.Subscript(value=ast.literal_eval(node)), node)
else:
return node
What it should do in this specific case is simplify 1+2 into 3, and then 3 +3 into 6. It does simplify the binary operations I want to simplify, but it doesn't update the original Syntax Tree. I tried different approaches but I still don't get how I can recursively simplify all binary operations (in a depth-first manner). Could anyone point me in the right direction?
Thank you.