-
Notifications
You must be signed in to change notification settings - Fork 0
/
exp.py
99 lines (83 loc) · 3.36 KB
/
exp.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import parser
import lex
class exp(parser.node):
def parse0(self):
return self.parseadd(logic)
class logic(parser.node):
def parse0(self):
return self.nlist(order, [lex.land, lex.lor, lex.lergo],
parser.ASSOC_LEFT, 1)
class order(parser.node):
def parse0(self):
return self.nlist(add, [lex.lt, lex.gt, lex.le,
lex.ge, lex.eq, lex.ne], parser.ASSOC_LEFT, 1)
class add(parser.node):
def parse0(self):
return self.nlist(mul, [lex.plus, lex.minus], parser.ASSOC_LEFT, 1)
class mul(parser.node):
def parse0(self):
return self.nlist(unary, [lex.asterisk,
lex.divide, lex.mod], parser.ASSOC_LEFT, 1)
class unary(parser.node):
def parse0(self):
self.push()
if self.oneof([lex.plus, lex.minus, lex.lnot]):
self.pop()
else:
self.rollback()
return self.parseadd(atom)
class atom(parser.node):
def parse0(self):
self.push()
n = self.oneofdict({lex.number : True, lex.identifier : True,
lex.stringliteral : True,
lex.left_bracket : +3, lex.left_paren : +2})
if n == +3:
self.rollback()
return self.parseadd(block.block)
if n == +2:
self.pop()
return self.parseadd(exp) and self.oneof([lex.right_paren])
else:
self.pop()
return n
def simplify_depth(node):
if len(node.children) == 1 and \
any([isinstance(node, ntype) for ntype in [exp, logic, order, add, mul,
unary, atom, stmt.stmt,
stmt.stmts, block.decls]]):
return [node.children[0]]
elif any([parser.istoken(node, t) for t in ["[", "]", "(", ")", ";", "|",
":", ":="]]):
return []
else:
return [node]
import trex
import reader
identities = [trex.trex(parser.pushstream(
lex.lex(reader.stringreader(s)))) for s in
['"0" ; "+" ; x:. ;^>add>', # 0 + x == x
'x:. ; "+" ; "0" ;^>add>', # x + 0 == x
'x:. ; "-" ; "0" ;^>add>', # x - 0 == x
'x:"OMEGA" ; "+" ; . ;^>add>', # OMEGA + x == OMEGA
'x:"OMEGA" ; "-" ; . ;^>add>', # OMEGA - x == OMEGA
'. ; "+" ; x:"OMEGA" ;^>add>', # x + OMEGA == OMEGA
'"1" ; "*" ; x:. ;^>mul>', # 1 * x == x
'x:. ; "*" ; "1" ;^>mul>', # x * 1 == x
'x:. ; "/" ; "1" ;^>mul>', # x / 1 == x
'x:"0" ; "*" ; . ;^>mul>', # 0 * x == 0
'x:"0" ; "/" ; . ;^>mul>', # 0 / x == 0
'. ; "*" ; x:"0" ;^>mul>']] # x * 0 == 0
assert all(i.parse() and i.atend() for i in identities)
def simplify_arith(node):
if not (type(node) in {add, mul}) or len(node.children) < 3:
return False
for i in identities:
ctx = trex.context([node], 0, {})
if i.match(ctx):
assert "x" in ctx.out
node.children = [ctx.out["x"]]
return True
return False
import stmt
import block