from block import * def tp(sth): if sth ==None: return -1 if sth[0] >='0' and sth[0] <='9': return 2 if sth[0] != '_': return 0 return 1 class DAGNode: cnt = 1 def __init__(self,tag=None,l=None,r=None,op=None): self.cnt = DAGNode.cnt DAGNode.cnt += 1 self.parents = [] self.lc = l self.rc = r self.op = op self.main_tag = tag self.other_tag = set() if tag is not None: self.other_tag.add(tag) def insert(self,tag): self.other_tag.add(tag) if tp(tag) > tp(self.main_tag): self.main_tag = tag def has(self,tag): return tag in self.other_tag class Optimizer: def __init__(self): self.nodes = [""] self.cnt = 0 self.ans= [] def cfind(self,tag): for i in range(1,self.cnt+1)[::-1]: if self.nodes[i].has(tag): return self.nodes[i] self.cnt += 1 self.nodes.append(DAGNode(tag=tag)) return self.nodes[self.cnt] def cfind_op1(self,op,lc,rc): for i in range(1,self.cnt+1)[::-1]: if self.nodes[i].op==op and ((self.nodes[i].lc == lc and self.nodes[i].rc == rc) or (self.nodes[i].lc == rc and self.nodes[i].rc == lc)): return self.nodes[i] self.cnt +=1 self.nodes.append(DAGNode(op=op,l=lc,r=rc)) return self.nodes[self.cnt] def cfind_op2(self,op,lc,rc): for i in range(1, self.cnt + 1)[::-1]: if self.nodes[i].op == op and self.nodes[i].lc == lc and self.nodes[i].rc == rc: return self.nodes[i] self.cnt += 1 self.nodes.append(DAGNode(op=op, l=lc, r=rc)) return self.nodes[self.cnt] def build(self,lst): self.ans = [] for _ in lst: op,a,b,res = _.a,_.b,_.c,_.d if op =='=': # 将ans插入到a的节点中 self.cfind(a).insert(res) elif op =='+' or op=='*' or op=='&' or op=='^' or op =='|' or op =='&&' or op =='||' or op =='==' or op == '!=': # 首先找一下有没有a b节点 , 没有就自己造一个 aNode = self.cfind(a) bNode = self.cfind(b) # 然后找一下有没有a op b 的节点 , 有的话插进去 # 这里并不能根据a ,b 来查找 , 因为昔人已乘黄鹤去 , 你找到的或许只是曾经的ab self.cfind_op1(op,aNode,bNode).insert(res) elif op =='-' or op=='%' or op=='/': # 这种不换的元素符 self.cfind_op2(op,self.cfind(a),self.cfind(b)).insert(ans) pass # 剩下就是while end , if end , el等 , 不用管 for i in range(1,self.cnt+1)[::-1]: _ = self.nodes[i] op = _.op if op is not None: self.ans.append(FourTuple(op,_.lc.main_tag,_.rc.main_tag,_.main_tag)) for __ in _.other_tag: if __ != _.main_tag: self.ans.append(FourTuple('=',_.main_tag,c='_',d=__)) self.ans = self.ans[::-1] if __name__ == '__main__': divider = BlockDivider(l) optimizer = Optimizer() ls = divider.run() for l in ls: optimizer.build(l) for i in optimizer.ans: print(i) # print()