Skip to content

Instantly share code, notes, and snippets.

@syoyo
Created October 5, 2008 08:29
Show Gist options
  • Save syoyo/14862 to your computer and use it in GitHub Desktop.
Save syoyo/14862 to your computer and use it in GitHub Desktop.
from pyparsing import *
def buildVar(s, l, t):
return [["id", t[0][0]]]
def buildExpr(s, l, t):
e = t[0]
if e[1] == "+":
return [["add", e[0], e[2]]]
elif e[1] == "-":
return [["sub", e[0], e[2]]]
elif e[1] == "*":
return [["mul", e[0], e[2]]]
elif e[1] == "/":
return [["div", e[0], e[2]]]
else:
raise Exception("Unknown expression:", t)
integer = Combine(Optional(oneOf("+ -")) + Word(nums)).setParseAction(buildVar)
mulOp = oneOf("* /")
addOp = oneOf("+ -")
lpar = Literal("(").suppress()
rpar = Literal(")").suppress()
def evalExpr(e):
op = e[0]
if op == "id":
return int(e[1])
elif op == "add":
return evalExpr(e[1]) + evalExpr(e[2])
elif op == "sub":
return evalExpr(e[1]) - evalExpr(e[2])
elif op == "mul":
return evalExpr(e[1]) * evalExpr(e[2])
elif op == "div":
return evalExpr(e[1]) / evalExpr(e[2])
else:
raise Exception("Unknown expression:", e)
expr = operatorPrecedence(integer,
[ (mulOp, 2, opAssoc.LEFT, buildExpr)
, (addOp, 2, opAssoc.LEFT, buildExpr)
]
)
program = expr + StringEnd()
try:
input = "(4+3)*7+9"
print "input =", input
e = program.parseString(input)
print "AST =", e
print "eval =", evalExpr(e[0])
print ""
input = "(4+3)*a" # expects parse err
print "input =", input
e = program.parseString(input)
print "AST =", e
print "eval =", evalExpr(e[0])
except ParseException, err:
print err.line
print " "*(err.column-1) + "^"
print err
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment