Skip to content

Instantly share code, notes, and snippets.

@mtomwing
Created September 6, 2013 06:50
Show Gist options
  • Save mtomwing/6460361 to your computer and use it in GitHub Desktop.
Save mtomwing/6460361 to your computer and use it in GitHub Desktop.
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
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)
>> ADD(MUL(2, 2), 3);
RESULT: 7
>> PRINT(1, 2, 3, ADD(1, 1, 2), MUL(5, 1));
RESULT: 1 2 3 4 5
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