| 6 | from lang.util import typename |
| 7 | |
| 8 | class ASTNode(object): |
| 9 | def __init__(self, node_type, label=None, value=None, children=None): |
| 10 | self.type = node_type |
| 11 | self.label = label |
| 12 | self.value = value |
| 13 | |
| 14 | if type(self) is not Rule: |
| 15 | self.parent = None |
| 16 | |
| 17 | self.children = list() |
| 18 | |
| 19 | if children: |
| 20 | if isinstance(children, Iterable): |
| 21 | for child in children: |
| 22 | self.add_child(child) |
| 23 | elif isinstance(children, ASTNode): |
| 24 | self.add_child(children) |
| 25 | else: |
| 26 | raise AttributeError('Wrong type for child nodes') |
| 27 | |
| 28 | assert not (bool(children) and bool(value)), 'terminal node with a value cannot have children' |
| 29 | |
| 30 | @property |
| 31 | def is_leaf(self): |
| 32 | return len(self.children) == 0 |
| 33 | |
| 34 | @property |
| 35 | def is_preterminal(self): |
| 36 | return len(self.children) == 1 and self.children[0].is_leaf |
| 37 | |
| 38 | @property |
| 39 | def size(self): |
| 40 | if self.is_leaf: |
| 41 | return 1 |
| 42 | |
| 43 | node_num = 1 |
| 44 | for child in self.children: |
| 45 | node_num += child.size |
| 46 | |
| 47 | return node_num |
| 48 | |
| 49 | @property |
| 50 | def nodes(self): |
| 51 | """a generator that returns all the nodes""" |
| 52 | |
| 53 | yield self |
| 54 | for child in self.children: |
| 55 | for child_n in child.nodes: |
| 56 | yield child_n |
| 57 | |
| 58 | @property |
| 59 | def as_type_node(self): |
| 60 | """return an ASTNode with type information only""" |
| 61 | return ASTNode(self.type) |
| 62 | |
| 63 | def __repr__(self): |
| 64 | repr_str = '' |
| 65 | # if not self.is_leaf: |
no outgoing calls
no test coverage detected