Created
July 3, 2018 10:10
-
-
Save soasme/9cf367101f5fe34494b1a3b388f3edf4 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
from rpython.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function | |
from rpython.rlib.parsing.parsing import ParseError | |
from rpython.rlib.parsing.deterministic import LexerError | |
EBNF = """ | |
IGNORE: " |\n"; | |
NUMBER: "\-?(0|[1-9][0-9]*)(\.[0-9]+)?"; | |
expr : NUMBER >(arith_op NUMBER)+< | <NUMBER>; | |
arith_op: <"+"> | <"-">; | |
main: <expr> [EOF]; | |
""" | |
regexes, rules, _to_ast = parse_ebnf(EBNF) | |
parse_ebnf = make_parse_function(regexes, rules, eof=True) | |
to_ast = _to_ast() | |
def eval(ast): | |
if ast.symbol == 'main': | |
expr = ast.children[0] | |
return eval(expr); | |
elif ast.symbol == 'expr': | |
term = eval(ast.children[0]) | |
for i in range(1, len(ast.children[1:]), 2): | |
op, term_i = ast.children[i], eval(ast.children[i+1]) | |
if op.additional_info == '+': | |
term = term + term_i | |
elif op.additional_info == '-': | |
term = term - term_i | |
return term | |
elif ast.symbol == 'NUMBER': | |
if ast.additional_info.startswith('-'): | |
return -1 * float(ast.additional_info[1:]) | |
else: | |
return float(ast.additional_info) | |
else: | |
print(ast) | |
raise ValueError('unknown ast.') | |
def run(source): | |
tree = parse_ebnf(source) | |
ast = to_ast.transform(tree) | |
print(eval(ast)) | |
if __name__ == '__main__': | |
while True: | |
try: | |
print '>', | |
expr = run(raw_input()) | |
except Exception as e: | |
print(e) |
Author
soasme
commented
Jul 3, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment