Skip to content

Instantly share code, notes, and snippets.

@crowsonkb
Created May 19, 2018 17:33
Show Gist options
  • Save crowsonkb/0a524d6a68f454dd8919a67d9145829b to your computer and use it in GitHub Desktop.
Save crowsonkb/0a524d6a68f454dd8919a67d9145829b to your computer and use it in GitHub Desktop.
import pyparsing as pp
from pyparsing import pyparsing_common as ppc
from repl import repl
variables = {}
var = ppc.identifier.copy()
def do_var(t):
try:
return variables[t[0]]
except KeyError as err:
raise pp.ParseFatalException(f'variable {err} is undefined')
var.addParseAction(do_var)
expr = pp.Forward()
expr.setName('expression')
atom = ppc.fnumber | var | pp.Suppress('(') + expr + pp.Suppress(')')
neg = '-' + atom
neg.addParseAction(lambda t: -t[1])
s_atom = neg | atom
term = s_atom + pp.ZeroOrMore((pp.Literal('*') | pp.Literal('/')) + s_atom)
def do_term(t):
result = t[0]
for i in range(2, len(t), 2):
if t[i-1] == '*':
result *= t[i]
elif t[i-1] == '/':
result /= t[i]
return result
term.addParseAction(do_term)
expr <<= term + pp.ZeroOrMore((pp.Literal('+') | pp.Literal('-')) + term)
def do_expr(t):
result = t[0]
for i in range(2, len(t), 2):
if t[i-1] == '+':
result += t[i]
elif t[i-1] == '-':
result -= t[i]
return result
expr.addParseAction(do_expr)
assign = ppc.identifier + '=' + expr
assign.setName('assignment')
def do_assign(t):
variables[t[0]] = t[2]
return t[2]
assign.addParseAction(do_assign)
stmt = assign | expr
repl(stmt)
from prompt_toolkit import prompt
from prompt_toolkit.history import InMemoryHistory
from pyparsing import ParseBaseException
def sgr(*args):
return '\033[{}m'.format(';'.join(str(i) for i in args))
def repl(parser):
parser.validate()
history = InMemoryHistory()
while True:
try:
s = prompt('> ', history=history)
result = parser.parseString(s, parseAll=True)[0]
print(result)
except ParseBaseException as err:
print(f'{sgr(1, 31)}{err.__class__.__name__}{sgr(0)}: {err}')
except KeyboardInterrupt:
pass
except EOFError:
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment