'Find a CFG production whose right hand side matches the
rightmost stack elements; and combine those stack elements
into a single Tree, with the node specified by the
production\'s left-hand side.  If more than one CFG production
matches the stack, then use the production that is listed
earliest in the grammar.  The new Tree replaces the
elements in the stack.
:rtype: Production or None
:return: If a reduction is performed, then return the CFG
production that the reduction is based on; otherwise,
return false.
:type stack: list(string and Tree)
:param stack: A list of strings and Trees, encoding
the structure of the text that has been parsed so far.
:type remaining_text: list(str)
:param remaining_text: The portion of the text that is not yet
covered by ``stack``.'

def _reduce(self, stack, remaining_text, production=None):

    if (production is None):
        productions = self._grammar.productions()
    else:
        productions = [production]
    for production in productions:
        rhslen = len(production.rhs())
        if self._match_rhs(production.rhs(), stack[(- rhslen):]):
            tree = Tree(production.lhs().symbol(), stack[(- rhslen):])
            stack[(- rhslen):] = [tree]
            if self._trace:
                self._trace_reduce(stack, production, remaining_text)
            return production
    return None
