Skip to content

Instantly share code, notes, and snippets.

@bradbeattie
Created June 24, 2016 20:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradbeattie/a893898dc23b8eec236043d78aeeb917 to your computer and use it in GitHub Desktop.
Save bradbeattie/a893898dc23b8eec236043d78aeeb917 to your computer and use it in GitHub Desktop.
Python AST parser
import ast
import operator as op
# Supported tokens and their operators
operators = {
ast.Add: op.add,
ast.Sub: op.sub,
ast.Mult: op.mul,
ast.Div: op.truediv,
}
def evaluate(expr):
return limited_eval(ast.parse(expr, mode='eval').body)
def limited_eval(node):
if isinstance(node, ast.Num): # <number>
return node.n
elif isinstance(node, ast.BinOp): # <left> <operator> <right>
return operators[type(node.op)](limited_eval(node.left), limited_eval(node.right))
elif isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
return operators[type(node.op)](limited_eval(node.operand))
else:
raise TypeError("Operations are limited to a permitted subset", node, operators.keys())
assert evaluate("14 + 2 * 3 - 6 / 2") == 17
assert evaluate("(1 + 2) * 3") == 9
assert evaluate("__import__('os').remove('foobar.file')")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment