-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
344 additions
and
11 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
General | ||
Read from file! | ||
> Rho for vars & funs | ||
several statements | ||
> args really just in dictio in function body? | ||
parser doing proper separation? -> nope | ||
|
||
b | ||
> basic (BasicValue) | ||
> check if int | ||
|
||
x | ||
> var (Variable) | ||
> one word, further specifications? -> check in constructor | ||
global, local? | ||
|
||
(op1 e) | ||
> uadd, usub, brkt (Other) | ||
> brackets don't need own nodes | ||
|
||
( e1 op2 e2 ) | ||
> add, sub, mul, div | ||
> gt, ge, lt, le, eq | ||
|
||
( if e0 then e1 else e2 ) | ||
> if | ||
> conditions | ||
|
||
( e' e0 ... ek−1 ) | ||
> app | ||
> fun has to be known | ||
> split e0 to ek-1 correctly? | ||
convert "39 + 3" to "39+3" | ||
|
||
( fun x0 ... xk−1 -> e ) | ||
> fun | ||
> differ between args and vars | ||
|
||
( let x1 = e1 in e0 ) | ||
> let, asgn | ||
> differ between var and fun? | ||
|
||
( let rec x1 = e1 and ... and xn = en in e0 ) | ||
> rec, asgn |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,227 @@ | ||
from tree_nodes import * | ||
from parse import * | ||
import numpy as np | ||
import re | ||
|
||
Node("abcd") | ||
x = Other ("abcd", "sdfsdf") | ||
x = Other("plus", [BasicValue("basic", 3), BasicValue("basic", 6)]) | ||
def mk_rec(x, depth, dictio): | ||
defs = x['defs'].split('and') | ||
|
||
new_dict = dictio.copy() | ||
|
||
children = [] | ||
for defi in defs: | ||
y = parse("{x1} = fun {e1}", defi) | ||
if(y == None): | ||
raise Exception('"{}" is not a valid assignment in let rec.'.format(defi)) | ||
|
||
new_dict[y['x1']] = "fvar" | ||
|
||
for defi in defs: | ||
y = parse("{x1} = {e1}", defi) | ||
|
||
x1 = Variable("fvar", y['x1'], depth+2) | ||
e1 = parse_tree(y['e1'], depth+2, new_dict) | ||
|
||
children.append(Other("asgn", [x1, e1], depth+1)) | ||
|
||
e0 = parse_tree(x['e0'], depth+1, new_dict) | ||
children.append(e0) | ||
|
||
return Other("rec", children, depth) | ||
|
||
def mk_let(x, depth, dictio): | ||
tag = "fvar" if x['e1'].split(' ', 1)[0] == "fun" else "var" | ||
|
||
new_dict = dictio.copy() | ||
|
||
x1 = Variable(tag, x['x1'], depth+2) | ||
new_dict[x['x1']] = tag | ||
|
||
e1 = parse_tree(x['e1'], depth+2, new_dict) | ||
|
||
asgn = Other("asgn", [x1, e1], depth+1) | ||
e0 = parse_tree(x['e0'], depth+1, new_dict) | ||
|
||
return Other("let", [asgn, e0], depth) | ||
|
||
def mk_fun(x, depth, dictio): | ||
args = x['args'].split() | ||
|
||
new_dict = dictio.copy() | ||
|
||
children = [] | ||
for arg in args: | ||
children.append(Variable("arg", arg, depth+1)) | ||
new_dict[arg] = "arg" | ||
|
||
e = parse_tree(x['e'], depth+1, new_dict) | ||
children.append(e) | ||
|
||
return Other("fun", children, depth) | ||
|
||
def split_expr(exprs): | ||
x = parse("({e1}) {e2}", exprs) | ||
if(x != None): | ||
tmp = [x['e1']] | ||
tmp.extend(split_expr(x['e2'])) | ||
return tmp | ||
|
||
x = parse("({e})", exprs) | ||
if(x != None): | ||
return [x['e']] | ||
|
||
x = exprs.split(' ', 1) | ||
|
||
if len(x) == 1: | ||
return [x[0]] | ||
|
||
else: | ||
tmp = [x[0]] | ||
tmp.extend(split_expr(x[1])) | ||
return tmp | ||
|
||
def mk_app(x, depth, dictio): | ||
children = [Variable("fvar", x[0], depth+1)] | ||
|
||
for expr in split_expr(x[1]): | ||
children.append(parse_tree(expr, depth+1, dictio)) | ||
|
||
return Other("app", children, depth) | ||
|
||
def mk_if(x, depth, dictio): | ||
e0 = parse_tree(x['e0'], depth+1, dictio) | ||
e1 = parse_tree(x['e1'], depth+1, dictio) | ||
e2 = parse_tree(x['e2'], depth+1, dictio) | ||
|
||
return Other("if", [e0, e1, e2], depth) | ||
|
||
def mk_op2(x, depth, dictio, tag): | ||
e1 = parse_tree(x['e1'], depth+1, dictio) | ||
e2 = parse_tree(x['e2'], depth+1, dictio) | ||
return Other(tag, [e1, e2], depth) | ||
|
||
def mk_op1(x, depth, dictio, tag): | ||
e = parse_tree(x['e'], depth+1, dictio) | ||
return Other(tag, [e], depth) | ||
|
||
def is_known(expr, dictio, tag=""): | ||
if tag == "": | ||
return expr in dictio | ||
|
||
try: | ||
return dictio[expr] == tag | ||
except KeyError: | ||
return False | ||
|
||
def is_int(expr): | ||
try: | ||
int(expr) | ||
return True | ||
except ValueError: | ||
return False | ||
|
||
def parse_tree(expr, depth=0, dictio={}): | ||
|
||
# remove unnecessary whitespace | ||
expr = re.sub(' +', ' ',expr).strip() | ||
|
||
# (e) | ||
x = parse("({e})", expr) | ||
if(x != None): | ||
return parse_tree(x['e'], depth, dictio) | ||
|
||
# let rec x1 = e1 and ... and xn = en in e0 | ||
x = parse("let rec {defs} in {e0}", expr) | ||
if(x != None): | ||
return mk_rec(x, depth, dictio) | ||
|
||
# let x1 = e1 in e0 | ||
x = parse("let {x1} = {e1} in {e0}", expr) | ||
if(x != None): | ||
return mk_let(x, depth, dictio) | ||
|
||
# fun x0 ... xk-1 -> e | ||
x = parse("fun {args} -> {e}", expr) | ||
if(x != None): | ||
return mk_fun(x, depth, dictio) | ||
|
||
# e' e0 ... ek−1 | ||
x = expr.split(' ', 1) | ||
if(is_known(x[0], dictio, "fvar")): | ||
return mk_app(x, depth, dictio) | ||
|
||
# if e0 then e1 else e2 | ||
x = parse("if {e0} then {e1} else {e2}", expr) | ||
if(x != None): | ||
return mk_if(x, depth, dictio) | ||
|
||
# e1 >= e2 | ||
x = parse("{e1}>={e2}", expr) | ||
if(x != None): | ||
return mk_op2(x, depth, dictio, "ge") | ||
|
||
# e1 > e2 | ||
x = parse("{e1}>{e2}", expr) | ||
if(x != None): | ||
return mk_op2(x, depth, dictio, "gt") | ||
|
||
# e1 <= e2 | ||
x = parse("{e1}<={e2}", expr) | ||
if(x != None): | ||
return mk_op2(x, depth, dictio, "le") | ||
|
||
# e1 < e2 | ||
x = parse("{e1}<{e2}", expr) | ||
if(x != None): | ||
return mk_op2(x, depth, dictio, "lt") | ||
|
||
# e1 == e2 | ||
x = parse("{e1}=={e2}", expr) | ||
if(x != None): | ||
return mk_op2(x, depth, dictio, "eq") | ||
|
||
# e1 * e2 | ||
x = parse("{e1}*{e2}", expr) | ||
if(x != None): | ||
return mk_op2(x, depth, dictio, "mul") | ||
|
||
# e1 / e2 | ||
x = parse("{e1}/{e2}", expr) | ||
if(x != None): | ||
return mk_op2(x, depth, dictio, "div") | ||
|
||
# e1 + e2 | ||
x = parse("{e1}+{e2}", expr) | ||
if(x != None): | ||
return mk_op2(x, depth, dictio, "add") | ||
|
||
# e1 - e2 | ||
x = parse("{e1}-{e2}", expr) | ||
if(x != None): | ||
return mk_op2(x, depth, dictio, "sub") | ||
|
||
# +e | ||
x = parse("+{e}", expr) | ||
if(x != None): | ||
return mk_op1(x, depth, dictio, "uadd") | ||
|
||
# -e | ||
x = parse("-{e}", expr) | ||
if(x != None): | ||
return mk_op1(x, depth, dictio, "usub") | ||
|
||
# variable | ||
if(is_known(expr, dictio, "var")): | ||
return Variable("var", expr, depth) | ||
|
||
# argument | ||
if(is_known(expr, dictio, "arg")): | ||
return Variable("arg", expr, depth) | ||
|
||
# basic value | ||
if(is_int(expr)): | ||
return BasicValue("basic", int(expr), depth) | ||
|
||
# default case | ||
raise Exception('"{}" is not a valid expression.'.format(expr)) | ||
# return Variable("dummy", expr, depth) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,56 @@ | ||
class Node(object): | ||
|
||
def __init__(self, tag): | ||
def __init__(self, tag, depth=0): | ||
self.tag = tag | ||
self.depth = depth | ||
|
||
def __str__(self): | ||
return " " * self.depth + self.tag | ||
|
||
class BasicValue(Node): | ||
|
||
def __init__(self, tag, value): | ||
def __init__(self, tag, value, depth=0): | ||
self.value = value | ||
super(BasicValue, self).__init__(tag) | ||
super(BasicValue, self).__init__(tag, depth) | ||
|
||
def __str__(self): | ||
super_str = super(BasicValue, self).__str__() | ||
return super_str + ": " + str(self.value) | ||
|
||
def check_var(var): | ||
for char in var: | ||
if ord(char) < 48 or ord(char) > 57 and ord(char) < 65 or ord(char) > 91 and ord(char) < 97 or ord(char) > 122: | ||
if not char == '_': | ||
raise Exception('"{}" is not a valid variable name.'.format(var)) | ||
|
||
try: | ||
int(var[0]) | ||
raise Exception('"{}" is not a valid variable name.'.format(var)) | ||
except ValueError: | ||
pass | ||
|
||
if var[0] == '_' or var[-1] == '_': | ||
raise Exception('"{}" is not a valid variable name.'.format(var)) | ||
|
||
class Variable(Node): | ||
|
||
def __init__(self, tag, var): | ||
def __init__(self, tag, var, depth=0): | ||
if(tag != "dummy"): | ||
check_var(var) | ||
|
||
self.var = var | ||
super(Variable, self).__init__(tag) | ||
super(Variable, self).__init__(tag, depth) | ||
|
||
def __str__(self): | ||
super_str = super(Variable, self).__str__() | ||
return super_str + ": " + self.var | ||
|
||
class Other(Node): | ||
|
||
def __init__(self, tag, children): | ||
def __init__(self, tag, children, depth=0): | ||
self.children = children | ||
super(Other, self).__init__(tag) | ||
super(Other, self).__init__(tag, depth) | ||
|
||
def __str__(self): | ||
super_str = super(Other, self).__str__() | ||
return super_str + ":\n" + '\n'.join(map(str, self.children)) |