Skip to content

Instantly share code, notes, and snippets.

@erezsh
Created July 9, 2021 14:16
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 erezsh/530823b1754412375612ee0069b21c7f to your computer and use it in GitHub Desktop.
Save erezsh/530823b1754412375612ee0069b21c7f to your computer and use it in GitHub Desktop.
?start: (statement | _NL) *
?statement: simple_statement _NL
| print_statement _NL
?simple_statement: assign | expr
assign: NAME "=" sum
?expr: sum
print_statement: "print" expr
?sum: product
| sum "+" product -> add
| sum "-" product -> sub
?product: atom
| product "*" atom -> mul
| product "/" atom -> div
?atom: NUMBER -> number
| "-" atom -> neg
| NAME -> var
| "(" sum ")"
%import common.CNAME -> NAME
%import common.NUMBER
%import common.WS_INLINE
%import common.NEWLINE -> _NL
%ignore WS_INLINE
from lark import Lark, v_args, Transformer
from lark.visitors import Interpreter, visit_children_decor
p = Lark.open('interp.lark', parser='lalr', rel_to=__file__)
code = """
b = 4
a = b*2
print a+1
"""
tree = p.parse(code)
@v_args(inline=True)
class MyEval(Transformer):
from operator import add, sub, mul, truediv as div, neg
number = float
def __init__(self, ns):
self.ns = ns
def var(self, name):
return self.ns[name]
def eval_expr(tree, ns):
return MyEval(ns).transform(tree)
@v_args(inline=True)
class MyInterp(Interpreter):
def __init__(self):
self.namespace = {}
def assign(self, var, expr):
self.namespace[var] = eval_expr(expr, self.namespace)
def print_statement(self, expr):
res = eval_expr(expr, self.namespace)
print(res)
# print(tree.pretty())
MyInterp().visit(tree)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment