2012-06-19 18 views
7

Sto lavorando a un compilatore di compilazione e al suo interno genera un albero che rappresenta il programma sorgente che viene passato. Voglio mostrare questo è un albero come la moda così posso visualizzare la struttura del programma a chiunque sia interessatoPretty Stampa una struttura dati ad albero in Ruby

In questo momento non mi resta che la stampa albero su una singola linea come questa:

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

Quello che vorrei è qualcosa di simile:

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

non ho davvero lavorato con alberi in Ruby, come vengono solitamente rappresentati?

Qualsiasi aiuto sarebbe apprezzato.

+1

+1 per l'albero ascii pretty :) –

+0

Vuoi solo gli alberi generati in ASCII? – Sean

+2

Stampa l'albero * lateralmente *, il nodo principale per primo, con rientri childen. Vedi LISP S-expressions per i modi canonici di rappresentare/stampare alberi. Fatto bene, ti ci vorranno 1-2 ore. –

risposta

3

Questo tipo di stampa carina richiede un bel po 'di matematica. Inoltre, non è chiaro cosa dovrebbe accadere se l'albero si allarga troppo per la finestra della console. Non conosco alcuna libreria esistente che faccia questo. Io personalmente uso awesome_print.

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

require 'awesome_print' 

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

Ha un sacco di opzioni, dai un'occhiata!

+0

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

+0

Grazie, non ne ho mai sentito parlare ma sembra davvero promettente. –

+0

Qualche idea su come potrei passare il passaggio di questi dati tra le classi? Ognuno dei nodi nell'albero sopra rappresenta una classe nel mio compilatore, dovrei semplicemente restituire un array da ciascuno di quei nodi e riunirli in un hash in qualche modo? –

2

È necessario controllare la gemma Graph. È fantastico e straordinariamente semplice da lavorare. Puoi scegliere la direzione del tuo albero e la forma dei nodi, così come i colori e molto altro ancora. L'ho scoperto per la prima volta al Rubyconf l'anno scorso e sono rimasto senza parole.

E 'semplice come:

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

Ovviamente si vorrebbe entrare programmazione bordi :)

Ecco un link to a pdf del discorso che darà ulteriori informazioni su di esso:

C'è anche un video del talk su Confreaks se sei interessato.

Cheers, Sean

+0

Grazie, lo esaminerò sicuramente –

Problemi correlati