2012-06-19 16 views
7

Pracuję nad budowaniem kompilatora iw tym celu generuję drzewo, które reprezentuje program źródłowy, który jest przekazywany. Chcę wyświetlić to drzewo jak moda, więc mogę wyświetlić strukturę programu wszystkim zainteresowanym.Całkiem Drukowanie struktury danych drzewa w Ruby

Teraz mam tylko druk drzewo na jednej linii jak to:

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

Co chciałbym jest coś takiego:

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

ja naprawdę nie pracował z drzewami w Ruby, jak są zwykle reprezentowane?

Każda pomoc zostanie doceniona.

+1

+1 dla ładnego drzewa ascii :) –

+0

Czy po prostu chcesz drzew wygenerowanych w ASCII? – Sean

+2

Wydrukuj drzewo * z boku *, najpierw węzeł główny, z wcięciem potomnym. Zobacz wyrażeń S LISP dla kanonicznych sposobów przedstawiania/drukowania drzew. Zrobione dokładnie to zajmie ci 1-2 godziny. –

Odpowiedz

3

Ten rodzaj ładnego drukowania wymaga sporo matematyki. Poza tym nie jest jasne, co powinno się stać, jeśli drzewo będzie zbyt szerokie dla okna konsoli. Nie znam żadnych istniejących bibliotek, które to zrobią. Osobiście używam awesome_print.

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

require 'awesome_print' 

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

Ma mnóstwo opcji, sprawdź to!

+0

[Jak działa 'git'?] (Http://www.kernel.org/pub/software /scm/git/docs/git-log.html) –

+0

Dziękuję, nigdy o tym nie słyszałem, ale wygląda naprawdę obiecująco. –

+0

Jakieś pomysły, w jaki sposób mogę przekazać te dane między klasami? Każdy z węzłów w powyższym drzewie reprezentuje klasę w moim kompilatorze, czy powinienem zwrócić tablicę z każdego z tych węzłów i jakoś ją zebrać w mieszanie? –

2

Musisz sprawdzić klejnot Graph. To jest niesamowite i niezwykle proste w obsłudze. Możesz wybrać kierunek drzewa i kształt węzłów, a także kolory i wiele więcej. Po raz pierwszy dowiedziałem się o tym w Rubyconf w zeszłym roku i byłem zdmuchnięty.

Jest to tak proste, jak:

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

Oczywiście chciałbyś programowo wprowadzić krawędzie :)

Oto link to a pdf z rozmów, które dadzą więcej informacji na jej temat:

Jest także wideo z przemówienia na Confreaks, jeśli jesteś zainteresowany.

Cheers, Sean

+0

Dziękuję, na pewno się tym zajrzę –