def parse(self, parent):
        """
        https://www.w3.org/TR/html5/syntax.html
        See: 8.2.5 Tree construction
        """

        last_child = None

        for event, element in self.stream:

            tag = element.tag

            if event == 'start':

                last_child = element

                if isinstance(parent.behavior, Table):

                    # these are not direct descendants of <table>, add missing parent

                    if tag in ('td', 'th', 'tr'):
                        parent = parent.behavior.tbody or self.make_child(parent, 'tbody', {})

                    elif tag == 'col':
                        parent = parent.behavior.columns or self.make_child(parent, 'colgroup', {})

                elif isinstance(parent.behavior, TableRowGroup):

                    # these are not direct descendants of <tbody>, add missing parent

                    if tag in ('td', 'th'):
                        parent = self.make_child(parent, 'tr', {})

                node = self.make_child(parent, tag, element.attrib)

                if isinstance(node.behavior, Table) and self.table_columns:
                    measurements_data = self.table_columns.pop(0)
                    node.behavior.columns.behavior.measurements = measurements_data['maximums']
                    node.behavior.columns.behavior.span = measurements_data['span']

                if isinstance(node.behavior, Table) and parent.tag == 'body':
                    yield from self.parse(node)

                else:

                    # root tables are a very special case
                    # where the table and row groups
                    # are not yielded but the table rows
                    # themselves are yielded as "root nodes"

                    skip_root_table_meta_groups = (  # don't yield <colgroup>, <thead>, <tbody>, <tfoot>
                        parent.parent and parent.parent.tag == 'body' and
                        isinstance(node.behavior, (TableRowGroup, TableColumnGroup, TableCaption))
                    )

                    yield_root_table_rows = (  # do yield <tr> that's inside <tbody>
                        skip_root_table_meta_groups and
                        node.style.display == 'table-row-group'
                    )

                    position = 0
                    position_of_type = {}

                    for previous, (child_element, child_node), last in iter_previous_current_last(self.parse(node)):
                        if previous is not None:
                            if node.text_allowed and previous[0].tail:
                                # insert text between previous node and current node
                                node.insert(len(node.children)-2, previous[0].tail)
                        position_of_type.setdefault(child_node.tag, 0)
                        child_node.position = position = position + 1
                        child_node.position_of_type = position_of_type[child_node.tag] = position_of_type[child_node.tag] + 1
                        child_node.last = last
                        if yield_root_table_rows and isinstance(child_node.behavior, TableRow):
                            self.css.apply_recursively(child_node)
                            yield child_element, child_node

                    if node.text_allowed and element.text:
                        node.insert(0, element.text)

                    if not skip_root_table_meta_groups:
                        yield element, node

            else:

                if parent.text_allowed and last_child is not None and last_child.tail:
                    parent.add(last_child.tail)

                break