Created
November 21, 2019 03:13
-
-
Save tekknolagi/48c8e1a236bda0a4ee8474bc50b006df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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