From 71844b0befd28724e113a6f1be2a4f7f1912cf4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandra=20Gra=C3=9F?= Date: Sun, 28 Jul 2019 10:16:32 +0200 Subject: [PATCH] input from file and minor bug fixing --- TODO | 8 ++-- input/slide_102.ml | 5 +++ input/slide_114.ml | 5 +++ input/slide_131.ml | 3 ++ input/slide_140.ml | 4 ++ input/slide_159.ml | 5 +++ input/test_1.ml | 7 ++++ main.py | 95 +++++++++++----------------------------------- parser.py | 40 +++++++++++++------ test.py | 45 ++++++++++++++++++++++ 10 files changed, 130 insertions(+), 87 deletions(-) create mode 100644 input/slide_102.ml create mode 100644 input/slide_114.ml create mode 100644 input/slide_131.ml create mode 100644 input/slide_140.ml create mode 100644 input/slide_159.ml create mode 100644 input/test_1.ml create mode 100644 test.py diff --git a/TODO b/TODO index dd1ce32..23f39a4 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,10 @@ General - Read from file! + > Read from file! > Rho for vars & funs several statements > args really just in dictio in function body? - parser doing proper separation? -> nope - change imports in main + > parser doing proper separation? -> nope + > change imports in main b > basic (BasicValue) @@ -30,7 +30,7 @@ x ( e' e0 ... ek−1 ) > app > fun has to be known - > split e0 to ek-1 correctly? + split e0 to ek-1 correctly? convert "39 + 3" to "39+3" ( fun x0 ... xk−1 -> e ) diff --git a/input/slide_102.ml b/input/slide_102.ml new file mode 100644 index 0000000..674cf40 --- /dev/null +++ b/input/slide_102.ml @@ -0,0 +1,5 @@ +let rec fac = fun x -> + if x <= 1 + then 1 + else x * fac (x-1) in + fac 7 \ No newline at end of file diff --git a/input/slide_114.ml b/input/slide_114.ml new file mode 100644 index 0000000..e90299d --- /dev/null +++ b/input/slide_114.ml @@ -0,0 +1,5 @@ +let c = 5 in + let f = fun a -> + let b = a * a in + b + c in + f c \ No newline at end of file diff --git a/input/slide_131.ml b/input/slide_131.ml new file mode 100644 index 0000000..4f4b978 --- /dev/null +++ b/input/slide_131.ml @@ -0,0 +1,3 @@ +let a = 19 in + let b = a * a in + a + b \ No newline at end of file diff --git a/input/slide_140.ml b/input/slide_140.ml new file mode 100644 index 0000000..16d86e3 --- /dev/null +++ b/input/slide_140.ml @@ -0,0 +1,4 @@ +let a = 17 in + let f = fun b -> + a + b in + f 42 \ No newline at end of file diff --git a/input/slide_159.ml b/input/slide_159.ml new file mode 100644 index 0000000..a500ca1 --- /dev/null +++ b/input/slide_159.ml @@ -0,0 +1,5 @@ +let rec f = fun x y -> + if y <= 1 + then x + else f ( x * y ) ( y - 1 ) in + f 1 \ No newline at end of file diff --git a/input/test_1.ml b/input/test_1.ml new file mode 100644 index 0000000..1b76e98 --- /dev/null +++ b/input/test_1.ml @@ -0,0 +1,7 @@ +let rec x = fun a -> 1 + and y = fun b -> + let rec z0 = fun c -> c + and z1 = fun d -> d in + z1 1 + and z = fun a -> a in + ((x 2) + (y 2)) \ No newline at end of file diff --git a/main.py b/main.py index def0dbb..75c7dcb 100644 --- a/main.py +++ b/main.py @@ -1,80 +1,31 @@ -from parser import * -from code_generator import * +from parser import parse_tree +from code_generator import * # TODO just import necessary method -if __name__ == '__main__': +from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter - from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter - - # default values - input_file = "input.txt" - output_file = "output.txt" +# default values +input_file = "input/test1.ml" +output_file = "output/test1.txt" - # parse command line arguments - parser = ArgumentParser( - description="translate functional code to MaMa language", - formatter_class=ArgumentDefaultsHelpFormatter - ) - parser.add_argument("-i", "--input", type=str, help="path to a file containing functional language", default=input_file) - parser.add_argument("-o", "--output", type=str, help="path to output file", default=output_file) - args = parser.parse_args() +# parse command line arguments +parser = ArgumentParser( + description="translate functional code to MaMa language", + formatter_class=ArgumentDefaultsHelpFormatter +) +parser.add_argument("-i", "--input", type=str, help="path to a file containing functional language", default=input_file) +parser.add_argument("-o", "--output", type=str, help="path to output file", default=output_file) +args = parser.parse_args() - # usage: main.py [-h] [-i INPUT] [-o OUTPUT] - #print(args.input) - #print(args.output) +# usage: main.py [-h] [-i INPUT] [-o OUTPUT] - # own examples - ''' - print(parse_tree("let a = 17 in let f = fun b -> a + b in f (39 + 2)")) - print() - print(parse_tree("if 1 then 3 else 4")) - print() - print(parse_tree("let x3 = 4 in + x3 ")) - print() - print(parse_tree("((34))")) - print() - print(parse_tree("3 / 4")) - print() - print(parse_tree("let rec f = fun x y -> if y <= 1 then x else f ( x * y ) ( y - 1 ) in f 1")) - print() - print(parse_tree("let y_x = 4 in y_x")) - print() +with open(args.input) as i_f: - # from lecture slides - print(parse_tree("let rec fac = fun x -> if x <= 1 then 1 else x * fac (x-1) in fac 7")) # 102 - print() + # read input and remove whitespace + expr = i_f.read() + expr = ' '.join(expr.split()) - # TODO: for let f, first "in" is chosen (a in b) - # print(parse_tree("let c = 5 in let f = fun a -> let b = a * a in b + c in f c")) # 114 - # print() - - print(parse_tree("let a = 19 in let b = a * a in a + b")) # 131 - print() + # parse syntax tree + tree = parse_tree(expr) - print(parse_tree("let a = 17 in let f = fun b -> a + b in f 42")) # 140 - print() - - print(parse_tree("let rec f = fun x y -> if y <= 1 then x else f ( x * y ) ( y - 1 ) in f 1")) # 159 - print() - ''' - - ##examples handled by code generation - #result = parse_tree("let a = 19 in let b = a * a in a + b") # 131 - #parse_syntaxTree(result) - #result = parse_tree("if 1 then 3 else 4") - #parse_syntaxTree(result) - #result = parse_tree("let a = 17 in let f = fun b -> a + b in f (39 + 2)") - #parse_syntaxTree(result) - #result = parse_tree("let a = 17 in let f = fun b -> a + b in f 42") # 140 - #parse_syntaxTree(result) - #result = parse_tree("let rec f = fun x y -> if y <= 1 then 5 else f ( x * y ) ( y - 1 ) in f 1") - #parse_syntaxTree(result) - #result = parse_tree("let x3 = 4 in + x3 ") - #parse_syntaxTree(result) - '''Needs Work:''' - #result = parse_tree("let f = fun x y -> let a = 5 in let b = x + 2*y in b + a*x in f 0 1") - #parse_syntaxTree(result) - #result = parse_tree("if y > x then x else 7 + y * x") - #parse_syntaxTree(result) - - # Testing let rec & and parsing - # print(parse_tree("let rec x = fun a -> 1 and y = fun b -> let rec z0 = fun c -> c and z1 = fun d -> d in z1 1 and z = fun a -> a in ((x 2) + (y 2))")) + # TODO generate code and print to file + print(tree) diff --git a/parser.py b/parser.py index 25a18d4..4a90062 100644 --- a/parser.py +++ b/parser.py @@ -1,7 +1,6 @@ from tree_nodes import * from parse import * import numpy as np -import re def parse_brack(expr): if(parse("({e})", expr) is None): @@ -214,6 +213,20 @@ def mk_if(x, depth, dictio): return Other("if", [e0, e1, e2], depth) +def check_brack(expr): + count = 1 + + for char in expr: + if(char == '('): + count += 1 + if(char == ')'): + count -= 1 + + if not count: + return False + + return True + def mk_op2(x, depth, dictio, tag): e1 = parse_tree(x['e1'], depth+1, dictio) e2 = parse_tree(x['e2'], depth+1, dictio) @@ -242,7 +255,7 @@ def is_int(expr): def parse_tree(expr, depth=0, dictio={}): # remove unnecessary whitespace - expr = re.sub(' +', ' ',expr).strip() + expr = ' '.join(expr.split()) # (e) x = parse_brack(expr) @@ -276,47 +289,52 @@ def parse_tree(expr, depth=0, dictio={}): # e1 >= e2 x = parse("{e1}>={e2}", expr) - if(x != None): + if(x != None and check_brack(x['e2'])): return mk_op2(x, depth, dictio, "ge") # e1 > e2 x = parse("{e1}>{e2}", expr) - if(x != None): + if(x != None and check_brack(x['e2'])): return mk_op2(x, depth, dictio, "gt") # e1 <= e2 x = parse("{e1}<={e2}", expr) - if(x != None): + if(x != None and check_brack(x['e2'])): return mk_op2(x, depth, dictio, "le") # e1 < e2 x = parse("{e1}<{e2}", expr) - if(x != None): + if(x != None and check_brack(x['e2'])): return mk_op2(x, depth, dictio, "lt") # e1 == e2 x = parse("{e1}=={e2}", expr) - if(x != None): + if(x != None and check_brack(x['e2'])): return mk_op2(x, depth, dictio, "eq") + # e1 != e2 + x = parse("{e1}!={e2}", expr) + if(x != None and check_brack(x['e2'])): + return mk_op2(x, depth, dictio, "neq") + # e1 + e2 x = parse("{e1}+{e2}", expr) - if(x != None): + if(x != None and check_brack(x['e2'])): return mk_op2(x, depth, dictio, "add") # e1 - e2 x = parse("{e1}-{e2}", expr) - if(x != None): + if(x != None and check_brack(x['e2'])): return mk_op2(x, depth, dictio, "sub") # e1 * e2 x = parse("{e1}*{e2}", expr) - if(x != None): + if(x != None and check_brack(x['e2'])): return mk_op2(x, depth, dictio, "mul") # e1 / e2 x = parse("{e1}/{e2}", expr) - if(x != None): + if(x != None and check_brack(x['e2'])): return mk_op2(x, depth, dictio, "div") # +e diff --git a/test.py b/test.py new file mode 100644 index 0000000..c970f33 --- /dev/null +++ b/test.py @@ -0,0 +1,45 @@ +from parser import parse_tree +from code_generator import parse_syntaxTree + +# own examples +print(parse_tree("let a = 17 in let f = fun b -> a + b in f (39 + 2)")) +print() +print(parse_tree("if 1 then 3 else 4")) +print() +print(parse_tree("let x3 = 4 in + x3 ")) +print() +print(parse_tree("((34))")) +print() +print(parse_tree("3 / 4")) +print() +print(parse_tree("let rec f = fun x y -> if y <= 1 then x else f ( x * y ) ( y - 1 ) in f 1")) +print() +print(parse_tree("let y_x = 4 in y_x")) +print() + +# examples handled by code generation +result = parse_tree("let a = 19 in let b = a * a in a + b") # 131 +parse_syntaxTree(result) +print() +result = parse_tree("if 1 then 3 else 4") +parse_syntaxTree(result) +print() +result = parse_tree("let a = 17 in let f = fun b -> a + b in f (39 + 2)") +parse_syntaxTree(result) +print() +result = parse_tree("let a = 17 in let f = fun b -> a + b in f 42") # 140 +parse_syntaxTree(result) +print() +result = parse_tree("let rec f = fun x y -> if y <= 1 then 5 else f ( x * y ) ( y - 1 ) in f 1") +parse_syntaxTree(result) +print() +result = parse_tree("let x3 = 4 in + x3 ") +parse_syntaxTree(result) + +# needs work +''' +result = parse_tree("let f = fun x y -> let a = 5 in let b = x + 2*y in b + a*x in f 0 1") +parse_syntaxTree(result) +result = parse_tree("if y > x then x else 7 + y * x") +parse_syntaxTree(result) +''' \ No newline at end of file