'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.
:return: A list of productions matching the given constraints.
: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 (not empty):
            return self._productions
        else:
            return self._empty_index.values()
    elif (lhs and (not rhs)):
        if (not empty):
            return self._lhs_index.get(lhs, [])
        elif (lhs in self._empty_index):
            return [self._empty_index[lhs]]
        else:
            return []
    elif (rhs and (not lhs)):
        return self._rhs_index.get(rhs, [])
    else:
        return [prod for prod in self._lhs_index.get(lhs, []) if (prod in self._rhs_index.get(rhs, []))]
