【问题标题】:graphically plotting lisp code以图形方式绘制 lisp 代码
【发布时间】:2023-04-05 20:32:01
【问题描述】:

关于一个 GP 项目,我有很多自动生成的 lisp sn-ps,它们基本上看起来像这样:

(+ 2 (f1 (f2 x y) (f2 x y)))

简而言之:大量单行。

如何将其以图形方式绘制到函数树中?最好通过在 dot 或类似的东西中生成图表,这些图表可以很容易地通过 graphviz 推送,这样我就可以将它渲染成这样的东西:

       +
      / \
     /   \
    2     f1
         /  \
        /    \
       /      \
      /        \
     f2         f2
    /  \       /  \
   /    \     /    \
  x      y   x      y

【问题讨论】:

标签: treeview lisp graphviz dot


【解决方案1】:

这是怎么回事(在方案 [Dr. Racket] 中):

(define (as-string elm)
  (cond
    ((string? elm) (string-append "\\\"" elm "\\\""))
    ((number? elm) (number->string elm))
    ((symbol? elm) (symbol->string elm))
    ((null? elm) "*empty-list*")
    (else (error "Unrecognized type"))))

(define (node-name-label names labels)
  (apply append (map (lambda (a b)
                       (if (list? a)
                           (node-name-label a b)
                           (list (cons a b))))
                     names labels)))

(define (node-txt names labels)
  (apply string-append (map (lambda (x)
                              (let ((name (car x)) (label (cdr x)))
                                (string-append name " [label=\"" (as-string label) "\"];\n")))
                            (node-name-label names labels))))

(define (graph-txt lst)
  (apply string-append (map (lambda (x)
                              (let ((a (car x)) (b (cdr x)))
                                (string-append a " -- " b ";\n")))
                            (get-relationships lst))))

(define (declare-nodes lst (basename "node"))
  (map (lambda (x n)
         (if (and (list? x) (not (empty? x)))
             (declare-nodes x (string-append basename "_" (number->string n)))
             (string-append basename "_" (number->string n))))
       lst
       (range 0 (length lst))))

(define (get-relationships lst)
  (if (< (length lst) 2)
      null
      (apply append (map (lambda (x)
                           (if (list? x)
                               (cons (cons (car lst) (car x)) (get-relationships x))
                               (list (cons (car lst) x))))
                         (cdr lst)))))

(define (range start end)
  (if (>= start end)
      '()
      (cons start (range (+ 1 start) end))))

(define (get-graph code graph-title)
  (let ((names (declare-nodes code)))
    (string-append
     "graph "
     graph-title
     " {\n"
     (node-txt names code)
     "\n"
     (graph-txt names)
     "}")))

用法:(display (get-graph '(+ 2 (f1 (f2 () y) (f2 x y))) "simple_graph")) 产生:

graph simple_graph {
node_0 [label="+"];
node_1 [label="2"];
node_2_0 [label="f1"];
node_2_1_0 [label="f2"];
node_2_1_1 [label="*empty-list*"];
node_2_1_2 [label="y"];
node_2_2_0 [label="f2"];
node_2_2_1 [label="x"];
node_2_2_2 [label="y"];

node_0 -- node_1;
node_0 -- node_2_0;
node_2_0 -- node_2_1_0;
node_2_1_0 -- node_2_1_1;
node_2_1_0 -- node_2_1_2;
node_2_0 -- node_2_2_0;
node_2_2_0 -- node_2_2_1;
node_2_2_0 -- node_2_2_2;
}

【讨论】:

    【解决方案2】:

    我制作了一个快速而肮脏的 perl 脚本来满足我的需要。把它放在这里以防其他人可以使用它: 链接:http://jarmund.net/stuff/lisp2svg.pl.txt

    示例输出:http://jarmund.net/graphs/lisp.svg

    注意:你不能嘲笑丑陋的代码,它只处理最基本的事情,所以它可能需要一些黑客来做比我需要的更多的事情。

    【讨论】:

      猜你喜欢
      • 2019-09-25
      • 1970-01-01
      • 2016-11-11
      • 1970-01-01
      • 1970-01-01
      • 2011-04-01
      • 2011-09-21
      • 2020-01-05
      • 2011-06-30
      相关资源
      最近更新 更多