Wie schließe ich die Verwendung von Klammern beim Übersetzen eines Ausdrucksbaums ab?

8

Ich arbeite daran, einen Ausdrucksbaum in ein Format zu übersetzen, das der Infix-Notation ähnelt; Ich werte den Baum nicht aus oder führe seine Operationen nicht aus. Der Baum enthält sowohl logische als auch relationale Operationen, und ich möchte während der Übersetzung intelligente Klammern ausgeben.

Betrachten Sie zur Veranschaulichung den folgenden konstruierten Ausdruck:

%Vor%

Wenn ich den von diesem Ausdruck erzeugten Ausdrucksbaum in der richtigen Reihenfolge gehe, dann drucke ich den folgenden Ausdruck aus, der falsch ist.

%Vor%

Alternativ kann ich erneut eine Intra-Order-Traversierung durchführen, aber vor und nach der Verarbeitung eines binären Ausdrucks Klammern ausgeben. Dies erzeugt den folgenden korrekten Ausdruck, jedoch mit mehreren überflüssigen Klammern.

%Vor%

Gibt es einen Traversal-Algorithmus für den Ausdrucksbaum, der in optimaler Weise Ausdrücke in Klammern erzeugt?

Hier ist ein Auszug der ExpressionVisitor Ich benutze, um den Baum zu inspizieren.

%Vor%     
Steve Guidi 21.08.2012, 14:49
quelle

2 Antworten

3

Versuchen Sie etwas wie dies, angenommen, dass node.NodeType vom Typ NodeType ist und dass die Funktion Precedes existiert und true zurückgibt, wenn der erste Parameter vor dem zweiten steht.

%Vor%     
Dialecticus 21.08.2012, 15:33
quelle
4

Ich habe die Antwort von Dialecticus akzeptiert, da sie eine gute Grundlage für die Implementierung dieses Algorithmus bietet. Das einzige Problem mit dieser Antwort ist, dass die Methode VisitBinary() über ihren übergeordneten Aufrufer als Methodenargument informiert werden muss, was nicht durchführbar ist, da diese Methoden Überladungen einer Basismethode sind.

Ich biete die folgende Lösung an, die einen ähnlichen Algorithmus verwendet, aber die Prüfung anwendet, um Klammern im übergeordneten Aufruf für die Kindknoten der Ausdrucksbaumstruktur auszugeben.

%Vor%

Die Präzedenzvergleichsfunktion wird als IComparer<ExpressionType> implementiert, wodurch die C # -Regeln der Operatorenpriorität .

%Vor%     
Steve Guidi 24.08.2012 15:17
quelle