def _restore_tree_for(root, translate):
    # type: (Any, Dict[Type[Nonterminal], Type[Rule]]) -> Union[Nonterminal, Terminal]
    """
    Create part of AST that generate epsilon.
    :param root: Symbol in the original rule that results in epsilon.
    Can be Nonterminal or epsilon itself.
    :param translate: Dictionary where key is nonterminal and value is rule which is next to generate epsilon.
    :return: Nonterminal instance with part of AST generating epsilon.
    """
    # the symbol is epsilon directly, just return Terminal.
    if root is EPSILON:
        return Terminal(EPSILON)
    # create nonterminal
    created_nonterm = root()  # type: Nonterminal
    created_rule = translate[root]()  # type: Rule
    created_nonterm._set_to_rule(created_rule)
    created_rule._from_symbols.append(created_nonterm)
    # all symbols from the right are rewritable to epsilon, so we need to restore them as well
    for ch in created_rule.right:
        p = _restore_tree_for(ch, translate)  # type: Nonterminal
        p._set_from_rule(created_rule)
        created_rule._to_symbols.append(p)
    return created_nonterm
def _restore_tree_for ( root , translate ) : if root is EPSILON : return Terminal ( EPSILON ) created_nonterm = root ( ) created_rule = translate [ root ] ( ) created_nonterm . _set_to_rule ( created_rule ) created_rule . _from_symbols . append ( created_nonterm ) for ch in created_rule . right : p = _restore_tree_for ( ch , translate ) p . _set_from_rule ( created_rule ) created_rule . _to_symbols . append ( p ) return created_nonterm
Create part of AST that generate epsilon.
    :param root: Symbol in the original rule that results in epsilon.
    Can be Nonterminal or epsilon itself.
    :param translate: Dictionary where key is nonterminal and value is rule which is next to generate epsilon.
    :return: Nonterminal instance with part of AST generating epsilon.