Skip to content

Instantly share code, notes, and snippets.

@tekknolagi
Created November 21, 2019 03:13
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 tekknolagi/48c8e1a236bda0a4ee8474bc50b006df to your computer and use it in GitHub Desktop.
Save tekknolagi/48c8e1a236bda0a4ee8474bc50b006df to your computer and use it in GitHub Desktop.
import inspect
import ast
def terminal(s):
return "<%s>" % s
def define_name(o):
return terminal(o.id) if isinstance(o, ast.Name) else o.s
def define_expr(op):
if isinstance(op, ast.BinOp) and isinstance(op.op, ast.Add):
return (*define_expr(op.left), define_name(op.right))
return (define_name(op),)
def get_alternatives(op, to_expr=lambda o: o.s):
if isinstance(op, ast.BinOp) and isinstance(op.op, ast.BitOr):
return get_alternatives(op.left, to_expr) + [to_expr(op.right)]
return [to_expr(op)]
def funct_parser(tree, to_expr=lambda o: o.s):
return {
assign.targets[0].id: get_alternatives(assign.value, to_expr)
for assign in tree.body[0].body
}
def define_grammar(fn, to_expr=lambda o: o.s):
source = inspect.getsource(fn)
tree = ast.parse(source)
grammar = funct_parser(tree, to_expr)
return grammar
def define_ex_grammar(fn):
return define_grammar(fn, define_expr)
@define_ex_grammar
def expression_grammar():
start = expr
expr = term + "+" + expr | term + "-" + expr
term = factor + "*" + term | factor + "/" + term | factor
factor = (
"+" + factor
| "-" + factor
| "(" + expr + ")"
| integer + "." + integer
| integer
)
integer = digit + integer | digit
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
if __name__ == "__main__":
for symbol in expression_grammar:
print(symbol, "::=\n\t|", '\n\t| '.join(
[' '.join(i) for i in expression_grammar[symbol]]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment