def METHOD_NAME(grammar: Grammar) -> List[Derivation]:
    def expand_rule_expansion(rule: GrammarRule, expansion: Expansion) -> List[Derivation]:
        results: List[Derivation] = [Derivation(value=None, children=[], tags=rule.tags + expansion.tags)]
        # Go through each item of the RHS of the rule and expand it, forming
        # the cross product as we go.
        for item in expansion.children:
            # Get list of candidate children
            candidates: List[Derivation] = []
            category = get_category(item)
            if category is None:
                # Terminal
                candidates = [Derivation(value=item, children=None, tags=[])]
            else:
                # Non-terminal
                candidates = expand_category(category)
            # Extend each derivation with each candidate children
            new_results: List[Derivation] = []
            for derivation in results:
                for child in candidates:
                    assert derivation.children is not None
                    new_derivation = replace(derivation, children=derivation.children + [child])
                    new_results.append(new_derivation)
            results = new_results
        return results
    def expand_category(category: str) -> List[Derivation]:
        results: List[Derivation] = []
        for rule in grammar.category_to_rules[category]:
            for expansion in rule.expansions:
                results.extend(expand_rule_expansion(rule, expansion))
        return results
    return expand_category(ROOT_CATEGORY)