Executor
Vorbemerkungen
Der Executor ist derjenige Teil von Structorizer, der versucht, ein Diagramm zu interpretieren und auszuführen. Er ist z. B. über das Menü „Debug" erreichbar.

Beachten Sie, dass Nassi-Shneiderman-Diagramme (NS-Diagramme) grundsätzlich syntaxfrei sind. Das bedeutet, dass Sie beliebigen beschreibenden Text in die Elemente einfügen können. Wie sinnvoll das ist, hängt natürlich vom Detailgrad ab. Häufig ist es praktischer, formalere Notationen wie Pseudocode oder mehr oder weniger allgemein akzeptierte Programmiersprach-Konstrukte zu verwenden.
Um ein NS-Diagramm „auszuführen", müssen Sie sich an eine bestimmte Syntax halten. Aus demselben Grund können nicht alle Diagramme oder alle enthaltenen Strukturen interpretiert werden. Der Executor wurde ursprünglich hinzugefügt, um Anfängern das Verstehen von Kontrollstrukturen und Ausführungsabläufen zu erleichtern. Im Laufe der Zeit haben zahlreiche Erweiterungen ihn jedoch erheblich mächtiger gemacht als ursprünglich geplant. Eine Übersicht über den ausführbaren Dialekt, der in Structorizer verwendet wird, finden Sie auf der Syntax-Seite dieses User Guides.
Übersicht der restlichen Unterabschnitte dieser Handbuchseite:
- Executor starten
- Executor-Steuerfeld
- Animation
- Haltepunkte (Breakpoints)
- Ausgabefenster (Output Console Window)
- Aufrufstapel-Anzeige (Call Stack Display)
- Einschränkungen und Probleme
Executor starten
Um den Executor zu starten, verwenden Sie den Menüpunkt „Debug › Executor ..." oder klicken Sie auf das entsprechende Symbolleistensymbol. Dadurch öffnet sich das Executor-Steuerfeld.
Wenn Ihr Algorithmus Turtleizer-spezifische Unterroutinen enthält, müssen Sie stattdessen auf das Schildkröten-Symbol in der Symbolleiste klicken oder den Menüpunkt „Debug › Turtleizer ..." wählen (es sei denn, das Turtleizer-Fenster ist bereits geöffnet).
Hinweis: Das Steuerfeld kann nicht über die betriebssystemübliche Schließen-Schaltfläche (z. B. das rote „X" oben rechts in Windows) geschlossen werden, solange eine Ausführung läuft oder ausstehend ist. Ab Release 3.27 werden Sie gewarnt, wenn Sie dies versuchen.
Das Steuerfeld schließt sich automatisch bei Beendigung der Ausführung, außer wenn Runtime Analysis aktiv ist. Sie können es durch Drücken der entsprechenden Schaltfläche schließen oder im Hintergrund halten, wenn es im Runtime-Analysis-Modus stört.
Executor-Steuerfeld
Im Folgenden werden die Details des Executor-Steuerfelds erläutert.

Schaltflächen für die Ausführungssteuerung
Die wichtigsten Bedienelemente sind die vier Schaltflächen in der vierten Zeile mit folgenden Funktionen (von links nach rechts):
- (Stop): Bricht die Ausführung sofort ab und schließt das Steuerfeld (außer bei aktiver Runtime Analysis). Alle Ausführungsstatus gehen verloren (erfasste Laufzeitzähler bleiben jedoch erhalten).
- (Run): Startet oder setzt die Ausführung mit der aktuellen Anweisung fort und läuft mit der über den Schieberegler in der ersten Zeile eingestellten Verzögerung.
- (Pause): Unterbricht die Ausführung, behält aber den aktuellen Ausführungsstatus, sodass die Ausführung nach einer Inspektion und Interaktion fortgesetzt werden kann.
- (Step): Führt nur die aktuelle Anweisung aus und pausiert danach automatisch vor der nächsten Anweisung oder dem Ende des Algorithmus.
Ab Version 3.30-14 wird die Pause-Schaltfläche vorübergehend durch folgende Schaltfläche ersetzt, wenn bei einem CALL-Element pausiert wird:
- (Step into): Steigt in das aufgerufene Unterroutinen-Diagramm ein und setzt das Debugging darin fort (z. B. schrittweise).
Die Ausführung endet in folgenden Fällen:
- Die letzte Anweisung des Algorithmus wurde erreicht und ausgeführt.
- Ein EXIT-Element mit einer Exit-Anweisung wurde ausgeführt.
- Ein EXIT-Element mit einer Return-Anweisung wurde ausgeführt und das aktuell ausgeführte Diagramm befindet sich auf oberster Ebene.
- Die Stop-Schaltfläche wurde gedrückt.
- Ein Syntax- oder Ausführungsfehler ist aufgetreten.
Die Ausführung pausiert (kann also fortgesetzt werden) bei folgenden Ereignissen:
- Die Ausführung wurde mit der Step- (oder Step-into-)Schaltfläche durchgeführt.
- Die Pause- oder Step-Schaltfläche wurde während der Ausführung gedrückt.
- Ein Haltepunkt (Breakpoint) wird erreicht.
- Eine Eingabeanweisung wird ausgeführt und Sie haben im erscheinenden Eingabedialog „Cancel" gedrückt.
- Eine Ausgabeanweisung wird ausgeführt (sofern der Ausgabemodus nicht „output to window" ist) und Sie haben in der erscheinenden Anzeigemeldung „Pause" gedrückt.
- Ein mit „Step over" ausgeführter Unterroutinen-CALL zurückgekehrt ist.
Einige Aktivitäten (wie die Aufrufstapel-Anzeige) sind nur im pausierten Zustand möglich.
Die Ausführung wird über die Run- oder Step-Schaltfläche (oder die Step-into-Schaltfläche bei einem CALL-Element, ab Version 3.30-14) fortgesetzt.
Ausführungsverzögerung

Mit dem Schieberegler in der obersten Zeile können Sie die Ausführungsverzögerung zwischen den Anweisungen steuern (für eine bessere Beobachtbarkeit). Da die Mausbedienung recht grob ist, können Sie die Pfeiltasten (links/rechts) verwenden, um den Verzögerungswert um 1 zu erhöhen oder zu verringern, wenn der Schieberegler ausgewählt ist. Wenn Sie die Verzögerung auf 0 reduzieren, werden einige angezeigte Informationen (wie Variablenwerte, Ausführungszähler usw.) möglicherweise nicht aktualisiert, bis der Algorithmus wegen eines der oben beschriebenen Ereignisse in den pausierten Zustand übergeht.
Ausgabemodus

Die zweite Zeile enthält ein Kontrollkästchen „Output to window" (Ausgabe in Fenster), mit dem Sie festlegen können, wie Ausgabeanweisungen dargestellt werden: Wenn das Kontrollkästchen nicht ausgewählt ist, öffnet jede Ausgabeanweisung ein Meldungsfenster, das bestätigt werden muss, um fortzufahren. Andernfalls bleibt ein konsolenartiges Textfenster dauerhaft geöffnet, in das alle Ausgaben ohne Pause oder Warten geschrieben werden. Da die Ausgabe immer in diesem Konsolenfenster protokolliert wird (auch wenn es nicht sichtbar ist), können Sie die gesamte Ausgabehistorie des Programms durch Aktivieren des Kontrollkästchens nach Ausführung des Algorithmus noch einsehen.
Runtime-Analysis-Steuerung

Die dritte Zeile enthält ein Kontrollkästchen und eine Auswahlliste für den Visualisierungsmodus der Runtime Analysis. Das linke Kontrollkästchen aktiviert den Tracking-Modus, die Auswahlliste bestimmt die Art der Elementhervorhebung in Abhängigkeit vom Analysezweck. Die Steuerelemente sind während der Ausführung teilweise deaktiviert. Details finden Sie auf der Seite Runtime Analysis.
Aufrufstapel-Anzeige

Die fünfte Zeile zeigt rechts die aktuelle Unterroutinen-Aufrufebene an: Jede CALL-Anweisung, in die die Ausführung abgetaucht ist, erhöht die Unterroutinen-Ebene um eins; bei der Rückkehr aus einer aufgerufenen Unterroutine wird sie verringert. Die oberste Ebene (Programmebene) ist 0. Beachten Sie, dass eingebaute Funktionen oder Prozeduren die angezeigte Unterroutinen-Ebene nicht beeinflussen – nur aufgerufene Nassi-Shneiderman-Diagramme wirken sich aus. Im pausierten Ausführungszustand öffnet ein Klick auf die Schaltfläche „Call Stack" eine scrollbare Listenansicht des aktuellen Aufrufstapels.
Variablenanzeige

Der untere Bereich des Steuerfelds wird von der Variablenanzeige belegt. Sobald eine neue Variable eingeführt wird, erscheint eine neue Zeile mit dem Variablennamen in der linken Spalte und einer Zeichenkettendarstellung des aktuellen Werts in der rechten Spalte. Bei Zeilen mit zusammengesetztem Wert (d. h. einem Array oder Datensatz) zeigt die mittlere Spalte eine Aufklappschaltfläche.
Die drei (und einen halben) Wege zur Einführung einer Variable in Structorizer (die Variablen sind in den Beispielen id1 bis id5 benannt) sind:
- Als Parameter der (aktuell ausgeführten) Unterroutine, z. B.:
function(id1, id2) - Als Ziel einer Zuweisungsanweisung, z. B.:
id3 <- expression - Als Ziel einer Eingabeanweisung, z. B.:
INPUT id4 - Durch eine Deklaration, z. B.:
var id5: integer(Eine reine Deklaration ohne Zuweisung lässt die Variable in einem nicht initialisierten Zustand.)
Immer wenn die Ausführung pausiert, können Sie durch Doppelklick in ein Feld der rechten Spalte der Variablenanzeige den Wert zu Testzwecken bearbeiten oder weit rechts liegende Elemente eines großen Arrays einsehen. Der Wert einer angezeigten Konstante kann jedoch nicht bearbeitet werden (Konstantenwerte sind durch einen rosafarbenen Zellhintergrund gekennzeichnet).



Zusammengesetzte Werte können durch Drücken der zugehörigen Aufklappschaltfläche in der mittleren Spalte eingesehen oder geändert werden. Diese öffnet eine tabellarische Ansicht ähnlich der Variablenanzeige, die eine strukturierte Inspektion (und ggf. Modifikation) des Inhalts ermöglicht.





Wenn Sie die Ausführung fortsetzen, arbeitet der Algorithmus mit den geänderten Werten weiter. Die Start- und Step-Schaltflächen sind gesperrt, bis Sie die Bearbeitung abschließen oder verwerfen.
Animation
Die aktuell ausgeführte oder pausierte Anweisung wird mit einem orangefarbenen Hintergrund hervorgehoben. Zusammengesetzte Elemente mit ausstehender Ausführung (d. h. verschachtelte Komponenten, von denen gerade eine ausgeführt oder pausiert wird) werden in einem cremefarbenen Ton hervorgehoben. So können Sie den Ausführungsfortschritt leicht verfolgen.
Innerhalb von PARALLEL-Elementen werden diejenigen Teile der Threads, die bereits abgearbeitet wurden, ebenfalls cremefarbig markiert; da die Ausführung zufällig springt, wäre sonst kaum erkennbar, wie weit die verschiedenen Threads fortgeschritten sind.
Zusätzlich können im Runtime-Analysis-Modus bereits ausgeführte Elemente in leuchtendem Grün hervorgehoben werden, um die Test-Code-Abdeckung zu visualisieren. Alternativ können Elemente in einem Spektralfarbbereich entsprechend ihrer relativen Ausführungszählung oder der Anzahl beteiligter „atomarer" Operationen eingefärbt werden. Diese Färbung hat eine geringere Priorität als die Hervorhebung des aktuellen Ausführungsstatus.
Die Animationsgeschwindigkeit wird durch den Verzögerungsschieberegler in einem Bereich zwischen 0 und 2000 gesteuert. Der Standardwert ist 50.
CALL-Ausführung

Wenn Sie bei einem CALL-Element pausieren (z. B. weil Sie im Einzelschrittmodus dorthin gelangt sind, ein Haltepunkt gesetzt war oder Sie die Pause-Schaltfläche gedrückt haben), wird die Pause-Schaltfläche durch eine Step-into-Schaltfläche ersetzt (ab Version 3.30-14).

Sie haben dann beim weiteren Debugging im Einzelschrittmodus zwei Möglichkeiten:
- (Step into): Steigt in das aufgerufene Unterroutinen-Diagramm ein und führt es Element für Element im Einzelschrittmodus aus.
- (Step over): Führt die Unterroutine als Ganzes aus und pausiert beim nächsten Element nach der Rückkehr aus dem CALL.
Vor Version 3.30-14 stieg die Step-Schaltfläche immer in den CALL ein. Um ihn zu überspringen, musste ein Haltepunkt nach dem CALL gesetzt und die Run-Schaltfläche verwendet werden (was umständlich und nicht immer möglich war).
Haltepunkte (Breakpoints)
Sie können an beliebig vielen Elementen Ihres Diagramms Haltepunkte setzen. Die Ausführung pausiert, sobald ein Element mit Haltepunkt erreicht wird.
Um einen Haltepunkt zu setzen oder zu entfernen, wählen Sie das entsprechende Element aus und klicken Sie dann entweder mit der rechten Maustaste und wählen/entfernen Sie den Menüpunkt „Toggle breakpoint" im Menü „Debug" oder im Kontextmenü, oder Sie doppelklicken und aktivieren/deaktivieren das Kontrollkästchen „Breakpoint" am unteren Rand des Element-Editors. Alternativ können Sie das Tastenkürzel StrgShiftB verwenden.

Im Diagramm wird ein Haltepunkt als roter horizontaler Balken am oberen Rand des Elementrahmens angezeigt (außer bei REPEAT-Schleifen, wo der rote Balken sinnvollerweise zwischen Schleifenrumpf und Abbruchbedingung erscheint).

Wenn Sie einen Haltepunkt auf einer Schleife (FOR, WHILE, REPEAT) setzen, pausiert die Ausführung jedes Mal, wenn die Schleifenbedingung erneut geprüft wird.
Auf einer ENDLESS-Schleife kann kein Haltepunkt gesetzt werden (da sie keine Steuermittel hat). Setzen Sie stattdessen einen Haltepunkt auf das erste Element ihres Rumpfs.
Während der Runtime-Analysis-Modus aktiv ist, können Sie auch konditionierte Haltepunkte verwenden: Sie können einen Ausführungszählwert angeben, der den Haltepunkt beim Erreichen auslösen soll. Das heißt, solange das Element noch nicht so oft ausgeführt wurde wie angegeben, wird der Haltepunkt übergangen, als wäre er nicht vorhanden. Erst wenn der aktuelle Ausführungszähler (beim Eintritt in das Element) genau dem angegebenen Auslösewert minus eins entspricht, wird der Haltepunkt ausgelöst. Konditionierte Haltepunkte werden als gepunktete rote Linie dargestellt; der Auslösewert erscheint in roter Farbe vor den Laufzeitzählern.

Ein Auslösewert von 0 entspricht einem unkonditionierten Haltepunkt wie oben beschrieben.
Da ein konditionierter Haltepunkt nach Überschreitung des (nicht null) Auslösezählers nicht mehr ausgelöst wird, dürfen Sie den Auslösewert ändern, wenn die Ausführung pausiert ist. Verwenden Sie dazu für ein ausgewähltes Element den Menüpunkt „Specify break trigger..." im Menü „Debug" oder im Kontextmenü, oder das Tastenkürzel StrgAltB.

Beim Deaktivieren des Haltepunkts bleibt der Auslösewert erhalten und kann bei späterer Reaktivierung wieder verwendet werden.
Um alle Haltepunkte über alle Diagramme hinweg vorübergehend zu deaktivieren, drücken Sie die entsprechende Schaltfläche in der Symbolleiste oder den Menüpunkt „Ignore all breakpoints" im Menü „Debug".
Hinweise:
- Haltepunkte werden nicht in Dateien gespeichert.
- Das Setzen, Ändern oder Entfernen eines Haltepunkts erzeugt keinen Eintrag im Undo-/Redo-Stapel. Jede rückgängig zu machende Änderung an einem Diagramm ist jedoch mit einem Schnappschuss aller aktuell gesetzten Haltepunkte verknüpft, sodass beim Rückgängigmachen der frühere Haltepunktstatus wiederhergestellt wird.
- Wenn Sie während der Ausführung einen Haltepunkt in einer rekursiven Routine setzen, gilt er nur für die aktuelle und alle neuen tieferen Aufrufstapelebenen, nicht für äußere Ebenen.
Ausgabefenster (Output Console Window)
Durch Aktivieren des Kontrollkästchens „Output to window" öffnet sich ein Textfenster, das alle Ausgaben und Eingaben protokolliert.

Zu Beginn der Ausführung wird jeder frühere Inhalt gelöscht; eine automatisch erzeugte Meta-Zeile nennt das ausgeführte Programm (oder die Routine der obersten Ebene) und zeigt Startdatum und -zeit (in hellgrauen Buchstaben). Bei Beendigung der Ausführung erscheint eine ähnliche Meta-Zeile mit der Beendigungszeit. Ab Version 3.32-35 wird das Datum im ISO-Format (YYYY-MM-DD) angegeben und die Zeit enthält auch Sekunden und Millisekunden. Zudem werden eine geschätzte Obergrenze für die reine Rechenzeit in Millisekunden (oder Mikrosekunden bei unter 1 ms) und die Anzahl ausgeführter Basisoperationen angezeigt.
Im Protokollfenster können keine Eingaben gemacht oder bearbeitet werden. Eingabeanweisungen werden immer über ein interaktives Fragefenster ausgeführt, aber sowohl der automatisch erzeugte Eingabeaufforderungstext (in gelber Farbe) als auch die Eingabe selbst (in grüner Farbe) werden hier protokolliert. Reguläre Ausgaben des Algorithmus werden in weißer Farbe dargestellt. Jede Ausgabeanweisung erzeugt eine neue Zeile.

Wenn das Kontrollkästchen „Output to window" nicht ausgewählt ist, bleibt das Fenster verborgen, existiert aber im Hintergrund und sammelt die ausgedruckten Texte. Dabei gibt es einen wichtigen Unterschied:
- Im deaktivierten Modus öffnet jede Ausgabeanweisung ein Meldungsfenster, das bestätigt werden muss; die Ausgabe wird zusätzlich im Hintergrund protokolliert.
- Mit aktiviertem „Output to window" werden alle Ausgaben nur in das sichtbare Ausgabefenster geschrieben, ohne zu pausieren. Dieser Modus befreit Sie von der Notwendigkeit, jede einzelne Ausgabe zu bestätigen, und ermöglicht einen kontinuierlichen Ausführungsfluss (besonders nützlich bei Algorithmen mit viel Ausgabe).
Sie können die Ausgabeoption jederzeit während oder nach einer Ausführung ändern, ohne den Fensterinhalt zu verlieren. Wenn Sie das Fenster über dessen Schließen-Schaltfläche geschlossen haben, öffnet es sich bei der nächsten Ausgabe- oder Eingabeaktion des Algorithmus automatisch wieder.
Die Schriftart des Ausgabefensters kann über das Menü, die Tasten + und - auf dem Ziffernblock in Kombination mit Strg oder (ab Version 3.28-01) über das Mausrad bei gedrückter Strg-Taste geändert werden.

Ausführungsfehler werden ebenfalls in roter Farbe im Ausgabefenster protokolliert, nachdem sie als Fehlermeldungsfenster erschienen sind.
Über das Menü „Contents" (ab Version 3.28-07) können Sie die Protokollierung der Executor-Meta-Texte (wie Start- und Beendigungszeit, Berichte über Variablenwertmanipulationen usw.) deaktivieren. Standardmäßig ist die Protokollierung dieser Meldungen aktiviert. Alternativ können Sie ein eingerücktes Tracing von Unterdiagramm-Aufrufen aktivieren – sowohl beim Eintritt (mit Präfix „>>>") als auch beim Austritt (mit Präfix „<<<"), was besonders nützlich ist, um Rekursion zu demonstrieren.


Speichern des Fensterinhalts: Sie können jederzeit einen Abschnitt des Fensterinhalts (oder das gesamte Protokoll über StrgA) auswählen und in einen Texteditor kopieren. Bei sehr großen Protokollen kann dies fehlschlagen; verwenden Sie stattdessen den Menüpunkt „Save log ..." im Menü „Contents".
Verwendete Textfarben
| Farbe | Art der Meldungen |
|---|---|
| Weiß | Algorithmusausgabe |
| Gelb | Eingabeaufforderungen |
| Grün | Benutzereingaben |
| Grau | Start- und Beendigungsinfo, Eintritt in und Austritt aus Aufrufen |
| Cyan | Unterroutinen-Argumenteingaben und Ergebnisausgaben (wenn auf oberster Ebene ausgeführt) |
| Rot | Fehler- und Abbruchmeldungen, Wertmanipulationen in der Variablenanzeige |
Aufrufstapel (Call Stack)
Wie im Abschnitt Executor-Steuerfeld beschrieben, können Sie den Aufrufstapel anzeigen (macht natürlich nur Sinn bei Diagrammen, die – möglicherweise geschachtelte – CALLs enthalten). Durch Klick auf die Schaltfläche „Call Stack" öffnet sich das Stapelverfolgungsfenster. Dazu ist eine begonnene Ausführung erforderlich, die aktuell pausiert (z. B. durch Pause-Schaltfläche, Haltepunkt oder Einzelschrittmodus).
Die oberste Zeile stellt immer den innersten Aufruf (d. h. die aktuell ausgeführte Unterroutine) dar, die unterste Zeile (Ebene 0) steht für das initial gestartete Hauptprogramm oder die Hauptroutine. Scrollbalken werden automatisch hinzugefügt, wenn sie benötigt werden.


Einschränkungen und Probleme beim Testen
Wenn Sie versuchen, den Executor für ein Diagramm zu starten, während eine andere Debugging-Sitzung noch nicht beendet wurde, werden Sie durch ein Meldungsfenster gewarnt, dass eine Ausführung läuft. Sie haben dann zwei Möglichkeiten:

- Die ausstehende Ausführung abzubrechen, um eine neue zu starten.
- Durch Drücken von „No" abzubrechen – dadurch wird das möglicherweise ausgeblendete oder minimierte Steuerfeld in den Vordergrund geholt, sodass Sie die Ausführung leicht fortsetzen können.
Ähnliches gilt, wenn Sie versuchen, ein Diagramm zu bearbeiten, während dessen Ausführung noch aussteht (was zu einem inkonsistenten Executor-Zustand führen würde). Einige modifizierende Aktionen sind während der Ausführung einfach deaktiviert.
In sehr seltenen Fällen (z. B. nach einem unerwarteten internen Fehler) kann der Executor in einem inkonsistenten Zustand feststecken. In einem solchen Fall ist der einzige zuverlässige Ausweg, Structorizer zu schließen (nach dem Speichern aller relevanten Änderungen) und neu zu öffnen.