2012-06-19 12 views
7

Ich arbeite an einem Gebäude einen Compiler und innerhalb dieser erzeuge ich einen Baum, der das Quellprogramm darstellt, das übergeben wird. Ich möchte dies anzeigen ist ein Baum wie Mode, damit ich anzeigen kann die Struktur des Programms für alle Interessierten.Ziemlich Drucken einer Baumdatenstruktur in Ruby

Im Moment habe ich nur den Baum Druck auf einer einzigen Zeile wie folgt aus:

ProgramNode -> 'Math' BlockNode -> DeclarationNode -> ConstantDeclarationNode -> const ConstantListNode -> [m := 7, ConstantANode -> [n := StringLiteralNode -> ""TEST"" ]] ; 

Was Ich mag wäre so etwas wie dies:

ProgramNode 
    / \ 
'Math' BlockNode 
      | 
    DeclarationNode 
      | 
    ConstantDeclarationNode ------------------------------ 
     / \           | 
    const ConstantListNode        | 
      /| \  \        | 
      m := 7 ConstantANode     | 
          /| \     | 
          n := StringLiteralNode  | 
            / | \   | 
             " TEST "  ; 

Ich habe nicht wirklich mit Bäumen gearbeitet in Ruby, wie werden sie normalerweise dargestellt?

Jede Hilfe wäre willkommen.

+1

+1 für den hübschen ascii Baum :) –

+0

Wollen Sie nur die in ascii erzeugten Bäume? – Sean

+2

Drucken Sie den Baum * seitwärts *, zuerst den Wurzelknoten, mit Kinder eingerückt. Siehe LISP S-Ausdrücke für die kanonischen Möglichkeiten, Bäume darzustellen/zu drucken. Fertig rechts dauert das 1-2 Stunden. –

Antwort

3

Diese Art von schönen Drucken erfordert ziemlich viel Mathematik. Außerdem ist unklar, was passieren soll, wenn der Baum für das Konsolenfenster zu breit wird. Ich kenne keine vorhandenen Bibliotheken, die das tun. Ich persönlich benutze awesome_print.

tree = {'ConstantDeclarationNode' => ['const', 
             'ConstantListNode' => ['m', ':=', '7']]} 

require 'awesome_print' 

ap tree 
# >> { 
# >>  "ConstantDeclarationNode" => [ 
# >>   [0] "const", 
# >>   [1] { 
# >>    "ConstantListNode" => [ 
# >>     [0] "m", 
# >>     [1] ":=", 
# >>     [2] "7" 
# >>    ] 
# >>   } 
# >>  ] 
# >> } 

Es hat Tonnen von Optionen, überprüfen Sie es!

+0

[Wie macht 'git' es?] (Http://www.kernel.org/pub/software /scm/git/docs/git-log.html) –

+0

Danke, ich habe noch nie davon gehört, aber es sieht wirklich vielversprechend aus. –

+0

Irgendwelche Ideen, wie ich diese Daten zwischen den Klassen weitergeben könnte? Jeder der Knoten im obigen Baum stellt eine Klasse in meinem Compiler dar. Soll ich einfach ein Array von jedem dieser Knoten zurückgeben und irgendwie zu einem Hash zusammenfassen? –

2

Sie müssen die Graph Edelstein überprüfen. Es ist erstaunlich und bemerkenswert einfach zu arbeiten. Sie können die Richtung Ihres Baumes und die Form der Knoten sowie Farben und vieles mehr wählen. Ich habe es letztes Jahr im Rubyconf erfahren und war überwältigt.

Es ist so einfach wie:

digraph do 
    edge "Programnode", "Blocknode" 
    edge "Programnode", "Math" 
    edge "Blocknode", "DeclarationNode" 
end 

Offensichtlich würden Sie programmatisch die Ränder eingeben möchten :)

Hier ist ein link to a pdf des Vortrags, die auf es weitere Informationen geben:

Es gibt auch ein Video von der Rede auf Confreaks, wenn Sie interessiert sind.

Cheers, Sean

+0

Danke, ich werde mich definitiv darum kümmern –

Verwandte Themen