Home meiner WebpräsenzStartseite
Das Menü auf einem Blick!Sitemap
Downloads vorliegender WebSiteDownloads
Hilfeseite vorliegender HomepageHilfe
Erscheinungsvermerk vorliegender HomepageImpressum
Anforderungsdefinition mit PflichtenheftPflichtenheft










Tinyray-DotCode
DotCode erzeugt aus einem Tinyray-Programm ein Dot-Programm von graphviz.
1 Dot
2 Implementierung
3 Anwendung
Dot

Zielvorstellung
Ein Tinyray−Quellprogramm soll in ein Dot−Programm übersetzt werden.
Was ist denn eigentlich Dot?
Dot ist eine Anwendung zur Visualisierung von Grafen. Diese Dot−Anwendung können Sie unter www.graphviz.org herunterladen.
Implementierung

Die Java−Klasse DotCode ist hier als Visitor realisiert.
DotCode.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
package tinyray.language;

import java.util.Iterator;

/**
 * Die Klasse DotCode implementiert einen Besucher (Visitor),
 * der aus einem Syntaxbaum, der mit Hilfe von LanguageKit erzeugt ist,
 * einen Dot-Code.
 */

public class DotCode implements Visitor<String, String> {

    private final static String NEWLINE = "\r\n";
    private final static String INDENT = "\t";
    private final static String BREAK = NEWLINE + INDENT;
    private final static String ARROW = " -> ";
    private final static String TERMINATOR = ";";
    private final static String NODE = "node";
    private final static String EDGE = "edge";

    private boolean compact;
    private int indexer;
    private boolean color;

    private String label(String string) {
        return "[label=\"" + string + "\"]";
    }

    public DotCode() {
        this(false);
    }

    public DotCode(boolean compact) {
        this.compact = compact;
        this.indexer = 0;

        this.color = false;
    }

    public String visit(Tinyray tinyray, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Header
        result += "// Automatisch generierter Dot-Code";
        result += NEWLINE;
        result += "// $ dot -Tpng mein.dot -o mein.png";
        result += NEWLINE;
        result += "// Herkunft: Tinyray (http://www.stefan-baur.de)";
        result += NEWLINE;
        result += NEWLINE;
        // Dot-Graph
        result += "digraph TinyrayGraph {";
        // Dot-Parameter
        result += NEWLINE;
        result += BREAK + "graph[rankdir=LR]" + TERMINATOR;
        result += BREAK + "graph[ranksep=0.3]" + TERMINATOR;
        result += BREAK + "edge[fontname=\"Arial\"]" + TERMINATOR;
        result += BREAK + "edge[fontsize=11]" + TERMINATOR;
        result += BREAK + "edge[fontcolor=\"#333333\"]" + TERMINATOR;
        result += BREAK + "edge[color=\"#333333\"]" + TERMINATOR;
        result += BREAK + "node[height=0.08]" + TERMINATOR;
        result += BREAK + "node[fontname=\"Arial\"]" + TERMINATOR;
        result += BREAK + "node[fontsize=10]" + TERMINATOR;
        result += BREAK + "node[fontcolor=\"#333333\"]" + TERMINATOR;
        result += BREAK + "node[color=\"#333333\"]" + TERMINATOR;
        result += NEWLINE;
        // Tinyray-Knoten Dot-Code
        result += BREAK + node + this.label("Tinyray") + TERMINATOR;
        result += BREAK + node + TERMINATOR;
        // Besuche camera
        result += NEWLINE;
        result += BREAK + EDGE + this.label("") + TERMINATOR;
        result += tinyray.camera.accept(this, node);
        // Besuche ambience
        result += NEWLINE;
        result += BREAK + EDGE + this.label("") + TERMINATOR;
        result += tinyray.ambience.accept(this, node);
        // Besuche background
        result += NEWLINE;
        result += BREAK + EDGE + this.label("") + TERMINATOR;
        result += tinyray.background.accept(this, node);
        // Besuche fog
        result += NEWLINE;
        result += BREAK + EDGE + this.label("") + TERMINATOR;
        result += tinyray.fog.accept(this, node);
        // Besuche suns
        Iterator<Sun> suns = tinyray.suns.iterator();
        while (suns.hasNext()) {
            result += NEWLINE;
            result += BREAK + EDGE + this.label("") + TERMINATOR;
            result += suns.next().accept(this, node);
        }
        // Besuche Defaults und Geoobjekte
        Iterator<Visitable> visitables = tinyray.visitables.iterator();
        while (visitables.hasNext()) {
            result += NEWLINE;
            result += BREAK + EDGE + this.label("") + TERMINATOR;
            result += visitables.next().accept(this, node);
        }
        result += NEWLINE;
        result += "}";
        // Sourcecode
        result += NEWLINE;
        result += NEWLINE;
        result += "// Quelle: Tinyray-Code";
        result += NEWLINE;
        result += "//";
        result += NEWLINE;
        result += tinyray.accept(new PrettyPrint(), "// ");
        result += NEWLINE;
        return result;
    }

    public String visit(Camera camera, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Camera-Knoten Dot-Code
        result += BREAK + node + this.label("Camera") + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        // Besuche location
        result += NEWLINE;
        result += BREAK + EDGE + this.label("location") + TERMINATOR;
        result += camera.location.accept(this, node);
        // Besuche lookAt
        result += NEWLINE;
        result += BREAK + EDGE + this.label("look at") + TERMINATOR;
        result += camera.lookAt.accept(this, node);
        // Besuche up
        result += NEWLINE;
        result += BREAK + EDGE + this.label("up") + TERMINATOR;
        result += camera.up.accept(this, node);
        return result;
    }

    public String visit(Background background, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Background-Knoten Dot-Code
        result += BREAK + node + this.label("Background") + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        // Besuche color
        result += NEWLINE;
        result += BREAK + EDGE + this.label("color") + TERMINATOR;
        this.color = true;
        result += background.color.accept(this, node);
        return result;
    }

    public String visit(Ambience ambience, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Ambience-Knoten Dot-Code
        result += BREAK + node + this.label("Ambience") + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        // Besuche color
        result += NEWLINE;
        result += BREAK + EDGE + this.label("color") + TERMINATOR;
        this.color = true;
        result += ambience.color.accept(this, node);
        return result;
    }

    public String visit(Fog fog, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Fog-Knoten Dot-Code
        result += BREAK + node + this.label("Fog") + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        // Besuche color
        result += NEWLINE;
        result += BREAK + EDGE + this.label("color") + TERMINATOR;
        this.color = true;
        result += fog.color.accept(this, node);
        // Besuche density
        result += NEWLINE;
        result += BREAK + EDGE + this.label("density") + TERMINATOR;
        result += fog.density.accept(this, node);
        return result;
    }

    public String visit(Defaults defaults, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Defaults-Knoten Dot-Code
        result += BREAK + node + this.label("Defaults") + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        // Besuche parameters
        result += NEWLINE;
        result += BREAK + EDGE + this.label("") + TERMINATOR;
        result += defaults.parameters.accept(this, node);
        return result;
    }

    public String visit(Sun sun, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Sun-Knoten Dot-Code
        result += BREAK + node + this.label("Sun") + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        // Besuche direction
        result += NEWLINE;
        result += BREAK + EDGE + this.label("direction") + TERMINATOR;
        result += sun.direction.accept(this, node);
        // Besuche color
        result += NEWLINE;
        result += BREAK + EDGE + this.label("color") + TERMINATOR;
        this.color = true;
        result += sun.color.accept(this, node);
        return result;
    }

    public String visit(Bounding bounding, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Bounding-Knoten Dot-Code
        result += BREAK + node + this.label("Bounding") + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        // Besuche alle besuchbaren Objekte von bounding
        Iterator<Visitable> visitables = bounding.visitables.iterator();
        while (visitables.hasNext()) {
            result += NEWLINE;
            result += BREAK + EDGE + this.label("") + TERMINATOR;
            result += visitables.next().accept(this, node);
        }
        return result;
    }

    public String visit(Triangle triangle, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Triangle-Knoten Dot-Code
        result += BREAK + node + this.label("Triangle") + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        // Besuche x
        result += NEWLINE;
        result += BREAK + EDGE + this.label("x") + TERMINATOR;
        result += triangle.x.accept(this, node);
        // Besuche y
        result += NEWLINE;
        result += BREAK + EDGE + this.label("y") + TERMINATOR;
        result += triangle.y.accept(this, node);
        // Besuche z
        result += NEWLINE;
        result += BREAK + EDGE + this.label("z") + TERMINATOR;
        result += triangle.z.accept(this, node);
        // Besuche parameters
        if (triangle.parameters.visitables.size() > 0) {
            result += NEWLINE;
            result += BREAK + EDGE + this.label("") + TERMINATOR;
            result += triangle.parameters.accept(this, node);
        }
        return result;
    }

    public String visit(Sphere sphere, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Sphere-Knoten Dot-Code
        result += BREAK + node + this.label("Sphere") + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        // Besuche center
        result += NEWLINE;
        result += BREAK + EDGE + this.label("center") + TERMINATOR;
        result += sphere.center.accept(this, node);
        // Besuche radius
        result += NEWLINE;
        result += BREAK + EDGE + this.label("radius") + TERMINATOR;
        result += sphere.radius.accept(this, node);
        // Besuche parameters
        if (sphere.parameters.visitables.size() > 0) {
            result += NEWLINE;
            result += BREAK + EDGE + this.label("") + TERMINATOR;
            result += sphere.parameters.accept(this, node);
        }
        return result;
    }

    public String visit(Plane plane, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Plane-Knoten Dot-Code
        result += BREAK + node + this.label("Plane") + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        // Besuche x
        result += NEWLINE;
        result += BREAK + EDGE + this.label("x") + TERMINATOR;
        result += plane.x.accept(this, node);
        // Besuche y
        result += NEWLINE;
        result += BREAK + EDGE + this.label("y") + TERMINATOR;
        result += plane.y.accept(this, node);
        // Besuche z
        result += NEWLINE;
        result += BREAK + EDGE + this.label("z") + TERMINATOR;
        result += plane.z.accept(this, node);
        // Besuche parameters
        if (plane.parameters.visitables.size() > 0) {
            result += NEWLINE;
            result += BREAK + EDGE + this.label("") + TERMINATOR;
            result += plane.parameters.accept(this, node);
        }
        return result;
    }

    public String visit(Parameters parameters, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Parameters-Knoten Dot-Code
        result += BREAK + node + this.label("Parameters") + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        // Besuche 1. Parameter, falls vorhanden
        if (parameters.visitables.size() > 0) {
            result += NEWLINE;
            result += BREAK + EDGE + this.label("diffuse") + TERMINATOR;
            this.color = true;
            result += parameters.visitables.get(0).accept(this, node);
        }
        // Besuche 2. Parameter, falls vorhanden
        if (parameters.visitables.size() > 1) {
            result += NEWLINE;
            result += BREAK + EDGE + this.label("ambient") + TERMINATOR;
            this.color = true;
            result += parameters.visitables.get(1).accept(this, node);
        }
        // Besuche 3. Parameter, falls vorhanden
        if (parameters.visitables.size() > 2) {
            result += NEWLINE;
            result += BREAK + EDGE + this.label("specular") + TERMINATOR;
            result += parameters.visitables.get(2).accept(this, node);
        }
        // Besuche 4. Parameter, falls vorhanden
        if (parameters.visitables.size() > 3) {
            result += NEWLINE;
            result += BREAK + EDGE + this.label("shininess") + TERMINATOR;
            result += parameters.visitables.get(3).accept(this, node);
        }
        // Besuche 5. Parameter, falls vorhanden
        if (parameters.visitables.size() > 4) {
            result += NEWLINE;
            result += BREAK + EDGE + this.label("mirror") + TERMINATOR;
            result += parameters.visitables.get(4).accept(this, node);
        }
        return result;
    }

    public String visit(Vector vector, String parent) {
        String node = NODE + indexer++;
        String result = "";

        if (this.color) {
            // Hintergrundfarbe des Vector-Knotens ermitteln und setzen.
            int r = Math.min(Math.max((int)(vector.x.value * 255.0), 0), 255);
            int g = Math.min(Math.max((int)(vector.y.value * 255.0), 0), 255);
            int b = Math.min(Math.max((int)(vector.z.value * 255.0), 0), 255);
            String hexR = ((<= 0xF) ? "0" : "") + Integer.toHexString(r);
            String hexG = ((<= 0xF) ? "0" : "") + Integer.toHexString(g);
            String hexB = ((<= 0xF) ? "0" : "") + Integer.toHexString(b);
            String hexRGB = hexR + hexG + hexB;
            result += BREAK + node + "[style=filled]" + TERMINATOR;
            result += BREAK + node + "[fillcolor=\"#";
            result += hexRGB + "\"]" + TERMINATOR;
            // Vordergrundfarbe des Vector-Knotens setzen.
            if (+ g + b > 255) {
                result += BREAK + node + "[color=\"#333333\"]" + TERMINATOR;
                result += BREAK + node + "[fontcolor=\"#333333\"]" + TERMINATOR;
            } else {
                result += BREAK + node + "[color=\"#cccccc\"]" + TERMINATOR;
                result += BREAK + node + "[fontcolor=\"#cccccc\"]" + TERMINATOR;
            }
            // Farbe konsumiert.
            this.color = false;
        }
        // Vector-Knoten Dot-Code
        if (this.compact) {
            // Kurzfassung
            result += BREAK + node + "[shape=record]" + TERMINATOR;
            result += BREAK + node + "[label=\"{ Vector | { ";
            result += vector.x.value + " | ";
            result += vector.y.value + " | ";
            result += vector.z.value + " } }\"]" + TERMINATOR;
            result += BREAK + parent + ARROW + node + TERMINATOR;
        } else {
            // Langfassung
            result += BREAK + node + this.label("Vector") + TERMINATOR;
            result += BREAK + parent + ARROW + node + TERMINATOR;
            // Besuche x
            result += NEWLINE;
            result += BREAK + EDGE + this.label("x") + TERMINATOR;
            result += vector.x.accept(this, node);
            // Besuche y
            result += NEWLINE;
            result += BREAK + EDGE + this.label("y") + TERMINATOR;
            result += vector.y.accept(this, node);
            // Besuche z
            result += NEWLINE;
            result += BREAK + EDGE + this.label("z") + TERMINATOR;
            result += vector.z.accept(this, node);
        }
        return result;
    }

    public String visit(Real real, String parent) {
        String node = NODE + indexer++;
        String result = "";
        // Real-Knoten Dot-Code
        result += BREAK + node + "[shape=record]" + TERMINATOR;
        result += BREAK + node + "[label=\"{ Real | ";
        result += real.value + " }\"]" + TERMINATOR;
        result += BREAK + parent + ARROW + node + TERMINATOR;
        return result;
    }
}
Anwendung

Folgende Anwendung nutzt die Klasse DotCode und wandelt ein gegebenes Tinyray−Programm in ein Dot−Programm um.
UseDotCode.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package tinyray;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

import tinyray.frontend.ParseException;
import tinyray.frontend.Parser;
import tinyray.frontend.Scanner;
import tinyray.language.LanguageKit;
import tinyray.language.DotCode;
import tinyray.language.Tinyray;
import tinyray.language.Visitable;

/**
 * Die Klasse UseDotCode generiert aus einem Tinyray-Code
 * einen Dot-Code (siehe http://www.graphviz.org/).
 */

public class UseDotCode {

    /**
     * Das Hauptprogramm, welches aus einem Tinyray-Code einen Dot-Code
     * generiert. Das Ergebnis wird auf der Konsole ausgegeben (System.out).
     * @param arguments Die Aufrufargumente.
     *        Das erste Argument gibt den Dateinamen der Tinyray-Datei an.
     *        Ist das erste Argument nicht gesetzt, erhält der Benutzer
     *        einen kurzen Hilfetext.
     */

    public static void main(String[] arguments) {

        // Mindestens ein Argument erforderlich: <Dateiname>
        if (arguments.length > 0) {

            try {
                // Der Scanner erhält den Tinyray-Code als Stream.
                Scanner scanner =
                    new Scanner(new FileInputStream(arguments[0]));

                // Der Parser erhält den Scanner und eine konkreten Fabrik
                // (hier LanguageKit).
                Parser<Visitable, Tinyray> parser =
                    new Parser<Visitable, Tinyray>(scanner, new LanguageKit());

                // Der Parse-Vorgang bringt einen Syntaxbaum hervor.
                // Die einzelnen Knoten des Syntaxbaumes werden automatisch
                // von der konkreten Fabrik "LanguageKit" erzeugt.
                Tinyray tinyray = parser.parse();

                // Der Syntaxbaum besteht aus besuchbaren Knoten (accept).

                boolean compact = false;

                if (arguments.length > 1) {
                    compact = "compact".equalsIgnoreCase(arguments[1]);
                }

                String dotcode = tinyray.accept(new DotCode(compact), "");

                // Ausgabe des DotCode
                System.out.println(dotcode);

            } catch (ParseException e) {
                // Fehlermeldung, falls gegebener Tinyray-Code fehlerhaft.
                System.err.println(e.getMessage());
            } catch (FileNotFoundException e) {
                // Fehlermeldung, falls das erste Argument keine Datei benennt.
                System.err.println(e.getMessage());
            }

        } else {
            // Kurzhilfe, falls Aufruf ohne Argument.
            System.out.println(usage());
        }
    }

    public static String usage() {
        String result = "";
        result += "java tinyray/UseDotCode <TinyrayDatei> [compact]\r\n";
        result += "\r\nBeispiele:\r\n";
        result += " java tinyray/UseDotCode MyScene.tinyray\r\n";
        result += " java tinyray/UseDotCode Test01.txt compact\r\n";
        result += "\r\nHinweis:\r\n";
        result += " Mindestens JRE (java-1.6.0) erforderlich.\r\n";
        return result;
    }
}
Ein Programmaufruf ohne Aufrufparameter zeigt dem Aufrufenden die Programmkurzhilfe (usage).
java UseDotCode
1
2
3
4
5
6
7
8
9
java tinyray/UseDotCode <TinyrayDatei> [compact]

Beispiele:
 java tinyray/UseDotCode MyScene.tinyray
 java tinyray/UseDotCode Test01.txt compact

Hinweis:
 Mindestens JRE (java-1.6.0) erforderlich.
Allgemein

Diese Seite ist Bestandteil der Domäne www.stefan−baur.de und heißt Tinyray−DotCode. Die letzte Änderung erfuhr diese Seite am Dienstag, den 22. Mai 2007 von Stefan K. Baur. Zuletzt wurde sie von Ihnen am Mittwoch, den 8. September 2010 um 3:32 Uhr im Internet besucht. Sie gelangen zur vorliegenden Seite, wenn Sie ausgehend von der Startseite über dem Hauptmenü wie folgt navigieren:
Startseite
Informatik
Programmiersprachen
Interpreter
Tinyray
Tinyray−Language
Tinyray−Visitors
Tinyray−DotCode
Wenn Sie die vorliegende Seite ausdrucken möchten, nutzen Sie dazu die Printversion.


Autoren

Werden Sie Autor vorliegender Homepage, informieren Sie sich unter Autoren.
Look & Feel

Das aktuelle Design trägt den Namen „Design 2007”.
Falls Ihnen jedoch das aktuelle Design nicht zusagen sollte, so stehen Ihnen noch andere, alternative Designs zur Verfügung:
Design 2010
Design 2009
Design 2008
Design 2006
Design 2005
Design 2004
Copyright

Vorliegender Webauftritt wurde in mühevoller Kleinarbeit von Stefan K. Baur entwickelt.
Copyright (c) 2004-2010 Stefan K. Baur
Home meiner WebpräsenzStartseite
Das Menü auf einem Blick!Sitemap
Downloads vorliegender WebSiteDownloads
Hilfeseite vorliegender HomepageHilfe
Erscheinungsvermerk vorliegender HomepageImpressum
Anforderungsdefinition mit PflichtenheftPflichtenheft