Skip to content

Commit eddf696

Browse files
committed
Add fixed graphviz notes
1 parent 753d1cf commit eddf696

1 file changed

Lines changed: 25 additions & 27 deletions

File tree

www/notes/graphviz.scrbl

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@
1010

1111
@(define codeblock-include (make-codeblock-include #'h))
1212

13-
@(for-each (λ (f) (ev `(require (file ,(path->string (build-path notes "knock" f))))))
14-
'("interp.rkt" "compile.rkt" "ast.rkt" "syntax.rkt" "asm/interp.rkt" "asm/printer.rkt"))
15-
1613
@title[#:tag "Graphviz"]{Using Graphviz/dot to visualize our AST}
1714

1815
@table-of-contents[]
@@ -23,16 +20,15 @@ Abstract Syntax Trees (ASTs) are a useful abstraction when dealing with
2320
programming languages as an object for analysis or manipulation (e.g.
2421
compilation). At the same time, these structures can quickly become
2522
too large reason about just by looking at it. For example, in Knock,
26-
our AST for @racket[(if (zero? x) (add1 (add1 x)) (sub1 x))] looks
23+
our AST for @tt{(if (zero? x) (add1 (add1 x)) (sub1 x))} looks
2724
like the following:
2825

2926
@#reader scribble/comment-reader
3027
(racketblock
3128
(if-e
3229
(prim-e 'zero? (list (var-e 'x)))
3330
(prim-e 'add1 (list (prim-e 'add1 (list (int-e 1)))))
34-
(prim-e 'sub1 (list (var-e 'x))))
35-
)
31+
(prim-e 'sub1 (list (var-e 'x)))))
3632

3733
This has all the information necessary for manipulating our program (and more),
3834
it's a bit unwieldy to look at. Particularly when debugging, it can
@@ -46,11 +42,11 @@ the following AST:
4642
@#reader scribble/comment-reader
4743
(racketblock
4844
(if-e
49-
(prim-e 'zero? (list (var-e 'x)
45+
(prim-e 'zero? (list (var-e 'x)))
5046
(let-e
51-
(list (binding 'g387 (prim-e 'add1 (list (int-e 1))))
52-
(prim-e 'add1 (list (var-e 'g387))
53-
(prim-e 'sub1 (list (var-e 'x)))
47+
(list (binding 'g387 (prim-e 'add1 (list (int-e 1)))))
48+
(prim-e 'add1 (list (var-e 'g387)))
49+
(prim-e 'sub1 (list (var-e 'x))))))
5450

5551
Was the program transformation done correctly? If you study the AST
5652
carefully, you can determine that it was. However, it would be easier
@@ -89,28 +85,28 @@ for visualizing graphs.
8985
Graphviz has many components, but we will focus on @tt{dot}, which is
9086
the tool for laying out directed graphs. The full manual for @tt{dot}
9187
can be found on the graphviz website:
92-
@link["https://www.graphviz.org/pdf/dotguide.pdf"]{https://www.graphviz.org/pdf/dotguide.pdf}.
88+
@link["https://www.graphviz.org/pdf/dotguide.pdf"]{The Dot Guide}.
9389

9490
Instructions for downloading Graphviz (and therefore @tt{dot}) can be found on
9591
their website as well:
96-
@link["https://www.graphviz.org/download/"]{https://www.graphviz.org/download/}
92+
@link["https://www.graphviz.org/download/"]{Download Graphviz}
9793

9894
The syntax for @tt{dot} files is fairly straightforward, you first declare the
9995
type of graph, and give it a name. For our purposes the type will always be
10096
@tt{digraph} (i.e. directed-graph), and the name can be whatever you choose
10197
(though it will likely not matter much). For example:
10298

103-
@verbatim|
99+
@verbatim|{
104100
digraph CMSC430 {
105101
...
106102
}
107-
|
103+
}|
108104

109105
The ellipses are where you describe the graph you'd like to visualize. The
110106
designers of Graphviz provide a grammar describing the language accepted by
111107
their tools (I wish all system designers provided a grammar!). This can be
112108
found on the Graphviz website:
113-
@link["https://graphviz.org/doc/info/lang.html"]{https://graphviz.org/doc/info/lang.html}
109+
@link["https://graphviz.org/doc/info/lang.html"]{The DOT language}.
114110

115111
Most of the time you will not need to consult the grammar, as most of the
116112
simple rules are straightforward for those that have programmed in C or Java.
@@ -132,13 +128,13 @@ course), you can basically just use the following three types of statements:
132128
Node statements are just an ASCII string (representing a Node ID) and an
133129
optional list of attributes for that node. For example:
134130

135-
@verbatim|
131+
@verbatim|{
136132
digraph CMSC430 {
137133
lexer;
138134
parser [shape=box];
139135
code_gen [color=red];
140136
}
141-
|
137+
}|
142138

143139
Using the @tt{dot} tool on a file with the above as its contents produces the
144140
following diagram:
@@ -147,13 +143,13 @@ following diagram:
147143

148144
Edge statements connect nodes in our graph, for example:
149145

150-
@verbatim|
146+
@verbatim|{
151147
digraph CMSC430 {
152148
lexer -> parser -> code_gen;
153149
parser [shape=box];
154150
code_gen [color=red];
155151
}
156-
|
152+
}|
157153

158154
This produces the following diagram:
159155

@@ -163,13 +159,13 @@ You may wonder if the order matters here. While the @emph{horizontal} order
163159
matters when specifying the edges in an edge statement, the @emph{vertical}
164160
order does not matter in this case. The following produces the same diagram:
165161

166-
@verbatim|
162+
@verbatim|{
167163
digraph CMSC430 {
168164
parser [shape=box];
169165
code_gen [color=red];
170166
lexer -> parser -> code_gen;
171167
}
172-
|
168+
}|
173169

174170
Notice that @tt{lexer} does not have its own `declaration' this is because it
175171
is unnecessary unless you want to attach attributes to a node (as we do
@@ -179,13 +175,13 @@ Edge statements also support an optional list of attributes, the following
179175
produces a similar diagram except that both edges are shaded ``deeppink2'' (for
180176
the full list of supported colors, see the official documentation).
181177

182-
@verbatim|
178+
@verbatim|{
183179
digraph CMSC430 {
184180
lexer -> parser -> code_gen [color=deeppink2];
185181
parser [shape=box];
186182
code_gen [color=red];
187183
}
188-
|
184+
}|
189185

190186
Attribute nodes describe a set of attributes that apply to all subsequent
191187
statements (which means that vertical order @emph{does} matter here!). Unless
@@ -196,7 +192,7 @@ Here we added three attribute statements. Take a minute to study the example
196192
below and see how each attribute statement affects the output.
197193

198194

199-
@verbatim|
195+
@verbatim|{
200196
digraph CMSC430 {
201197
edge [color=blue];
202198
lexer -> parser
@@ -207,7 +203,7 @@ digraph CMSC430 {
207203
code_gen [color=red];
208204
optimizer -> code_gen;
209205
}
210-
|
206+
}|
211207

212208
@image{img/edges3.png}
213209

@@ -224,7 +220,7 @@ an @tt{if} node).
224220
Here is an example of a @tt{dot} description make using our library on the program
225221
@racket[(if (zero? x) 1 2)]:
226222

227-
@verbatim|
223+
@verbatim|{
228224
digraph prog {
229225
g850 [ label=" x " ];
230226
g849 [ color=red,label=" (zero? ...) " ];
@@ -236,7 +232,7 @@ digraph prog {
236232
g848 -> g851 ;
237233
g848 -> g852 ;
238234
}
239-
|
235+
}|
240236

241237
Not super nice to read, but we had a program write it for us!
242238

@@ -246,3 +242,5 @@ The complete library (three files):
246242
@codeblock-include["knock/dot.rkt"]
247243
@codeblock-include["knock/render-ast.rkt"]
248244
@codeblock-include["knock/pretty-printer.rkt"]
245+
246+

0 commit comments

Comments
 (0)