Der LIFO-Stapel * der Stapel-Datentyp

Moderator: MVogt

Post Reply
User avatar
Theo_Gottwald
Posts: 367
Joined: 03. Oct 2009, 08:57
Location: Herrenstr.11 * 76706 Dettenheim
Contact:

Der LIFO-Stapel * der Stapel-Datentyp

Post by Theo_Gottwald » 12. Feb 2017, 13:04

Thema in Part VI: Der LIFO-Stapel.

Der "Stapel-Datentyp". Beliebig viele - beliebig große STAPEL mit dem MPR nutzen.

Funktioniert erst ab dem Update 9/2019!

****************************
d_init_stack
****************************

Um verschachtelte Ausdrücke zu parsen, ist ein Stapel-Datentyp sehr hilfreich.

Der "Stack", zu Deutsch "Stapel", ist ein sogenannter LIFO-Datentyp. Das bedeutet "Last-In-First-Out".
Dasjenige Element, welches man zuletzt hinzugefügt hat, ist dasjenige, das man zuerst wieder zurückbekommt.
Vergleichbar mit den Karten auf einem Kartenspiel. Die oberste Karte ist die letzte Karte (Last IN), die auf den Kartenstapel gepackt wurde, so ist sie automatisch die erste Karte (first out), die man von OBEN auch wieder herunternehmen kann.

Wir alle kennen solche Stapel aus dem täglichen Arbeitsleben: das Ein- und Ausgangskörbchen in jedem Büro ist solch ein Stapel.
Um solche Vorgänge script-technisch nachzubilden gibt es nun den Stapel-Datentyp.
Es gibt also nicht nur einen Stapel, sondern viele Stapel.
Um das Scripting damit übersichtlich zu gestalten, bekommen diese Stapel vom User jeweils Namen, damit diese vom System ansprechbar werden.

Hinweis: Wenn man sich z.B. vom Spielkartenstapel die oberste Karte herunternimmt, so ist diese EXKLUSIV in der Hand und auf dem Stapel steht die nächste Karte zur Verfügung. Das ist das normale Verhalten, das wir alle kennen.
Mit dem Parameter "N", kann man dafür sorgen, dass man einen Blick auf die oberste Karte erhält, diese bleibt aber liegen.
Somit hat man quasi eine Kopie der Karte vor Augen.
Um nun wirklich an die nächste Karte vom Stapel zu bekommen, muss man nun manuell dem System sagen, dass die oberste Karte gelöscht werden soll (d_del_stack_item).

Wenn man einen Stapel verwenden möchte, muss man diesen zunächst benennen. Dazu dient der folgende Befehl:

Code: Select all

GRN\d_init_stack|(Name des Stapels)|(Autodeletefunktion an/aus) durch N oder weglassen
Ab dann steht ein Stapel mit diesem Namen zur Verfügung.
Es gibt die Möglichkeit, als weiteren Parameter das "N" wie "NoAutoDelete" anzugeben.
Ist dieser Parameter gesetzt, dann wird beim Abheben eines Elementes von diesem Stack dieses Element nicht automatisch gelöscht.
Existiert ein Stack dieses Namens bereits, löscht der Befehl den Stack und setzt das "N"-Bit neu.
Nach dem Erzeugen eines Stapels, wird dieser Stapel automatisch selektiert. Das bedeutet, dass "Push" und "Pop" Befehle dann auf diesen Stapel angewendet werden.
Beispiel:

Code: Select all

GRN\d_init_stack|Loops

' Im folgenden Beispiel wird die "N" Option verwendet. 
' Bei diesem Stack werden beim Abheben die Elemente nicht automatisch gelöscht.
' Dies muss man dann explizit mit "d_del_stack_item" tun, da die N Option aktiv ist.
GRN\d_init_stack|Loops|N
****************************
d_select_stack
****************************

Zum Beispiel beim Parsen von XML genügt ein Stack nicht, man benötigt mehrere Stacks.
Um nun festzulegen, welchen der Stacks man aktuell verwendet, wird dieser Befehl benötigt.
Beispiel:

Code: Select all

GRN\d_init_stack|Loops
' Der neuerliche "d_init_stack" selektiert automatisch den Stack "Ferz"
GRN\d_init_stack|Ferz
' Nun benötigt man den Loops-Stack; also selektiert man diesen
GRN\d_select_stack|Loops

' Löscht das oberste Item von dem gerade selektierten Stack.
GRN\d_del_stack_item
' Löscht die obersten 4 Items von dem gerade selektierten Stack.
GRN\d_del_stack_item||4
****************************
d_push_on_stack
****************************

Und wie kommen die Items nun auf den Stack? Mit "d_push_on_stack" natürlich.
Die Syntax lautet:

Code: Select all

GRN\d_push_on_stack|(Item-String)[|(Item-String 2) ...
Beispiel:

Code: Select all

GRN\d_init_stack|Loops
' Wir legen drei Items auf den neu erstellten Stapel
GRN\d_push_on_stack|Line 150|Line 160|Line 170
****************************
d_pop_from_stack
****************************

Sinn macht das Ganze natürlich erst, wenn wir die Items auch wieder vom Stack zurückbekommen. Das geht mit:

Code: Select all

GRN\d_pop_from_stack>$$ITM
Man hat die Möglichkeit hier noch den Namen eines Stapels anzugeben:

Code: Select all

GRN\d_pop_from_stack|Loops>$$ITM
Dann wird das Item von diesem Stapel genommen. Der Stapel wird aber nicht selektiert.
Ein nachfolgender

Code: Select all

GRN\d_pop_from_stack>$$ITM
wird also das Item vom derzeit selektierten Stapel nehmen.

****************************
d_del_stack_item
****************************

Will man Items vom Stapel entfernen, zum Beispiel weil die Option "N" beim Deklarieren des Stacks (siehe: d_init_stack) verwendet wurde, so ist dies der Befehl der Wahl. Man kann optional noch den Namen eines Stacks und die Anzahl der Items, die gelöscht werden sollen, angeben.

Code: Select all

' Löscht das oberste Item vom aktuellen Stack
GRN\d_del_stack_item

' Löscht das oberste Item vom Stack "Loops"
GRN\d_del_stack_item|Loops
 
' Löscht die obersten 5 Items vom Stack "Loops"
GRN\d_del_stack_item|Loops|5
 
' Löscht die obersten 5 Items vom aktuell selektierten Stack
GRN\d_del_stack_item||5
Der Befehl gibt auf Wunsch die Anzahl der noch auf dem Stack verbleibenden Elemente zurück.

Code: Select all

GRN\d_del_stack_item||5>$$CNT
****************************
d_get_stack_count
****************************

Gibt die Anzahl der Elemente auf dem jeweiligen Stapel zurück. Gibt man keinen Stapelnamen an, wird der aktuelle Stapel verwendet.
Gibt man den Namen eines Stapels an, wird dieser verwendet.

Code: Select all

' Hier bezieht sich der Befehl auf den selektierten Stack
GRN\d_get_stack_count>$$CNT
' Hier bezieht sich der Befehl auf den Stack mit Namen "Loops"
GRN\d_get_stack_count|Loops>$$CNT
****************************
d_erase_stack
****************************

Diese Funktion löscht den Stack und zwar auch den Stack-Namen. Er kann danach für einen neuen Stack erneut mit "d_init_stack" verwendet werden.
Beim Beenden des Scripts werden alle Stackspeicher sowieso freigegeben, dies ist also nicht unbedingt manuell erforderlich.
Bitte bei diesem Befehl den Namen des zu löschenden Stacks stets explizit angeben.

Code: Select all

GRN\d_erase_stack|Loops

' Im Folgenden erhält $$STK die Anzahl noch deklarierter Stacks.
GRN\d_erase_stack|Loops>$$STK
Aber noch Mal der Hinweis: Die Befehls stehe nicht in der Hilfe und sind derzeit offiziell nicht vorhanden obwohl sie jeder MPR Nutzer sofort nutzen kann. Also dazu ist kein Update nötig die Befehle sind da schon drin und zwar seit Jahren.
Last edited by Theo_Gottwald on 08. Jul 2019, 11:25, edited 4 times in total.

Post Reply

Return to “Package Robot”

Who is online

Users browsing this forum: No registered users and 3 guests