diff --git a/code/code_gen/calc.py b/code/code_gen/calc.py new file mode 100644 index 0000000..f893bc0 --- /dev/null +++ b/code/code_gen/calc.py @@ -0,0 +1,125 @@ +# +# This example shows how to write a basic calculator with variables. +# + +from lark import Lark, Transformer, v_args + + +try: + input = raw_input # For Python2 compatibility +except NameError: + pass + +''' + ?function: "log" -> log + | "exp" -> exp + | "dx" -> dx + | "d2x" -> d2x + + ''' + + +calc_grammar = """ + ?varlist: "[" [NAME ("," NAME)*] "]" + + ?start: NAME "=" sum -> assign_var + | varlist + + ?sum: product + | sum "+" product -> add + | sum "-" product -> sub + + ?product: atom + | product "*" atom -> mul + | product "/" atom -> div + + ?atom: NUMBER -> number + | "-" atom -> neg + | NAME -> var + | "(" sum ")" + | function "(" sum ")" -> fcall + + ?function: "log" -> log + | "exp" -> exp + | "dx" -> dx + | "d2x" -> d2x + | "sqrt" -> sqrt + + %import common.CNAME -> NAME + %import common.NUMBER + %import common.WS + + %ignore WS +""" + + +@v_args(inline=True) # Affects the signatures of the methods +class CalculateTree(Transformer): + from operator import add, sub, mul, truediv as div, neg + number = float + + def __init__(self): + self.primary = [] + self.derived = {} + + def varlist(self, *args): + for arg in args: + self.primary.append(arg.value) + return self.primary + + def assign_var(self, name, value): + self.derived[name] = value + return "{} = {}".format(name, value) + + def var(self, name): + return name + + def fcall (self, a, b): + return "( {} ( {} ) )".format(a, b) + + def neg(self, value): + return "( - {} )".format(value) + + def add(self, a, b): + return "( {} + {} )".format(a, b) + + def sub(self, a, b): + return "( {} - {} )".format(a, b) + + def mul(self, a, b): + return "( {} * {} )".format(a, b) + + def div(self, a, b): + return "( {} / {} )".format(a, b) + + log = lambda self : "log" + exp = lambda self : "exp" + dx = lambda self : "dx" + d2x = lambda self : "d2x" + sqrt = lambda self : "sqrt" + +tf=CalculateTree() + +calc_parser = Lark(calc_grammar, parser='lalr' , transformer=tf) +calc = calc_parser.parse + + +def main(): + while True: + try: + s = input('> ') + except EOFError: + break + print(calc(s)) + + +def test(): + with open("terms.input") as inputfile: + for line in inputfile: + if len(line.strip()) > 0: + print(calc(line)) + + +if __name__ == '__main__': + test() + # main() diff --git a/code/code_gen/code_gen.py b/code/code_gen/code_gen.py new file mode 100644 index 0000000..f893bc0 --- /dev/null +++ b/code/code_gen/code_gen.py @@ -0,0 +1,125 @@ +# +# This example shows how to write a basic calculator with variables. +# + +from lark import Lark, Transformer, v_args + + +try: + input = raw_input # For Python2 compatibility +except NameError: + pass + +''' + ?function: "log" -> log + | "exp" -> exp + | "dx" -> dx + | "d2x" -> d2x + + ''' + + +calc_grammar = """ + ?varlist: "[" [NAME ("," NAME)*] "]" + + ?start: NAME "=" sum -> assign_var + | varlist + + ?sum: product + | sum "+" product -> add + | sum "-" product -> sub + + ?product: atom + | product "*" atom -> mul + | product "/" atom -> div + + ?atom: NUMBER -> number + | "-" atom -> neg + | NAME -> var + | "(" sum ")" + | function "(" sum ")" -> fcall + + ?function: "log" -> log + | "exp" -> exp + | "dx" -> dx + | "d2x" -> d2x + | "sqrt" -> sqrt + + %import common.CNAME -> NAME + %import common.NUMBER + %import common.WS + + %ignore WS +""" + + +@v_args(inline=True) # Affects the signatures of the methods +class CalculateTree(Transformer): + from operator import add, sub, mul, truediv as div, neg + number = float + + def __init__(self): + self.primary = [] + self.derived = {} + + def varlist(self, *args): + for arg in args: + self.primary.append(arg.value) + return self.primary + + def assign_var(self, name, value): + self.derived[name] = value + return "{} = {}".format(name, value) + + def var(self, name): + return name + + def fcall (self, a, b): + return "( {} ( {} ) )".format(a, b) + + def neg(self, value): + return "( - {} )".format(value) + + def add(self, a, b): + return "( {} + {} )".format(a, b) + + def sub(self, a, b): + return "( {} - {} )".format(a, b) + + def mul(self, a, b): + return "( {} * {} )".format(a, b) + + def div(self, a, b): + return "( {} / {} )".format(a, b) + + log = lambda self : "log" + exp = lambda self : "exp" + dx = lambda self : "dx" + d2x = lambda self : "d2x" + sqrt = lambda self : "sqrt" + +tf=CalculateTree() + +calc_parser = Lark(calc_grammar, parser='lalr' , transformer=tf) +calc = calc_parser.parse + + +def main(): + while True: + try: + s = input('> ') + except EOFError: + break + print(calc(s)) + + +def test(): + with open("terms.input") as inputfile: + for line in inputfile: + if len(line.strip()) > 0: + print(calc(line)) + + +if __name__ == '__main__': + test() + # main() diff --git a/code/code_gen/terms.input b/code/code_gen/terms.input new file mode 100644 index 0000000..560848e --- /dev/null +++ b/code/code_gen/terms.input @@ -0,0 +1,5 @@ +[u, v, w, y] + +c = 1 - y +wrate = 21000 * (1 - c) * exp (- 26.7 / (1 + 3 * c)) +dcdx = dx (y)