#pagenr("%",40)##setcount(1)##block##pageblock# #headeven# #center#EUMEL-Benutzerhandbuch #center#____________________________________________________________ #end# #headodd# #center#TEIL 5 : Programmierung #center#____________________________________________________________ #end# #bottomeven# #center#____________________________________________________________ 5 - % #right#GMD #end# #bottomodd# #center#____________________________________________________________ GMD #right#5 - % #end# 5.3 Der Datentyp FILE (Textdateien) Der Datentyp FILE definiert Dateien von sequentieller Struktur, die Texte enthalten. Ein Objekt vom Datentyp FILE ist charakterisiert durch: 1) seine Betriebsrichtung : input = nur lesender Zugriff (TRANSPUTDIRECTION) output= nur schreibender Zugriff modify= lesender und schreibender Zugriff. 2) seinen Namen. Betriebsrichtung und Name werden in der Assoziierungsprozedur 'sequential file' (siehe Kap 2.8.2) festgelegt. ____________________________________________________________________________ ........................... Beispiel .......................... TEXT VAR name := ausgabe ; FILE VAR f := sequential file(output,name) ; ____________________________________________________________________________ Das Festlegen einer Betriebsrichtung impliziert eine Kontrolle der Benutzung der betreffenden Datei, hilft somit Programmierfehler zu vermeiden. ACHTUNG : #on("b")##on("u")#Alle#off("b")##off("u")# Prozeduren, die auf FILEs zugreifen, verlangen Objekte vom Typ FILE VAR, da die Lese/Schreiboperationen als ändernd betrachtet wer­ den (müssen). #page# 5.3.1 Assoziierung 'sequential file' #on("b")#FILE PROC sequential file (TRANSPUTDIRECTION CONST mode, DATASPACE VAR ds) #off("b")# Assoziierung einer sequentiellen Datei mit dem Dataspace 'ds' und der Betriebs­ richtung 'mode' (vergl. 'modify', 'input' bzw. 'output'). Diese Prozedur dient zur Assoziierung eines temporären Datenraums in der Benutzer-Task, der nach der Beendigung des Programmlaufs nicht mehr zugriffsfähig ist (weil der Name des Datenraums nicht mehr ansprechbar ist). Somit muß der Datenraum explizit vom Programm gelöscht werden. #on("b")#FILE PROC sequential file (TRANSPUTDIRECTION CONST mode,TEXT CONST name)#off("b")# Assoziierung einer sequentiellen Datei mit dem Namen 'name' und der Betriebs­ richtung 'mode' (vergl. 'input' bzw. 'output'). Existiert der FILE bereits, dann wird mit 'input' auf den Anfang des FILEs, bei 'output' hinter den letzten Satz der datei positioniert. Existiert dagagen der FILE noch nicht und ist die TRANSPUTDIRECTION 'output' oder 'modify', wird ein neuer FILE eingerich­ tet. FEHLER : "name" gibt es nicht" Es wurde versucht, einen nicht vorhandenen FILE mit 'input' zu asso­ ziieren. #page# 'input' #on("b")#PROC input (FILE VAR f) #off("b")# Ändern der Verarbeitungsart von 'modify' oder 'output' in 'input'. Dabei wird auf den ersten Satz der Datei positioniert. #on("b")#TRANSPUTDIRECTION CONST input #off("b")# Assoziierung in Zusammenhang mit der Prozedur 'sequential file' einer sequentiel­ len Datei mit der 'TRANSPUTDIRECTION' 'input' (nur lesen). 'output' #on("b")#PROC output (FILE VAR file) #off("b")# Ändern der Verarbeitungsart von 'input' oder 'modify' in 'output'. Dabei wird hinter den letzten Satz der Datei positioniert. #on("b")#TRANSPUTDIRECTION CONST output #off("b")# In Verbindung mit der Prozedur 'sequential file' kann eine Datei assoziiert werden mit der Betriebsrichtung 'output' (nur schreiben). 'modify' #on("b")#PROC modify (FILE VAR f) #off("b")# Ändern der Betriebsrichtung von 'input' oder 'output' in die Betriebsrichtung 'mo­ dify'. #on("b")#TRANSPUTDIRECTION CONST modify #off("b")# Diese Betriebsrichtung erlaubt das Vorwärts- und Rückwärts-Positionieren und das beliebige Einfügen und Löschen von Sätzen. 'modify' wird für die Assoziie­ rungsprozedur 'sequential file' benötigt. #page# 5.3.2 Informationsprozeduren 'eof' #on("b")#BOOL PROC eof (FILE CONST file) #off("b")# Informationsprozedur auf das Ende eines FILEs. Liefert den Wert TRUE, sofern hinter den letzten Satz eines FILEs positioniert wurde. 'line no' #on("b")#INT PROC line no (FILE CONST file) #off("b")# Liefert die aktuelle Zeilennummer. 'lines' #on("b")#PROC lines (FILE VAR f) #off("b")# Liefert die Anzahl der Zeilen der Datei 'f'. 'headline' #on("b")#TEXT PROC headline (FILE CONST f) #off("b")# Liefert den Inhalt der Kopfzeile der Datei 'f'. #on("b")#PROC headline (FILE VAR f, TEXT CONST ueberschrift) #off("b")# Setzt #ib#'ueberschrift' in die Kopfzeile#ie# der Datei 'f'. #page# 5.3.3 Betriebsrichtung INPUT In der Betriebsrichtung 'input' sind nur Leseoperationen auf der Datei zugelassen. Die Assoziierungsprozedur 'sequential file' bewirkt: 1) Falls die Eingabedatei noch nicht existiert, wird eine Fehlermeldung ausgegeben. 2) Falls es eine Datei des Namens gibt, wird auf das erste Zeichen des ersten Satzes positioniert. 'get' #on("b")#PROC get (FILE VAR f, INT VAR number) #off("b")# Lesen des nächsten Wortes aus der Datei 'f' und Konvertierung des Wortes zu einem Integer-Objekt. #on("b")#PROC get (FILE VAR f, REAL VAR number) #off("b")# Lesen des nächsten Wortes aus der Datei 'f' und Konvertierung des Wortes zu einem Real-Objekt. #on("b")#PROC get (FILE VAR f, TEXT VAR text) #off("b")# Lesen des nächsten Wortes aus der Datei 'f'. #on("b")#PROC get (FILE VAR f, TEXT VAR text, TEXT CONST delimiter)#off("b")# Lesen eines TEXT-Wertes 'text' von der Datei 'f', bis das Zeichen 'delimiter' angetroffen wird. Ein eventueller Zeilenwechsel in der Datei wird dabei übergan­ gen. #on("b")#PROC get (FILE VAR f, TEXT VAR text, INT CONST maxlength)#off("b")# Lesen eines TEXT-Wertes 'text' von der Datei 'f' mit 'maxlength' Zeichen. Ein eventueller Zeilenwechsel in der Datei wird dabei nicht übergangen. 'getline' #on("b")#PROC get line (FILE VAR file, TEXT VAR record) #off("b")# Lesen der nächsten Zeile aus der sequentiellen Datei 'file'. Mögliche Fehler bei Betriebsrichtung 'input': "Datei zu" Die Datei 'file' ist gegenwärtig nicht assoziiert. "Leseversuch nach Dateiende" Es wurde versucht, über die letzte Zeile einer Datei zu lesen. "Leseversuch auf output file" Es wurde versucht, von einem mit 'output' assoziierten FILE zu lesen. "Unzulässiger Zugriff auf modify-FILE" #page# 5.3.4 Betriebsrichtung OUTPUT In der Betriebsrichtung 'output' sind nur Schreiboperationen auf der Datei zugelassen. Die Assoziierungsprozedur 'sequential file' bewirkt: 1) Falls die Ausgabedatei noch nicht existiert, wird sie angelegt und auf den ersten Satz positioniert. 2) Falls es bereits eine Datei des Namens gibt, wird hinter den letzten Satz positio­ niert, die Datei wird also fortgeschrieben. 'put' #on("b")#PROC put (FILE VAR f, INT CONST number) #off("b")# Ausgabe eines INT-Wertes 'number' in die Datei 'f'. Dabei wird ein Leerzeichen an die Ausgabe angefügt. #on("b")#PROC put (FILE VAR f, REAL CONST number) #off("b")# Ausgabe eines REAL-Wertes 'number' in die Datei 'f'. Dabei wird ein Leerzei­ chen an die Ausgabe angefügt. #on("b")#PROC put (FILE VAR f, TEXT CONST text) #off("b")# Ausgabe eines TEXT-Wertes 'text' in die Datei 'f'. Dabei wird ein Leerzeichen an die Ausgabe angefügt. 'putline' #on("b")#PROC putline (FILE VAR file, TEXT CONST record) #off("b")# Ausgabe eines TEXTes 'record' in die Datei 'file'. Danach wird auf die nächste Zeile positioniert. 'file' muß mit 'output' assoziiert sein. 'write' #on("b")#PROC write (FILE VAR f, TEXT CONST text) #off("b")# Schreibt 'text' in die Datei 'f' (analog 'put (f, text)'), aber ohne Trennblank. 'line' #on("b")#PROC line (FILE VAR file) #off("b")# Positionierung auf die nächste Zeile der Datei 'file'. Wird versucht, über das Ende eines mit 'input' assoziierten FILEs zu positionieren, wird keine Aktion vorgenom­ men. #on("b")#PROC line (FILE VAR file, INT CONST lines) #off("b")# Positionierung mit 'lines' Zeilen Vorschub in der Datei 'file'. FEHLER: "Datei zu!" Die Datei 'file' ist gegenwärtig nicht assoziiert. "Schreibversuch auf input-File" Es wurde versucht, auf einen mit 'input' assoziierten FILE zu schreiben. Bei Textdateien, die mit dem Editor weiterbearbeitet werden sollen, ist also zu beachten: ine Ausgabe mit 'put' setzt ein 'blank' hinter die Ausgabe. Falls dieses Leerzeichen das letzte Zeichen in der Zeile ist, wird eine Absatzmarke in der Zeile gesetzt. Wird mit 'write' oder 'putline' ausgegeben, steht kein Leerzeichen und somit keine Absatzmarke am Zeilenende. #page# 5.3.5 Betriebsrichtung MODIFY In der Betriebsrichtung 'modify' sind Lese- und Schreiboperationen auf der Datei zugelassen. Desweiteren ist beliebiges Positionieren in der Datei erlaubt. Neue Sätze können an beliebiger Stelle in die Datei eingefügt werden, die sequentielle Struktur der Datei bleibt erhalten. Die Assoziierungsprozedur 'sequential file' bewirkt: 1) Falls die Ausgabedatei noch nicht existiert, wird sie angelegt. 2) Falls es bereits eine Datei des Namens gibt, ist undefiniert wo positioniert ist. Die erste Positionierung muß explizit vorgenommen werden! 'col' #on("b")#PROC col (FILE VAR f, INT CONST position) #off("b")# Positionierung auf die Spalte 'position' innerhalb der aktuellen Zeile. #on("b")#INT PROC col (FILE CONST f) #off("b")# Liefert die aktuelle Position innerhalb der aktuellen Zeile. 'down' #on("b")#PROC down (FILE VAR f) #off("b")# Positionieren um eine Zeile vorwärts. #on("b")#PROC down (FILE VAR f, INT CONST number) #off("b")# Positionieren um 'number' Zeilen vorwärts. 'to line' #on("b")#PROC to line (FILE VAR f, INT CONST number) #off("b")# Positionierung auf die Zeile 'number'. 'up' #on("b")#PROC up (FILE VAR f) #off("b")# Positionieren um eine Zeile rückwärts. #on("b")#PROC up (FILE VAR f, INT CONST number) #off("b")# Positionieren um 'number' Zeilen rückwärts. #page# 'delete record' #on("b")#PROC delete record (FILE VAR file) #off("b")# Der aktuelle Satz der Datei 'file' wird gelöscht. Der folgende Satz wird der aktuelle Satz. 'insert record' #on("b'PROC insert record (FILE VAR file) #off("b")# Es wird ein leerer Satz in die Datei 'file' vor die aktuelle Position eingefügt. Dieser Satz kann anschließend mit 'write record' beschrieben werden (d.h. der neue Satz ist jetzt der aktuelle Satz). 'read record' #on("b")#PROC read record (FILE CONST file, TEXT VAR record) #off("b")# Liest den aktuellen Satz der Datei 'file' in den TEXT 'record'. Die Position wird dabei nicht verändert. 'write record' #on("b")#PROC write record (FILE VAR file, TEXT CONST record) #off("b")# Schreibt einen Satz in die Datei 'file' an die aktuelle Position. Dieser Satz muß bereits vorhanden sein, d.h. mit 'write record' kann keine leere Datei beschrieben werden, sondern es wird der Satz an der aktuellen Position überschrieben. Die Position in der Datei wird nicht verändert. #page# 5.3.6 FILE -Ausschnitte Ähnlich den Editorfunktionen 'ESC RUBOUT' und 'ESC RUBIN', die erlauben ganze Abschnitte einer Datei zu löschen und das Gelöschte an anderer Stelle wiedereinzu­ fügen, gibt es die Möglichkeit per Programm solche Segmente eines 'modify-FILEs' zu verschieben. 'clear removed' #on("b")#PROC clear removed (FILE VAR f) #off("b")# Das mit 'remove' entfernte Segment wird gelöscht und nicht an anderer Stelle eingefügt. 'reinsert' #on("b")#PROC reinsert (FILE VAR f) #off("b")# Das mit 'remove' entfernte Segment wird vor die aktuelle Zeile wiedereingefügt. 'remove' #on("b")#PROC remove (FILE VAR f, INT CONST size) #off("b")# Löscht 'size' Zeilen vor der aktuellen Position aus 'f'. Das Segment wird in einen internen Puffer geschrieben. 'reorganize' #on("b")#PROC reorganize (TEXT CONST datei)#off("b")# Reorganisation von 'datei'. Die durch Löschen und Einfügen aus vielen Segmenten bestehende Datei wird zu einem Segment zusammengefügt, die aktuelle Position ist danach das erste Zeichen der ersten Zeile. Durch diese Prozedur kann ggf. Speicherplatz gespart werden. #on("b")#PROC reorganize#off("b")# Reorganisation der zuletzt bearbeiteten Datei. 'segments' #on("b")#PROC segments (FILE VAR f) #off("b")# Liefert die Anzahl der Segmente von 'f'. Eine große Anzahl von Segmenten kann langsamere Zugriffe zur Folge haben. #page# 5.4 Suchen und Ersetzen in Textdateien Such- und Ersetzungsprozeduren können sowohl interaktiv beim Editieren (siehe dazu 3.3), als auch in Prozeduren, die auf FILEs (siehe 5.3) arbeiten, angewandt werden. Die dazu dienenden Prozeduren sind im Paket 'pattern match' enthalten. Mit 'Pattern Matching' (Muster treffen) wird ein Verfahren bezeichnet Gleichheit von Objekten anhand von Regeln, denen diese Objekte genügen, zu überprüfen. Da oft nach Texten gesucht werden muß, deren genaue Ausprägung nicht bekannt ist, oder deren Auftreten nur in einem bestimmten Zusammenhang interessiert, gibt es die Möglichkeit feststehende Textelemente mit Elementen ungewisser Ausprägung zu kombinieren, also Textmuster zu erzeugen. Um einen Text zu suchen, muß die Suchrichtung und der gesuchte Text oder ein Muster, welches diesen Text beschreibt, angegeben werden. - Aufbauen von Textmustern : + , - , OR , any , bound , notion - Suchen nach Textmustern : down , downety , up , uppety - Treffer registrieren : LIKE , UNLIKE , at , pattern found - Treffer herausnehmen : ** , match , matchend , matchpos , somefix , word - Ändern in Dateien : change Nach einem erfolgreichen Suchvorgang ist stets auf das erste Zeichen der zu such­ enden Zeichenkette positioniert. Eine besondere Funktion kommt dem 'joker' zu: Dieses Symbol (Defaultwert: '*') steht für eine beliebige Zeichenkette beliebiger Länge. Insbesondere bei Ersetzungsaktionen in denen dieses Zeichen zur Musterbeschreibung verwendet wird, ist daher Vorsicht geboten und sorgfältig zu testen. #page# 5.4.1 Aufbau von Textmustern '+' #on("b")#TEXT OP + (TEXT CONST links, rechts) #off("b")# Verkettung der Texte 'links' und 'rechts' zu 'linksrechts'. Falls das Ergebnis länger als die maximal zulässige Textlänge ist, ist es undefiniert. Wenn 'muster1' einen beliebigen Text finden sollte, ( Siehe: PROC any) wird das Ende des von 'muster1' erkannten Textes durch den Anfang des von 'muster2' erkannten Textes im Nachhinein definiert. '-' #on("b")#TEXT OP - (TEXT CONST alphabet) #off("b")# Der Operator liefert das zu 'alphabet' komplementäre Alphabet, also alle Zeichen gemäß der EUMEL Codetabelle (5.2.4), die nicht in 'alphabet' enthalten sind. Sinnvoll im Zusammenhang mit der Textprozedur 'any'. 'OR' #on("b")#TEXT OP OR (TEXT CONST links, rechts) #off("b")# Liefert die Alternative von 'links' und 'rechts'. Die Reihenfolge spielt beim Suchen keine Rolle. 'any' Die Textprozedur 'any' liefert einen unbekannten Text unbestimmter Länge. Dieser Text sollte entweder durch festen Text sinnvoll eingegrenzt werden, oder direkt eingeschränkt werden. #on("b")#TEXT PROC any #off("b")# Beschreibt einen beliebigen Text. #on("b")#TEXT PROC any (INT CONST laenge) #off("b")# Beschreibt einen beliebigen Text der angebenen Länge. #on("b")#TEXT PROC any (TEXT CONST alphabet) #off("b")# Beschreibt einen beliebigen Text, der nur aus Zeichen besteht, die in 'alphabet' enthalten sind. #on("b")#TEXT PROC any (INT CONST laenge, TEXT CONST alphabet) #off("b")# Beschreibt einen Text der vorgegebenen Länge, der nur aus den in 'alphabet' vorgegebenen Zeichen besteht. ____________________________________________________________________________ ........................... Beispiel .......................... Die Textprozedur 'any' liefert einen unbekannten Text unbe­ stimmter Länge. Dieser Text sollte entweder durch festen Text sinnvoll eingegrenzt werden, oder direkt eingeschränkt werden. gib kommando: D("D" OR "d" + any (2,"aeirs") Sucht nach bestimmten Artikeln: 'der', 'die', 'das' etc. ____________________________________________________________________________ 'bound' #on("b")#TEXT PROC bound #off("b")# Bezeichnet ein Muster der Länge null, das nur am Zeilenanfang oder am Zeilenen­ de gefunden wird. Ein Präfix 'bound' fordert, daß das gesuchte Muster in der ersten Spalte beginnen muß, ein Postfix 'bound' fordert, daß das Muster mit dem Zeilenende abschließt. ____________________________________________________________________________ ........................... Beispiel .......................... Die Textprozedur 'any' liefert einen unbekannten Text unbe­ stimmter Länge. Dieser Text sollte entweder durch festen Textsinnvoll eingegrenzt werden, oder direkt eingeschränkt werden. gib kommando: U(bound + any (" ")) ____________________________________________________________________________ liefert Treffer bei eingerückten Zeilen. 'notion' #on("b")#PROC notion (TEXT CONST suchwort) #off("b")# Mit dieser Prozedur kann ein #on("u")#Wort#off("u")# spezifiziert werden, nach dem gesucht werden soll. Bei der Suche nach 'suchwort' wird nur dann ein Treffer geliefert, wenn 'suchwort' als Wort, also begrenzt von ' ' (blank), '.' , ',' oder anderen Sonderzei­ chen ist. #on("b")#PROC notion (TEXT CONST suchwort, INT CONST reg) #off("b")# Wie oben, der Treffer wird im Register 'reg' gespeichert. #page# 5.4.2 Suche nach Textmustern 'down' #on("b")#PROC down (FILE VAR f, TEXT CONST muster) #off("b")# Suche nach 'muster' in der Datei 'f' in Richtung Dateiende. Wird 'muster' gefun­ den, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man hinter dem letzten Zeichen der Datei. Achtung: 'down' sucht vom nächsten Zeichen rechts ab, so daß wiederholtes Suchen keine Endlosschleife ergibt. #on("b")#PROC down (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")# Wie obiges 'down', es wird aber maximal nur 'number'-Zeilen weit nach 'muster' gesucht. 'downety' #on("b")#PROC downety (FILE VAR f, TEXT CONST muster) #off("b")# Suche nach 'muster' in der Datei 'f' in Richtung Dateiende. Wird 'muster' gefun­ den, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man auf dem letzten Zeichen der Datei. Achtung: 'downety' sucht (im Gegensatz zu 'down') vom aktuellen Zeichen an. Daher muß explizit vorwärts positioniert werden. #on("b")#PROC downety (FILE VAR f, TEXT CONST muster, INT CONST number) #off("b")# Wie obiges 'downety', aber maximal nur 'number'-Zeilen weit. #page# 'up' #on("b")#PROC up (FILE VAR f, TEXT CONST muster) #off("b")# Suche nach 'muster' in der Datei 'f' in Richtung Dateianfang. Wird 'muster' gefunden, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man auf dem ersten Zeichen der Datei. Achtung: 'up' sucht vom nächsten Zeichen links ab, so daß wiederholtes Suchen keine Endlosschleife ergibt. #on("b")#PROC up (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")# Wie obiges 'up', aber maximal nur 'number'-Zeilen weit. 'uppety' #on("b")#PROC uppety (FILE VAR f, TEXT CONST muster) #off("b")# Suche nach 'muster' in der Datei 'f' in Richtung Dateianfang. Wird 'muster' gefunden, ist die Position das erste Zeichen von 'muster'. Andernfalls steht man auf dem ersten Zeichen der Datei. Achtung: 'uppety' sucht (im Gegensatz zu 'up') vom aktuellen Zeichen. #on("b")#PROC uppety (FILE VAR f, TEXT CONST muster, INT CONST number)#off("b")# Wie obiges 'uppety', aber maximal nur 'number'-Zeilen weit. #page# 5.4.3 Treffer registrieren 'LIKE' #on("b")#BOOL OP LIKE (TEXT CONST text , muster) #off("b")# Liefert TRUE, falls der Text 'text' 'muster' entspricht. In 'muster' kann das Spezialzeichen '*' verwandt werden, das abkürzend für die Konkatenation mit 'any' steht. Daraus folgt, daß das Suchen oder Ersetzen des Zeichens '*' nur durch any (1,"*") zu bewerkstelligen ist. ____________________________________________________________________________ ........................... Beispiel .......................... \#Druckdateien aus Thesaurus löschen\# gib kommando:"*.p" C "" 16.04.87 "Handbuch teil1" 04.05.87 "Handbuch teil1.p" 16.04.87 "Handbuch teil2" 06.05.87 "Handbuch teil2.p" ____________________________________________________________________________ aber: ____________________________________________________________________________ ........................... Beispiel .......................... \#Vordere Kommentarklammern löschen \# gib kommando:"(" + any(1,"*") C "" lernsequenz auf taste legen("a" , "archive") ; (* lernsequenz auf taste legen("(" , ""91"") ; *) (* lernsequenz auf taste legen(")" , ""93"") ; *) kommando auf taste legen("P" , "print("""")"8""8""11"") . ____________________________________________________________________________ 'UNLIKE' #on("b")#BOOL OP UNLIKE (TEXT CONST text , muster) #off("b")# Wirkt wie: '(NOT text LIKE muster)' #page# 5.4.4 Treffer herausnehmen Mit Hilfe der 'Register' ist es möglich identifizierte Texte zwischenzuspeichern und in weiteren Aktionen weiterzuverwenden. '**' #on("b")#TEXT OP ** (TEXT CONST muster, INT CONST register)#off("b")# Der als 'muster' erkannte Text wird einem 'Register' mit der Nummer 'register' zugeordnet. Es können 256 Register (1 bis 256) benutzt werden. 'match' #on("b")#TEXT PROC match (INT CONST nr) #off("b")# Liefert den Text der dem Register 'nr' zuletzt zugeordnet wurde. 'matchpos' #on("b")#INT PROC matchpos (INT CONST nummer) #off("b")# Liefert die Spaltennummer, auf der das dem Register 'nummer' zugeordnete Mu­ ster in der Zeile beginnt. ____________________________________________________________________________ ........................... Beispiel .......................... gib kommando:D("file"+any+"("+(any ** (1)... ____________________________________________________________________________ #page# 5.4.5 Ändern in Dateien 'change' #on("b")#PROC change (FILE VAR datei, INT CONST von, bis , TEXT CONST neuertext)#off("b")# In der Datei wird in der aktuellen Zeile in den Ausschnitt zwischen 'von' und 'bis' der Text 'neuertext' eingesetzt. entspricht: ____________________________________________________________________________ ........................... Beispiel .......................... FILE VAR file := sequential file (modify, name) TEXT VAR zeile; . . read record (file ,zeile); change (zeile, von, bis ,"neuertext"); write record (file, zeile); . ____________________________________________________________________________ #page# 5.4.6 Editor-Prozeduren 'edit' #on("b")#edit (TEXT CONST datei)#off("b")# Editieren der Datei 'datei'. Das Editorfenster ist maximal groß (von 1,1 bis max,max). Der Standard-Kommandointerpreter ist gültig, so daß Eingaben, die mit #schl("ESC")# beginnen, interpretiert werden, wie in 3.4 'Vorbelegte Tasten' beschrie­ ben. #on("b")#edit#off("b")# Wie oben, editiert wird die Datei mit dem zuletzt benutzten Namen. #on("b")#edit (THESAURUS CONST thes)#off("b")# Wie oben, editiert werden alle Dateien, deren Namen im Thesaurus 'thes' enthal­ ten sind. #on("b")#edit (TEXT CONST datei, INT CONST von x, von y, bis x, bis y)#off("b")# Editieren der Datei 'datei'. Das Editorfenster hat die linke obere Ecke bei 'von x, von y' und die rechte untere Ecke bei 'bis x, bis y'. #on("b")#edit (FILE VAR f)#off("b")# Editieren der als 'sequential file' assoziierten Textdatei 'f'. #on("b")#edit (FILE VAR, INT CONST von x, von y, bis x, bis y)#off("b")# Editieren der als 'sequential file' assoziierten Textdatei in einem Fenster mit der linken, oberen Ecke 'von x, von y' und der rechten, unteren Ecke 'bis x, bis y'. #on("b")#edit (FILE VAR f, TEXT CONST res, PROC (TEXT CONST) kdo interpreter)#off("b")# Editieren der als 'sequential file' assoziierten Textdatei 'f'. In 'res' werden reser­ vierte Zeichen übergeben, die von der Prozedur 'kdo interpreter' als Kommandos interpretiert werden, wenn sie als ESC-Sequenz eingegeben werden. Beispiel : #schl("ESC ")# #schl("e")# #page# 'editget' #on("b")#editget (TEXT VAR ausgabe) #off("b")# Aufruf des Zeileneditor. An der aktuellen Cursorposition wird eine Zeile ausgegeben in der 'ausgabe' steht. Für diese Zeile stehen alle Editiermöglichkeiten zur Verfügung, 'ausgabe' kann also beliebig überschrieben, ergänzt etc. werden. Die Eingabe wird durch #schl("CR")# abgeschlossen. Im Gegensatz zur Prozedur 'get' ist auch eine leere Eingabe möglich. #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, INT CONST scroll, TEXT CONST sep, TEXT CONST res, TEXT VAR exit) #off("b")# Wie oben, die Zeilenlänge ist jedoch auf 'zeile' Zeichen begrenzt. Die Eingabe wird durch #schl("CR")# oder durch eine Cursorbewegung über die Position 'zeile' hinaus abgeschlossen. Die Angabe 'scroll' setzt die Breite des Zeilenfensters fest, wird diese Breite überschritten, so wird 'ausgabe' gerollt. In 'sep' (Separator) können Zeichen festgesetzt werden, mit denen die Eingabe beendet wird (zusätzlich zu CR !). In 'res' (reservierte Tasten) können Tasten festgelegt werden, die in Verbindung mit die Eingabe beenden. Wurde der Zeileneditor durch einen Separator verlassen, so steht in 'exit' dieses Zeichen. Falls der Zeileneditor durch eine reservierte Taste verlassen, so enthält 'exit' 'ESC' und die Taste. #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, INT CONST scroll)#off("b")# Bedeutung der Parameter siehe oben. #on("b")#editget (TEXT VAR ausgabe, TEXT CONST sep, TEXT CONST res, TEXT VAR exit) #off("b")# Bedeutung der Parameter siehe oben. #on("b")#editget (TEXT VAR ausgabe, INT CONST zeile, TEXT VAR exit) #off("b")# Bedeutung der Parameter siehe oben. #page# 5.4.7 Sortierung von Textdateien Für die Sortierung von Textdateien gibt es zwei Sortierprogramme: - Sortierung nach ASCII : sort - Sortierung nach deutschem Alphabet : lexsort 'sort' #on("b")#PROC sort (TEXT CONST datei) #off("b")# Diese Prozedur sortiert die Datei 'datei' zeilenweise gemäß der von der EUMEL Codetabelle (siehe 5.2.4) vorgegebenen Reihenfolge. Zur Sortierung werden die Zeilen vom ersten Zeichen der Zeile beginnend, zeichenweise verglichen und dementsprechend sortiert. #on("b")#PROC sort (TEXT CONST datei, INT CONST position) #off("b")# Sortierkriterien wie oben, jedoch wird bei Vergleich und Sortierung der Satz erst ab der Position 'position' beachtet. Sortiert wird der ganze Satz! 'lex sort' #on("b")#PROC lex sort (TEXT CONST datei) #off("b")# Zeilenweise Sortierung nach lexikographischer Reihenfolge gemäß DIN 5007. Zu den Vergleichen werden die Operatoren LEXEQUAL, LEXGRATER, LEXGRATEREQUAL benutzt (siehe 5.2.4). #on("b")#PROC lex sort (TEXT CONST datei, INT CONST position) #off("b")# Lexikalische Sortierung durch Vergleich ab Position 'position'. #page# 5.4.8 Prozeduren auf Datenräumen Neben den Textdateien gibt es im EUMEL-System den Typ Datenraum, der Objekte jeglichen Typs aufnehmen kann und direkten Zugriff auf die Objekte gewährt (siehe 2.9.2). Für Objekte von Type Datenraum (nicht für die in Datenräumen enthaltenen Objekte!) existieren folgende Standardprozeduren: ':=' #on("b")#OP := ( DATASPACE VAR ds1, DATASPACE CONST ds2)#off("b")# Der Datenraum 'ds1' wird als Kopie von 'ds2' angelegt. Es handelt sich zunächst um eine logische Kopie, eine physische Kopie wird erst nach einem Schreibzugriff auf 'ds1' oder 'ds2' nötig. 'new' #on("b")#DATASPACE PROC new (TEXT CONST dsname) #off("b")# Liefert einen neuen Datenraum namens 'dsname'. ____________________________________________________________________________ DATASPACE VAR ds := new ("datenraum") (* ergibt zwei Datenräume 'ds' und 'datenraum'! *) ____________________________________________________________________________ 'nilspace' #on("b")#DATASPACE PROC nilspace#off("b")# Der 'nilspace' ist ein leerer Datenraum, der ausschließlich als Quelle zum Kopie­ ren bei der Initialisierung Verwendung finden darf. 'old' #on("b")#DATASPACE PROC old (TEXT CONST dsname) #off("b")# Liefert einen bereits existierenden Datenraum (oder auch eine Datei) mit dem Namen 'dsname'. FEHLER : "dsname" gibt es nicht 'type' #on("b")#PROC type (DATASPACE CONST ds, INT CONST typ)#off("b")# Der Datenraum 'ds' erhält den frei wählbaren Schlüssel 'typ'. Es muß eine positive Zahl gewählt werden. Der Datenraum muß zum Zeitpunkt der Typzuweisung an ein BOUND Objekt gekoppelt (gewesen) sein. #on("b")#INT PROC type (DATASPACE CONST ds)#off("b")# Liefert den Schlüssel des Datenraums 'ds'. Falls 'ds' nie an ein BOUND Objekt gekoppelt war, liefert die Prozedur einen Wert < 0, sonst 0 (keine Zuweisung erfolgt) oder die zugewiesene Typnummer. 'dataspaces' #on("b")#INT PROC dataspaces (TASK CONST task) #off("b")# Liefert die Anzahl der Datenräume der Task 'task'. #on("b")#INT PROC dataspaces #off("b")# Anzahl der Datenräume von 'myself'. 'ds pages' #on("b")#INT PROC ds pages (DATASPACE CONST ds)#off("b")# Liefert die Anzahl der durch 'ds' belegten Seiten (je 512 Byte). 'storage' #on("b")#INT PROC storage (DATASPACE CONST ds)#off("b")# Liefert den von 'ds' belegten Speicherplatz in KB. #page# 'copy' #on("b")#PROC copy (DATASPACE CONST ds, TEXT CONST datei) #off("b")# Eine neue Datei mit dem Namen 'datei' wird angelegt. Der Inhalt der Datei ist eine Kopie des Inhalts des Datenraumes 'ds'. 'forget' #on("b")#PROC forget (DATASPACE CONST ds)#off("b")# Der Datenraum 'ds' wird gelöscht#u#1)#e#. #foot# 1) Durch diese Prozedur steht nicht unmittelbar mehr freier Speicherplatz zur Verfügung. Die physische Räumung von Speicherplatz erfolgt durch die 'Müllabfuhr' bei einem Fixpunkt. #end# 'fetch' #on("b")#PROC fetch (DATASPACE CONST ziel, TEXT CONST datei, TASK CONST manager) #off("b")# Aus der Task 'manager' wird der Datenraum der Datei 'datei' in den eigenen Datenraum 'ziel' kopiert. 'save' #on("b")#PROC save (DATASPACE CONST quelle, TEXT CONST datei, TASK CONST manager) #off("b")# Der eigene Datenraum 'quelle' wird in die Datei 'datei' in der Task 'manager' kopiert. #page# 5.5 Eingabe/Ausgabe - Eingabesteuerzeichen : HOP , � � � � , TAB , RUBIN , RUBOUT CR , MARK , ESC - Ausgabesteuerzeichen : HOME , � � � � , CL EOP , CL EOL CPOS , BELL , CR , ENDMARK , BEGINMARK - Positionierung : cursor , get cursor , line , page - Eingabe : get , getline , inchar , incharety - Ausgabe : cout , out , out subtext , put , putline , TIMESOUT , write - Kontrolle : online , pause , sysin , sysout - Zeitmessung : clock , date , day , hour , pause , time time of day #page# 5.5.1 E/A auf Bildschirm Steuerzeichen und Standardprozeduren zur Ein- Ausgabe am Bildschirm werden zur Steuerung des Dialogverhaltens von Prozeduren benutzt. 5.5.1.1 Eingabesteuerzeichen Eingabesteuerzeichen werden durch die Funktionstasten (s. 3.2) erzeugt. Die Wirkung der Tasten ist ebenfalls an dieser Stelle beschrieben. Durch die Tasten werden folgende Codes an Programme gegeben: Codierung I Bezeichnung -----------+-------------- HOP I 1 RECHTS I 2 OBEN I 3 LINKS I 8 TAB I 9 UNTEN I 10 RUBIN I 11 RUBOUT I 12 CR I 13 MARK I 16 ESC I 27 #page# 5.5.1.2 Ausgabesteuerzeichen Die Ausgabe dieser Zeichen bewirkt folgendes Verhalten der Bildschirmausgabe. Code I Name I Wirkung -----+-------------+------------------------------------------------------- 0 I NUL I keine Wirkung 1 I HOME I Cursor in die linke obere Ecke setzen (Position 0,0!) 2 I RECHTS I Cursor eine Stelle nach rechts setzen 3 I OBEN I Cursor eine Zeile höher setzen 4 I CL EOP I Rest der Seite löschen 5 I CL EOL I Rest der Zeile löschen 6 I CPOS I Cursor setzen, nächstes Ausgabezeichen bestimmt die I I y-Position, das darauf folgende die x-Position. 7 I BELL I akustisches Signal 8 I LINKS I Cursor eine Stelle nach links setzen 10 I UNTEN I Cursor eine Stelle nach unten setzen 13 I CR I Cursor an den Anfang der nächsten Zeile setzen 14 I ENDMARK I Ende des markierten Bereichs 15 I BEGINMARK I Anfang des markierten Bereichs ____________________________________________________________________________ ........................... Beispiel .......................... TEXT VAR ausgabe := (""7""15"V O R S I C H T"14"7""); out(ausgabe); ____________________________________________________________________________ #page# 5.5.1.3 Positionierung 'cursor' #on("b")#PROC cursor (INT CONST column, row) #off("b")# Positioniert den Cursor auf dem Bildschirm, wobei 'column' die Spalte und 'row' die Zeile angibt. Die zulässigen Bereiche von 'column' und 'row' sind geräteab­ hängig. 'get cursor' #on("b")#PROC get cursor (INT VAR x, y) #off("b")# Erfragung der aktuellen Cursor-Position. Die Koordinaten des Cursors werden in 'x' und 'y' geliefert. Die aktuelle Cursor-Position ist nach Ausgabe von 'HOME' (Code = 1) oder einer Positionierung des Cursors mit der Prozedur 'cursor' stets definiert. Die Prozedur 'get cursor' liefert jedoch undefinierte Werte, wenn über den rechten Rand einer Zeile hinausgeschrieben wurde (die Wirkung einer solchen Operation hängt von der Hardware eines Terminals ab). 'line' #on("b")#PROC line #off("b")# Es wird zum Anfang einer neuen Zeile positioniert. #on("b")#PROC line (INT CONST number) #off("b")# Es werden 'number' Zeilenwechsel vorgenommen. 'page' #on("b")#PROC page #off("b")# Es wird zum Anfang einer neuen Seite positioniert (hier: linke obere Ecke (Position 1,1 !) des Bildschirms, wobei der Bildschirm gelöscht wird). #page# 5.5.1.4 Eingabe Grundlegende Prozeduren Die folgenden Prozeduren dienen ausschließlich der Eingabe vom Terminal. 'editget' Siehe 5.4.6 'getchar' #on("b")#PROC getchar (TEXT VAR zeichen)#off("b")# Liest genau ein Zeichen von der Tastatur und schreibt es in die Variable 'zeichen'. 'inchar' #on("b")#PROC inchar (TEXT VAR character) #off("b")# Wartet solange, bis ein Zeichen von der Tastatur eingegeben wird, und schreibt dieses Zeichen in die Variable 'character'. 'incharety' #on("b")#TEXT PROC incharety #off("b")# Versucht, ein Zeichen von der Tastatur zu lesen. Wurde kein Zeichen eingegeben, wird niltext geliefert. #on("b")#TEXT PROC incharety (INT CONST time limit) #off("b")# Versucht, ein Zeichen vom Bildschirm zu lesen. Dabei wird maximal eine 'time limit' lange Zeit auf das Zeichen gewartet (gemessen in Zehntel-Sekunden). #page# Umleitbare Eingabeprozeduren Die folgenden Eingabeprozeduren lesen ebenfalls vom Terminal, die Eingabequelle kann jedoch durch die Prozedur 'sysin' umgestellt werden. Falls in 'sysin' eine Datei angegeben wird wird die Eingabe statt vom Terminal aus dieser Datei gelesen. 'sysin' #on("b")#PROC sysin (TEXT CONST file name) #off("b")# Eingabe-Routinen lesen nicht mehr vom Benutzer-Terminal, sondern aus der Datei 'file name'. #on("b")#TEXT PROC sysin #off("b")# Liefert den Namen der eingestellten 'sysin'-Datei. "" bezeichnet das Benutzer- Terminal. 'get' #on("b")#PROC get (INT VAR number) #off("b")# Einlesen eines INT-Wertes vom Bildschirm. Der einzulesende INT-Wert kann bei der Eingabe vom Terminal editiert werden. #on("b")#PROC get (REAL VAR value) #off("b")# Einlesen eines REAL-Wertes vom Bildschirm. Der einzulesende REAL-Wert kann bei der Eingabe vom Terminal editiert werden. #on("b")#PROC get (TEXT VAR word) #off("b")# Liest einen Text in die Variable 'word' mit maximal 255 Zeichen. Es werden solange Zeichen vom Terminal gelesen, bis ein Leerzeichen oder #schl("CR")# eingegeben wird. Dabei werden führende Leerzeichen übergeben. Der einzulesende Text kann bei der Eingabe editiert werden. Eine leere Eingabe ist nicht erlaubt. #on("b")#PROC get (TEXT VAR word, INT CONST laenge) #off("b")# Liest einen Text vom Bildschirm mit der Länge 'laenge' oder bis #schl("CR")# eingegeben wird. Der einzulesende Wert kann bei der Eingabe editiert werden. #on("b")#PROC get (TEXT VAR word, TEXT CONST separator) #off("b")# Liest einen Text vom Bildschirm, bis ein Zeichen 'separator' angetroffen oder #schl("CR")# eingegeben wird. Der einzulesende Text kann bei der Eingabe editiert werden. 'getline' #on("b")#PROC get line (TEXT VAR line) #off("b")# Das System wartet auf eine Zeile vom Bildschirm (max. 255 Zeichen). #schl("CR")# been­ det die Eingabe. #page# 5.5.1.5 Ausgabe Grundlegende Prozeduren Die folgenden Prozeduren dienen ausschließlich der Ausgabe auf das Terminal. 'cout' #on("b")#PROC cout (INT CONST number) #off("b")# Schreibt 'number' an die aktuelle Cursor-Position auf den Bildschirm. Anschlie­ ßend wird an diese Position wieder zurück positioniert. 'number' muß > 0 sein. Paßt 'number' nicht mehr auf die Zeile, so ist die Wirkung von 'cout' nicht de­ finiert. 'cout' gibt den Wert von 'number' nur aus, wenn genügend freie Kanal- Kapazität für diese Ausgabe vorhanden ist. Das hat zur Folge, daß Programme nicht auf die Beendigung einer Ausgabe von 'number' warten müssen und ggf. Ausgaben überschlagen werden. 'out' #on("b")#PROC out (TEXT CONST text) #off("b")# Ausgabe eines Textes auf dem Bildschirm. Im Unterschied zu 'put' wird kein Blank an den ausgegebenen Text angefügt. 'out subtext' #on("b")#PROC out subtext (TEXT CONST source, INT CONST from) #off("b")# Ausgabe eines Teiltextes von 'source' von der Position 'from' bis Textende. Es wird keine Aktion vorgenommen für from > LENGTH source #on("b")#PROC out subtext (TEXT CONST source, INT CONST from, to)#off("b")# Ausgabe eines Teiltextes von 'source' von der Position 'from' bis zur Position 'to'. Für to > LENGTH source wird out subtext (source, from) ausgeführt. #on("b")#PROC out text (TEXT CONST source, INT CONST from, to) #off("b")# Ausgabe eines Teiltextes von 'source' von der Position 'from' bis zur Position 'to'. Für to > LENGTH source wird für die fehlenden Zeichen Blanks ausgegeben. 'TIMESOUT' #on("b")#OP TIMESOUT (INT CONST times, TEXT CONST text) #off("b")# Ausgabe eines TEXTes 'text' 'times'mal. An die Ausgabe wird im Gegensatz zu 'put' kein Leerzeichen angefügt. Es wird kein Text ausgegeben für times < 1 #page# Umleitbare Ausgabeprozeduren Die folgenden Ausgabeprozeduren schreiben ebenfalls auf das Terminal, die Ausgabe kann jedoch durch die Prozedur 'sysout' umgeleitet werden. Falls in 'sysout' eine Datei angegeben wird wird die Ausgabe statt zum Terminal in die angegebene Datei geleitet. 'sysout' #on("b")#PROC sysout (TEXT CONST file name) #off("b")# Ausgabe-Routinen gehen nicht mehr zum Benutzer-Terminal, sondern in die Datei 'file name'. #on("b")#TEXT PROC sysout #off("b")# Liefert den Namen der eingestellten 'sysout'-Datei. "" bezeichnet das Benut­ zer-Terminal. 'line' #on("b")#line#off("b")# Positionierung auf den Anfang einer neuen Ausgabezeile. #on("b")#line (INT CONST faktor)#off("b")# Nächste Ausgabezeile um 'faktor' Zeilen weiter positionieren. 'put' #on("b")#PROC put (INT CONST number) #off("b")# Ausgabe eines INT-Wertes auf dem Bildschirm. Anschließend wird ein Leer­ zeichen ausgegeben. #on("b")#PROC put (REAL CONST real) #off("b")# Ausgabe eines REAL-Wertes auf dem Bildschirm. Anschließend wird ein Leer­ zeichen ausgegeben. #on("b")#PROC put (TEXT CONST text) #off("b")# Ausgabe eines Textes auf dem Bildschirm. Nach der Ausgabe von 'text' wird ein Blank ausgegeben, um nachfolgenden Ausgaben auf der gleichen Zeile voneinan­ der zu trennen. Hardwareabhängig sind die Aktionen, wenn eine Ausgabe über eine Zeilengrenze (hier: Bildschirmzeile) vorgenommen wird. Meist wird die Ausga­ be auf der nächsten Zeile fortgesetzt. 'putline' #on("b")#PROC putline (TEXT CONST text) #off("b")# Ausgabe von 'text' auf dem Bildschirm. Nach der Ausgabe wird auf den Anfang der nächsten Zeile positioniert. Gibt man TEXTe nur mit 'putline' aus, so ist gesichert, daß jede Ausgabe auf einer neuen Zeile beginnt. Hardwareabhängig sind die Aktionen, wenn eine Ausgabe über eine Zeilengrenze (hier: Bildschirm­ zeile) vorgenommen wird. Meist wird die Ausgabe auf der nächsten Zeile fort­ gesetzt. 'write' #on("b")#PROC write (TEXT CONST text) #off("b")# Gibt 'text' ohne Trennblank aus ('put' mit Trennblank). #page# 5.5.1.6 Kontrolle 'online' #on("b")#BOOL PROC online #off("b")# Liefert TRUE, wenn die Task mit einem Terminal gekoppelt ist. 'pause' #on("b")#PROC pause (INT CONST time limit) #off("b")# Wartet 'time limit' in Zehntel-Sekunden. Bei negativen Werten ist die Wirkung nicht definiert. Die Wartezeit wird nicht nur durch das Erreichen der Grenze ab­ gebrochen, sondern auch durch die Eingabe eines beliebigen Zeichens. #on("b")#PROC pause#off("b")# Wartet bis zur Eingabe eines beliebigen Zeichens. #page# 5.5.2 Zeitmessung 'clock' #on("b")#REAL PROC clock (INT CONST index) #off("b")# Datum und Uhrzeit werden vom EUMEL-System für alle Tasks geführt. Neben einer Uhr ('Realzeituhr'), die das Datum und die aktuelle Uhrzeit enthält, wird eine Uhr für die von der Task verbrauchte CPU-Zeit geführt ('CPU-Zeituhr'). Beide Zeiten werden vom System als REALs realisiert. Die Prozedur 'clock' liefert die aktuellen Werte dieser Uhren. Bei 'index = 0' wird die akkumulierte CPU-Zeit der Task, bei 'index = 1' der Wert der Realzeituhr geliefert. Mit den REAL-Werten der Uhren kann ohne weiteres gerechnet werden, jedoch sind nur Werte > 0 definiert. Die REAL-Werte der Realzeituhr beginnen beim 1.1.1900 um 0 Uhr. Es sind nur Werte für dieses Jahrhundert zugelassen. Werte der Realzeituhr in lesbarer Form kann man durch die Konvertierungsprozeduren 'date' (vergl. 5- #topage("date")# ) (für den aktuellen Tag) und 'time of day' (Uhrzeit, vergl. 5-#topage("time")#) erhalten. Um die benötigte CPU-Zeit eines Programms zu berechnen, muß man die CPU-Zeituhr zweimal abfragen. Um solche Zeiten in lesbarer Form zu erhalten, kann man die Konvertierungsprozedur 'time' (vergl. 5- #topage("time")#) verwenden. Beispiel: ____________________________________________________________________________ ........................... Beispiel .......................... REAL CONST anfang :: clock (0); berechnungen; REAL CONST ende :: clock (0); put ("benoetigte CPU-Zeit in Sek:"); put (time (ende - anfang)) ____________________________________________________________________________ #page# 'date' #goalpage("date")# #on("b")#TEXT PROC date (REAL CONST time) #off("b")# Konvertierungsprozedur für das Datum, welches sich aus dem Aufruf der Prozedur 'clock (1)' ergibt. Das Datum wird in der Form 'tt.mm.jj' geliefert. Beispiel: ____________________________________________________________________________ put (date (clock (1))) (* z.B.: 24.12.87 *) ____________________________________________________________________________ #on("b")#REAL PROC date (TEXT CONST datum) #off("b")# Konvertierungsprozedur für ein Datum in der Form 'tt.mm.jj'. Liefert einen REAL-Wert, wie ihn die Prozedur 'clock (1)' liefern würde. Beispiel: ____________________________________________________________________________ put (date ("24.12.87")) (* 6.273539e10 *) ____________________________________________________________________________ #on("b")#TEXT PROC date#off("b")# Liefert das Tagesdatum. Wirkt wie 'date (clock (1))', ist jedoch erheblich schneller. 'day' #on("b")#REAL CONST day #off("b")# Liefert die Anzahl der Sekunden eines Tages (86 400.0). 'hour' #on("b")#REAL CONST hour #off("b")# Liefert die Anzahl der Sekunden einer Stunde (3600.0). 'pause' #on("b")#PROC pause (INT CONST time limit) #off("b")# Wartet 'time limit' in Zehntel-Sekunden. Bei negativen Werten ist die Wirkung nicht definiert. Die Wartezeit wird nicht nur durch das Erreichen der Grenze ab­ gebrochen, sondern auch durch die Eingabe eines beliebigen Zeichens. 'time' #goalpage("time")# #on("b")#TEXT PROC time (REAL CONST time) #off("b")# Konvertierungsprozedur für die Zeiten der CPU-Zeituhr. Liefert die Zeiten in der Form 'hh:mm:ss.s'. Vergl. dazu 'clock'. #on("b")#TEXT PROC time (REAL CONST value, INT CONST laenge) #off("b")# Konvertiert die Zeit in externe Darstellung. Für die 'laenge'-Werte ergibt sich: laenge = 10 (* hh:mm:ss.s *) laenge = 12 (* hhhh:mm:ss.s *) #on("b")#REAL PROC time (TEXT CONST time) #off("b")# Konvertierungsprozedur für Texte der CPU-Zeituhr in REAL-Werte. 'time of day' #on("b")#TEXT PROC time of day (REAL CONST time) #off("b")# Konvertierungsprozedur für REALs, wie sie die Realzeituhr liefert. Es wird die Tageszeit in der Form 'hh:mm' geliefert. Beispiel: ____________________________________________________________________________ put (time of day (clock (1))) (* z.B.: 17:25 *) ____________________________________________________________________________ #on("b")#TEXT PROC time of day #off("b")# Liefert die aktuelle Tageszeit. Entspricht ____________________________________________________________________________ time of day (clock (1)) ____________________________________________________________________________ #page# 5.6 Scanner Der Scanner kann benutzt werden, um festzustellen, welche Art von Symbolen in einem TEXT enthalten sind. Die Repräsentation der Symbole müssen dabei der ELAN-Syntax entsprechen. Folgende #ib#Symbole#ie# kann der Scanner erkennen: - "tags", d.h. Namen, - "bolds", d.h. Schlüsselworte, - "number", d.h. INT oder REAL Zahlen, - Operatoren, - "delimiter", d.h. Begrenzer wie z.B. ";", - und das Ende des Scan-Textes. Der Scanner überliest Kommentare und Leerzeichen zwischen den Symbolen. Der (erste) zu verarbeitende Text muß mit der Prozedur #ib#scan#ie# in den Scanner "hineingesteckt" werden. Mit der Prozedur #ib#next symbol#ie# wird das jeweils nächste Symbol des TEXTes geholt. Am Ende wird "end of scan" und als Symbol 'niltext' geliefert. Falls innerhalb eines TEXT-Denoters oder eines Kommentars "end of scan" auftritt, wird "within text" bzw. "within comment" gemel­ det. Der Scan-Prozeß kann dann mit dem nächsten zu scannenden TEXT (der nächsten Zeile) fortgesetzt werden. Dafür wird nicht die Prozedur 'scan', sondern #ib#continue scan#ie# verwandt. Sie setzt im letzten Scan-Zustand (z.B. Kommentar oder TEXT-Deno­ ter) wieder auf, so daß auch Folgen von TEXTen (Zeilen) wie z.B. Dateien leicht gescannt werden können. Mit den Prozeduren scan (* meldet eine Datei zum scannen an *) next symbol (* holt die Symbole *) kann man auch eine Datei nach ELAN-Symbolen untersuchen. ____________________________________________________________________________ FILE VAR f :: ... ... scan (f); (* beginnt das Scanning in der nächsten Zeile *) TEXT VAR symbol; INT VAR type; REP next symbol (f, symbol, type); verarbeite symbol UNTIL type >= 7 END REP. ____________________________________________________________________________ #page# Scanner-Kommandos 'continue scan' #on("b")#PROC continue scan (TEXT CONST scan text) #off("b")# Das Scanning soll mit 'scan text' fortgesetzt werden. Falls der Scan-Vorgang beim vorigen 'scan text' innerhalb eines TEXT-Denoters oder eines Kommentars abgebrochen wurde, wird er jetzt entsprechend mit dem nächsten 'next symbol' fortgesetzt. Der erste Teil-Scan einer Folge muß aber stets mit 'scan' eingeleitet werden! 'next symbol' #on("b")#PROC next symbol (TEXT VAR symbol, INT VAR type) #off("b")# Holt das nächste Symbol. In "symbol" steht der TEXT des Symbols, so z.B. die Ziffern eines INT-Denoters. Bei TEXT-Denotern werden die führenden und abschließenden Anführungsstriche abgeschnitten. Leerzeichen oder Kommentare spielen in "tags" oder "numbers" keine Rolle. Zwischen Symbolen spielen Leer­ zeichen oder Kommentare keine Rolle. In "type" steht eine Kennzeichung für den Typ des Symbols: tag = 1 , bold = 2 , number = 3 , text = 4 , operator = 5 , delimiter = 6 , end of file = 7 , within comment = 8 , within text = 9 . Wird Scan-Ende innerhalb eines Kommentars gefunden, so wird 'niltext' und 'within comment' geliefert. Wird Scan-Ende innerhalb eines TEXT-Denoters gefunden, so wird der schon analysierte Teil des Denoters und 'within text' gelie­ fert. #on("b")#PROC next symbol (TEXT VAR symbol) #off("b")# s.o. Es wird aber nur der Text des Symbols (ohne Typ) geliefert. #on("b")#PROC next symbol (FILE VAR f, TEXT CONST symbol) #off("b")# Arbeitet wie obige Prozeduren, jedoch auf einen FILE. #on("b")#PROC next symbol (FILE VAR f, TEXT CONST symbol, INT VAR type)#off("b")# Arbeitet wie obige Prozeduren, jedoch auf einen FILE. 'scan' #on("b")#PROC scan (TEXT CONST scan text) #off("b")# Meldet einen 'scan text' für den Scanner zur Verarbeitung an. Die Prozedur 'scan' muß vor dem ersten Aufruf von 'next symbol' gegeben werden. Im Gegensatz zu 'continue scan' normiert 'scan' den inneren Zustand des Scanners, d.h. vorherige Scan-Vorgänge haben keinen Einfluß mehr auf das Scanning. #on("b")#PROC scan (FILE VAR f) #off("b")# Wie obige Prozedur, jedoch auf einen FILE. Die zu scannende Zeile ist die näch­ ste Zeile im FILE 'f' ('scan' macht zuerst ein 'getline').