def _lay_out_tuples(self, yxs): """ For every @param yxs: list of tuples (row,col) """ def parent_of((row, col)): """ parent((row,col), (row',col')) <=> (row',col') in heads row' < row & col' < col & forall i. row' < i < row & j < col -> (i,j) not in yxs """ row_ = row - 1 while row_ >= min(heads): if row_ in heads: col_ = heads[row_] if col_ < col: return (row_, col_) row_ -= 1 return None by_row = Cabinet().of(ListWithAdd).with_key( lambda x: x[0], Cabinet.SINGULAR).updated(yxs) heads = {row: cols[0][1] for row, cols in by_row.iteritems()} t = Tree(u'§') nodes = {None: t} for _, lin in sorted(by_row.iteritems()): nodes[lin[0]] = s = Tree(lin) nodes[parent_of(lin[0])].subtrees += [s] return t
def p_infix_expr(self, p): """ term : term OP1 term """ if len(p) == 4: p[0] = Tree(p[2], [p[1], p[3]]) else: p[0] = Tree(p[1], [p[2]])
def p_infix_expr(self, p): """ atom : atom binary-operator atom | unary-operator atom (see __init__) """ if len(p) == 4: p[0] = Tree(p[2], [p[1], p[3]]) else: p[0] = Tree(p[1], [p[2]])
def xform(t): r, s = t.root, t.subtrees if r != '': f = [c for c in self.funcs if c.literal == r] if f: new_r = f[0] else: return Tree('') else: new_r = r return Tree(new_r, [x for x in s if x.root != ''])
def forestify(self, p): l = self.l forest, t = [], None for el in p: r = el.root if r[0] == l.TEXT and r[1].strip(): r = re.sub(u"^'(.*)'$", r'\1', r[1].strip()) t = Tree(r) forest += [t] elif r == (l.TOKEN, '}'): assert t is not None t.subtrees = self.forestify(el.subtrees) t = None return forest
def p_name(self, p): """ aterm : IDENTIFIER | NUMBER | ESCAPED_SYMBOL """ p[0] = Tree(p[1])
def p_application(self, p): """ aterm : aterm aterm """ f, a = p[1], p[2] if not f.subtrees: f = f.root p[0] = Tree(f, [a])
def postprocess(self, t): if t.root in ['γ', 'S', 'S1', 'E', 'E0'] and len(t.subtrees) == 1: return self.postprocess(t.subtrees[0]) elif t.root in ['S', 'S1', 'E'] and len( t.subtrees) == 3 and t.subtrees[1].root in [':=', ';', 'op']: return Tree( t.subtrees[1].subtrees[0].root, [self.postprocess(s) for s in [t.subtrees[0], t.subtrees[2]]]) elif len(t.subtrees) == 3 and t.subtrees[0].root == '(': return self.postprocess(t.subtrees[1]) elif t.root == 'S1' and t.subtrees[0].root in ['if', 'while']: return self.postprocess(Tree(t.subtrees[0].root, t.subtrees[1::2])) elif t.root == 'num': return Tree(t.root, [Tree(int(t.subtrees[0].root))]) # parse ints return Tree(t.root, [self.postprocess(s) for s in t.subtrees])
def as_tree(self): ta = TreeAssistant.build t = Tree("") for x, (from_, to_) in self.iterdefs(): d = ta((x, [(self.FUNC_SEP, [(self.PARAM_SEP, list(from_)), to_])])) t.subtrees.append(d) return t
def add_entry(self, datum, whence=None): if whence is None: whence = self.rootset() sub = Tree(datum) whence.end.subtrees.append(sub) n = whence + [sub] self.display_policy.added(self, n) self.indexing_policy.added(self, n) return n
def build_nodes(self, root): '''Recursively create subtree for given parse chart row''' # find subtrees of current symbol if root.completing: down = self.build_nodes(root.completing) elif root.dot > 0: down = [Tree(root.prev_category())] else: down = [] # prepend subtrees of previous symbols prev = root.previous left = [] if prev: left[:0] = [x.subtrees for x in self.build_nodes(prev)] prev = prev.previous else: left = [[]] for x in left: x.extend(down) return [Tree(root.rule.lhs, subtrees) for subtrees in left]
def __init__(self, data=None): """ @param data: data tree """ if data is None: data = Tree( type(self).__name__) # value at root is quite meaningless self.data = data self.pending = [] self.display_policy = self.DisplayPolicy() self.indexing_policy = self.NoIndexingPolicy() self.column_fmt = u"%-30s" self.column_sep = u" " self.width = 0
def __call__(self, token_stream): bal = 0 topen, tclose = self.topen, self.tclose bag = [] for t in token_stream: if t == topen: bal += 1 elif t == tclose: bal -= 1 bag += [t] if bal == 0: yield Tree(t, list(self(bag[1:-1]))) bag = [] if bal != 0: raise SyntaxError, "unbalanced '%s' and '%s'" % (self.topen, self.tclose)
def postprocess(self, t): if t.root in ['γ', 'E', 'E0', 'E1', "E1'"] and len(t.subtrees) == 1: return self.postprocess(t.subtrees[0]) elif t.root == 'E0' and t.subtrees[0].root == '(': return self.postprocess(t.subtrees[1]) elif t.root == r'\.': args = t.subtrees[1].split() t = reduce(lambda t, a: Tree('\\', [a, t]), reversed(args), t.subtrees[3]) elif t.root == "@'": t = Tree('@', t.subtrees) elif t.root == 'L': t = Tree('.', t.split()) return Tree(t.root, [self.postprocess(s) for s in t.subtrees])
def p_tagged_leaf(self, p): """atom : TAG IDENTIFIER | TAG ESCAPED_SYMBOL """ p[0] = Tree(Identifier.promote(p[2], kind=p[1]))
def p_abstraction1(self, p): """ term : QUANTIFIER term COMMA term """ p[0] = Tree(p[1], [p[2], p[4]])
def p_abstraction(self, p): """ term : QUANTIFIER term """ p[0] = Tree(p[1], [p[2]])
def p_node(self, p): """atom : IDENTIFIER LPAREN comma_sep_list RPAREN | ESCAPED_SYMBOL LPAREN comma_sep_list RPAREN """ p[0] = Tree(p[1], p[3])
def p_tagged_func_leaf(self, p): """atom : FUNCTION_TAG IDENTIFIER | FUNCTION_TAG ESCAPED_SYMBOL """ p[0] = Tree(Identifier.promote(p[2], kind='function'))
class ZipperConsTest(unittest.TestCase): tr = Tree(node=1, children=( Tree( node=2, children=(Tree(node=5, children=(Tree(node=8), )), ), ), Tree(node=3, children=(Tree(node=6), )), Tree(node=4, children=(Tree(node=7, children=(Tree(node=9), Tree(node=10), Tree(node=11))), )), )) tr_bfs = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) tr_dfs_pre = (1, 2, 5, 8, 3, 6, 4, 7, 9, 10, 11) tr_dfs_post = (8, 5, 2, 6, 3, 9, 10, 11, 7, 4, 1) cons = Cons(car=1, cdr=Cons(car=2, cdr=Cons(car=3, cdr=Cons(car=4, cdr=None)))) len_cons = 4 cons_slice = Cons(car=4, cdr=Cons(car=2, cdr=None)) cons2 = Cons(car=5, cdr=Cons(car=6, cdr=Cons(car=7, cdr=Cons(car=8, cdr=None)))) def test_zipper_tree(self): zt = ZipperTree.from_tree(self.tr) zt_bfs = tuple(zt.bfs()) zt_dfs_pre = tuple(zt.dfs_pre()) zt_dfs_post = tuple(zt.dfs_post()) self.assertEqual(self.tr_bfs, zt_bfs) self.assertEqual(self.tr_dfs_pre, zt_dfs_pre) self.assertEqual(self.tr_dfs_post, zt_dfs_post) def test_zipper_cons(self): zc1 = ZipperCons.from_cons(cons=self.cons) zc2 = zc1.go_down().go_up() zc3 = zc1.go_down().go_down().go_up().go_up() zc4 = zc1.go_down_most().go_up_most() self.assertEqual(zc1, zc2) self.assertEqual(zc1, zc3) self.assertEqual(zc1, zc4) self.assertEqual(self.len_cons, len(zc1)) self.assertEqual(self.cons_slice, zc1[3:0:-2]) with self.assertRaises(IndexError): try: zc1[4] except Exception as e: raise e with self.assertRaises(IndexError): try: zc1[-5] except Exception as e: raise e zc_other = ZipperCons.from_cons(cons=self.cons2) zc5 = zc1 + self.cons2 zc6 = zc1 + zc_other self.assertEqual(zc5.go_up_most().cons, zc6.go_up_most().cons)
else: t = t.go_up() def paths_iter( self) -> Generator[Optional[Generator[Optional[NewZipperTree]]]]: bottoms = self.bottom_iter() return (tr.path_iter() for tr in bottoms) if __name__ == '__main__': tr1 = Tree(node=1, children=( Tree( node=2, children=(Tree(node=5, children=(Tree(node=8), )), ), ), Tree(node=3, children=(Tree(node=6), )), Tree(node=4, children=(Tree(node=7, children=(Tree(node=9), Tree(node=10), Tree(node=11))), )), )) zt1 = NewZipperTree(tree=tr1) # for i in zt1.bottom_iter(): # print(type(i)) # print(i.tree.node) # for i in zt1.go_bottomleft().path_iter(): # print(type(i)) # print(i.tree.node)
def p_command_while(self, p): """cmdf : WHILE formula LCURLY formula RCURLY cmdf""" p[0] = Tree('while', [p[2], p[4], p[6]])
class TreeTest(unittest.TestCase): tr1 = Tree(node=1, children=( Tree( node=2, children=(Tree(node=5, children=(Tree(node=8), )), ), ), Tree(node=3, children=(Tree(node=6), )), Tree(node=4, children=(Tree(node=7, children=(Tree(node=9), Tree(node=10), Tree(node=11))), )), )) ibt1 = BTree(node=3, left=BTree(node=9), right=BTree(node=20, left=BTree(node=15), right=BTree(node=7))) ibt2 = BTree(node=1, left=BTree(node=2, left=BTree(node=3, left=BTree(node=4))), right=BTree(node=5, left=BTree(node=6), right=BTree(node=7, left=BTree(node=8), right=BTree(9)))) ibt1_depth = 3 ibt2_depth = 4 ibt2_bfs = (1, 2, 5, 3, 6, 7, 4, 8, 9) ibt2_dfs_pre = (1, 2, 3, 4, 5, 6, 7, 8, 9) ibt2_dfs_in = (4, 3, 2, 1, 6, 5, 8, 7, 9) ibt2_dfs_post = (4, 3, 2, 6, 8, 9, 7, 5, 1) tr1_bfs = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) tr1_dfs_pre = (1, 2, 5, 8, 3, 6, 4, 7, 9, 10, 11) tr1_dfs_post = (8, 5, 2, 6, 3, 9, 10, 11, 7, 4, 1) tr1_str = ( 'tree:', '1', '- 2', '- - 5', '- - - 8 (leaf)', '- 3', '- - 6 (leaf)', '- 4', '- - 7', '- - - 9 (leaf)', '- - - 10 (leaf)', '- - - 11 (leaf)', ) ibt2_str = ( 'binary tree:', '1', '- 2', '- - 3', '- - - 4 (leaf)', '- 5', '- - 6 (leaf)', '- - 7', '- - - 8 (leaf)', '- - - 9 (leaf)', ) def test_btree(self): self.assertEqual(self.ibt1_depth, self.ibt1.depth()) self.assertEqual(self.ibt2_depth, self.ibt2.depth()) self.assertEqual(self.ibt2_bfs, self.ibt2.bfs()) self.assertEqual(self.ibt2_dfs_pre, self.ibt2.dfs_pre()) self.assertEqual(self.ibt2_dfs_in, self.ibt2.dfs_in()) self.assertEqual(self.ibt2_dfs_post, self.ibt2.dfs_post()) def test_tree(self): self.assertEqual(self.tr1_bfs, self.tr1.bfs()) self.assertEqual(self.tr1_dfs_pre, self.tr1.dfs_pre()) self.assertEqual(self.tr1_dfs_post, self.tr1.dfs_post()) self.assertEqual(repr(self.tr1), '\n'.join(self.tr1_str)) self.assertEqual(repr(self.ibt2), '\n'.join(self.ibt2_str))
def p_stmt_assign(self, p): """stmt : id OP_ASSIGN id""" p[0] = Tree('x:=y', [p[1], p[3]])
def p_special_form_quantified_expr(self, p): """ atom : QUANTIFIER symbol_list LPAREN atom RPAREN """ p[0] = Tree(p[1], [Tree(x) for x in p[2]] + [p[4]])
def p_command_seq(self, p): """cmd : cmdf OP_SEMI cmd""" p[0] = Tree(p[2], [p[1], p[3]])
def p_leaf(self, p): """atom : NUMBER | IDENTIFIER | ESCAPED_SYMBOL """ p[0] = Tree(p[1])
def p_command_if_then_else(self, p): """cmdf : IF formula THEN cmdf ELSE cmdf""" p[0] = Tree('if', [p[2], p[4], p[6]])
def p_stmt_skip(self, p): """stmt : SKIP""" p[0] = Tree(p[1])
def postprocess(self, t): if t.root in ['γ', 'E', 'E0', 'E1', "E1'", 'A', 'T', 'T1'] and len( t.subtrees) == 1: return self.postprocess(t.subtrees[0]) elif t.root in ['E0', 'T1'] and t.subtrees[0].root == '(': return self.postprocess(t.subtrees[1]) elif t.root == r'\.': args = self.postprocess(t.subtrees[1]).split() t = reduce(lambda t, a: Tree('\\', [a, t]), reversed(args), t.subtrees[3]) elif t.root == "@'": t = Tree('@', t.subtrees) elif t.root in ['L', 'A0']: t = Tree('.', t.split()) elif t.root == 'A1': r = [self.postprocess(s) for s in t.subtrees] if r[0].root == 'id': return Tree('.', r) elif r[0].root == '(': # ( L:T ) A1 return Tree('.', r[1].subtrees + r[3:]) elif t.root == 'L:T': r = [self.postprocess(s) for s in t.subtrees] l, ty = r[0], r[2] return Tree('.', [Tree(r[1].root, [a, ty]) for a in l.split()]) elif t.root in ['id:T', 'T>']: t = Tree(t.subtrees[1].root, [t.subtrees[0], t.subtrees[2]]) return Tree(t.root, [self.postprocess(s) for s in t.subtrees])