7

我正在构建一个编译器,并在其中生成一棵树,它代表传入的源程序。我想显示这是一棵树,就像时尚一样,所以我可以向任何感兴趣的人显示程序的结构。

现在我只是将树打印在一行上,如下所示:

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

我想要的是这样的:

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

我还没有真正在 Ruby 中使用过树,它们通常是如何表示的?

任何帮助,将不胜感激。

4

2 回答 2

3

这种漂亮的印刷需要相当多的数学知识。此外,如果树对于控制台窗口来说太宽,会发生什么还不清楚。我不知道有任何现有的库可以做到这一点。我个人使用awesome_print.

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

require 'awesome_print'

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

它有很多选择,看看吧!

于 2012-06-19T15:05:27.213 回答
3

您需要查看Graph gem。使用起来非常棒,而且非常简单。您可以选择树的方向和节点的形状,以及颜色等等。我在去年的 Rubyconf 上第一次发现了它并被震撼了。

它很简单:

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

显然你会想以编程方式输入边缘:)

这是演讲pdf的链接,其中将提供更多信息:

如果您有兴趣,还有关于Confreaks的演讲视频。

干杯,肖恩

于 2012-06-19T18:04:41.903 回答