'Return the grammar productions, filtered by the left-hand side
or the first item in the right-hand side.
:param lhs: Only return productions with the given left-hand side.
:param rhs: Only return productions with the given first item
in the right-hand side.
:param empty: Only return productions with an empty right-hand side.
:rtype: list(Production)'

def productions(self, lhs=None, rhs=None, empty=False):

    if (rhs and empty):
        raise ValueError(u'You    cannot    select    empty    and    non-empty    productions    at    the    same    time.')
    if ((not lhs) and (not rhs)):
        if empty:
            return self._empty_productions
        else:
            return self._productions
    elif (lhs and (not rhs)):
        if empty:
            return self._empty_index.get(self._get_type_if_possible(lhs), [])
        else:
            return self._lhs_index.get(self._get_type_if_possible(lhs), [])
    elif (rhs and (not lhs)):
        return self._rhs_index.get(self._get_type_if_possible(rhs), [])
    else:
        return [prod for prod in self._lhs_index.get(self._get_type_if_possible(lhs), []) if (prod in self._rhs_index.get(self._get_type_if_possible(rhs), []))]
