Created
September 6, 2013 06:50
-
-
Save mtomwing/6460361 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 functools import reduce | |
import sys | |
from grammar import ( | |
Program, | |
Statement, | |
Function, | |
ArgumentList, | |
Argument, | |
Integer, | |
FunctionCall, | |
) | |
def add_func(*args): | |
return reduce(lambda a, x: a + x, args) | |
def mul_func(*args): | |
return reduce(lambda a, x: a * x, args) | |
def print_func(*args): | |
return ' '.join([str(_) for _ in args]) | |
functions = { | |
'ADD': (float('inf'), add_func), | |
'MUL': (float('inf'), mul_func), | |
'PRINT': (float('inf'), print_func), | |
} | |
def resolve_function_call(node): | |
name = node.find(Function).string | |
nargs, func = functions[name] | |
arg_nodes = node.find(ArgumentList)[0].find_all(Argument) | |
resolved_args = [] | |
for arg in arg_nodes: | |
arg = arg.elements[0] | |
if isinstance(arg, Integer): | |
resolved_args.append(int(arg.string)) | |
elif isinstance(arg, FunctionCall): | |
resolved_args.append(resolve_function_call(arg)) | |
else: | |
print('lolwtf') | |
return func(*resolved_args) | |
if __name__ == '__main__': | |
source = open(sys.argv[1]).read() | |
parser = Program.parser() | |
result = parser.parse_string(source) | |
# Execute the program | |
for statement in result.find_all(Statement): | |
print('>>', statement.string) | |
resolve_me = statement.find(FunctionCall) | |
try: | |
print(' RESULT:', resolve_function_call(resolve_me)) | |
except: | |
print(' ERROR: statement is not valid') | |
raise |
This file contains hidden or 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 modgrammar as mg | |
mg.grammar_whitespace_mode = 'optional' | |
class Integer(mg.Grammar): | |
grammar = mg.WORD('0-9') | |
class Argument(mg.Grammar): | |
grammar = (Integer | mg.REF('FunctionCall')) | |
class ArgumentList(mg.Grammar): | |
grammar = mg.OPTIONAL(mg.LIST_OF(Argument, sep=',')) | |
class Function(mg.Grammar): | |
grammar = mg.WORD('A-Za-z_') | |
class FunctionCall(mg.Grammar): | |
grammar = (Function, '(', ArgumentList, ')') | |
class Statement(mg.Grammar): | |
grammar = (FunctionCall, ';') | |
class Ignore(mg.Grammar): | |
grammar = (mg.BOL, mg.EOL) | |
class Program(mg.Grammar): | |
grammar = (mg.ZERO_OR_MORE(Statement | Ignore), mg.EOF) |
This file contains hidden or 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
>> ADD(MUL(2, 2), 3); | |
RESULT: 7 | |
>> PRINT(1, 2, 3, ADD(1, 1, 2), MUL(5, 1)); | |
RESULT: 1 2 3 4 5 |
This file contains hidden or 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
ADD(MUL(2, 2), 3); | |
PRINT(1, 2, 3, ADD(1, 1, 2), MUL(5, 1)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment