¿Cómo puedo inferir el uso de paréntesis al traducir un árbol de expresiones?

Estoy trabajando en la traducción de un árbol de expresiones a un formato que se asemeja a la notación de infijo; No estoy evaluando el árbol ni ejecutando sus operaciones. El árbol contiene operaciones lógicas y relacionales, y me gustaría emitir paréntesis de manera inteligente durante la traducción.

Para ilustrar, considere la siguiente expresión artificial:

a < x & (a < y | a == c) & a != d

Si recorro en orden el árbol de expresiones producido por esta expresión, imprimiré la siguiente expresión, que es incorrecta.

a < x & a < y | a == c & a != d
// equivalent to (a < x & a < y) | (a == c & a != d)

Alternativamente, puedo realizar nuevamente un recorrido en orden pero emitir paréntesis antes y después de procesar una expresión binaria. Esto producirá la siguiente expresión correcta, pero con varios paréntesis redundantes.

(((a < x) & ((a < y) | (a == c))) & (a != d))

¿Existe un algoritmo transversal de árbol de expresiones que produzca expresiones de paréntesis óptimas?

Para referencia, aquí hay un fragmento de laExpressionVisitor Estoy usando para inspeccionar el árbol.

class MyVisitor : ExpressionVisitor
{
    protected override Expression VisitBinary(BinaryExpression node)
    {
        Console.Write("(");

        Visit(node.Left);
        Console.WriteLine(node.NodeType.ToString());
        Visit(node.Right);

        Console.Write(")");

        return node;
    }

    // VisitConstant, VisitMember, and VisitParameter omitted for brevity.
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta