from block import * def is_f(s): return '.' in s or 'e' in s.lower() def tp(sth): if sth ==None: return -1 if is_f(sth): return 2 if sth[0] >='0' and sth[0] <='9': return 2 if sth[0] != '_': return 1 return 0 def f(op,a,b): if op =='+': return float(a)+float(b) elif op =='-': return float(a)-float(b) elif op =='*': return float(a)*float(b) elif op =='/': return float(a)/float(b) return 0 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 = ["empty"] self.cnt = 0 self.abset = dict() self._set = dict() self.ans= [] self.cnt_abset = 0 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 cfindeq(self,tag): for i in range(1,self.cnt+1)[::-1]: if self.nodes[i].has(tag): return [1,self.nodes[i]] self.cnt += 1 node = DAGNode() self.nodes.append(node) return [0,node] def build(self,lst): fg = False for _ in lst: if tp(_.d)==1 and self.abset.get(_.d) is None: self.abset[_.d] = True self.cnt_abset += 1 self.ans = [] for _ in lst: op,a,b,res = _.a,_.b,_.c,_.d if op =='=': # 将ans插入到a的节点中 num,node = self.cfindeq(a) if num == 0: node.main_tag = a node.other_tag.add(res) node.other_tag.add(a) else: node.insert(res) if node.op is None: node.op = '=' elif op =='+' or op=='*' or op =='==' or op == '!=': # 首先找一下有没有a b节点 , 没有就自己造一个 aNode = self.cfind(a) bNode = self.cfind(b) if tp(aNode.main_tag) == tp(bNode.main_tag) and tp(aNode.main_tag) == 2: val = (f(op,aNode.main_tag,bNode.main_tag)) if is_f(aNode.main_tag) or is_f(bNode.main_tag): val = str(val) else: val = str(int(val)) self.cnt += 1 Node = DAGNode(val) Node.insert(res) Node.op = '=' self.nodes.append(Node) continue # 然后找一下有没有a op b 的节点 , 有的话插进去 # 这里并不能根据a ,b 来查找 , 因为昔人已乘黄鹤去 , 你找到的或许只是曾经的ab self.cfind_op1(op,aNode,bNode).insert(res) elif op =='-' or op=='%' or op=='/': # 这种不换的元素符 aNode = self.cfind(a) bNode = self.cfind(b) if tp(aNode.main_tag) == tp(bNode.main_tag) and tp(aNode.main_tag) == 2: val = (f(op,aNode.main_tag,bNode.main_tag)) print(aNode.main_tag,bNode.main_tag) if is_f(aNode.main_tag) or is_f(bNode.main_tag): val = str(val) else: val = str(int(val)) self.cnt += 1 Node = DAGNode(val) Node.insert(res) Node.op = '=' self.nodes.append(Node) continue self.cfind_op2(op,self.cfind(a),self.cfind(b)).insert(res) # 剩下就是while end , if end , el等 , 不用管 for i in range(1,self.cnt+1)[::-1]: _ = self.nodes[i] op = _.op if op is not None or len(_.other_tag)>1: if _.lc is not None and _.rc is not None: if tp(_.main_tag) == 1: if self.abset[_.main_tag] == True: self.ans.append(FourTuple(op,_.lc.main_tag,_.rc.main_tag,_.main_tag)) self.abset[_.main_tag] = False self.cnt_abset -=1 if self.cnt_abset == 0: fg = True break else: if self._set.get(_.main_tag) is None: self._set[_.main_tag] = 1 self.ans.append(FourTuple(op, _.lc.main_tag, _.rc.main_tag, _.main_tag)) self.abset[_.main_tag] = False if fg: break for __ in _.other_tag: if __ != _.main_tag: if tp(__) == 1: if self.abset[__] == True: self.ans.append(FourTuple('=', _.main_tag, '_', __)) self.abset[__] = False self.cnt_abset -= 1 if self.cnt_abset == 0: fg = True break else: if self._set.get(__) == None: self._set[__] = 1 self.ans.append(FourTuple('=',_.main_tag,c='_',d=__)) if fg: break 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)