ELAN ist eine Programmiersprache aus der ALGOL-Familie. Urspr�glich als Schulsprache entworfen, hat ELAN St�rken in Hinsicht auf Lesbarkeit, Sicherheit und Ausdrucksm�glichkeit. Durch Anforderungen, die im Laufe der L3 Entwicklung erwuchsen, ist jedoch die 'reine Lehre' zugunsten wichtiger Leistungen an manchen Stellen aufgeweicht worden.
Lexikalische Elemente einer Programmiersprache sind die Elemente, in denen ein Programm notiert wird.
ELAN besteht aus folgenden Elementen:
Schl�sselw�rter besitzen in ELAN eine festgelegte Bedeutung. Sie werden in Gro�buchstaben geschrieben und d�rfen keine Leerzeichen enthalten.
Beispiele:
VAR, CONST,
INT, REAL, BOOL, TEXT,
IF THEN ELSE ENDIF
Bezeichner
Bezeichner werden benutzt, um Objekte (zum Beispiel Variablen oder Prozeduren) in einem Programmtext zu benennen und zu identifizieren. Sie formulieren Bezeichner in ELAN folgenderma�en :
das ist ein langer name
x koordinate
nr 1
Falsche Bezeichner:
x*1
1 exemplar
Nr 1
Sonderzeichen
Sonderzeichen sind Zeichen, die weder Klein- oder Gro�buchstaben, noch Ziffern sind. Sonderzeichen dienen in ELAN vorrangig als Trennzeichen oder als Operatoren.
ELAN kennt folgende Trennzeichen:
! $ % & ' * + - /
< = > ? @ `
� � � � � � �
Vordefinierte Kombinationen von Sonderzeichen:
:: := <= >= <> **
Kommentare
Kommentare dienen ausschlie�lich der Dokumentation eines Programms. Sie werden vom Compiler �berlesen und haben keinen Einflu� auf die Ausf�hrung eines Programms. Kommentare k�nnen an jeder beliebigen Stelle eines Programms, au�er in Schl�sselworten und Namen, eingef�gt werden. Ein Kommentar darf mehrere Zeilen lang sein. Kommentare werden durch Kommentarklammern umschlossen:
(* *) oder { } oder # #.
Kommentare d�rfen verschachtelt sein und alle beliebigen Zeichen enthalten.
Einfache Datentypen: BOOL, INT, REAL, TEXT
F�r Datenobjekte dieser denotierbaren Datentypen gibt es eine eindeutig vorgeschriebene Werterepr�sentation:
(* INT *) 1 123 0x123fff 0b 1111 0000 1100 1010 (* REAL *) 3.14 6.123456 (* BOOL *) TRUE FALSE (* TEXT *) "das ist ein Text" "Leerer TEXT: " ""
Alle Datenobjekte m�ssen deklariert werden. Eine Initialisierung ist optional. F�r Objekte, auf die Schreib- und Leserecht erteilt wird, mu� das Zugriffsattribut VAR angegeben werden. Das Zugriffsattribut CONST f�r Objekte, auf die nur Leserecht erteilt wird, ist optional.
INT VAR i ;
REAL CONST pi := 3.1412 ;
REAL zehn :: 10.0 ;
BOOL VAR option := FALSE ;
TEXT VAR name := "Pulverm�ller" ;
TEXT nix := "" ;
Zusammengesetzte Datentypen
Anweisungen
Jede Anweisung liefert einen Wert, der auch �void� (= nichts) sein kann. Setzt sich eine Anweisung aus mehreren einzelnen zusammen, so liefert sie den Wert der letzten ausgef�hrten Anweisung.
Operatoren
Operatoren werden in ELAN durch ein oder zwei Sonderzeichen oder als Schl�sselwort (in Gro�buchstaben) dargestellt.
Als Operanden (Datenobjekte, auf die ein Operator wirken soll) d�rfen verwendet werden :
Man unterscheidet zwei Operator-Arten :
- a
NOT x
Der Operator - liefert den Wert von a mit umgekehrtem Vorzeichen. Dabei mu� a vom Datentyp INT oder REAL sein.
Der Operator NOT realisiert die logische Negation. Dabei mu� x vom Datentyp BOOL sein.
Beispiele: a, b sind beide vom Datentyp REAL bzw. INT (bei DIV nur INT) x, y sind vom Datentyp BOOL.
Priorit�t von Operatoren
Es ist erlaubt, einen Ausdruck wieder als Operanden zu verwenden. Praktisch bedeutet dies, da� Sie mehrere Operatoren und Datenobjekte zusammen in einen Ausdruck schreiben d�rfen.
Beispiele:
a + 3 - b * cDie Reihenfolge der Auswertung entspricht den folgenden Priorit�ten, wobei 9 die h�chste Priorit�t hat, d.h. zuerst ausgef�hrt wird:
- a * b
Operatoren mit gleicher Priorit�t werden von links beginnend ausgef�hrt.
Durch entsprechend gesetzte Klammern k�nnen Sie die Reihenfolge �ndern.
Beispiel:
(a + b) * (a + b)
In diesem Beispiel wird zuerst a + b ausgewertet und dann die Multiplikation durchgef�hrt. Es d�rfen auch geschachtelte Klammerungen verwendet werden. Dabei gilt: Die innerste Klammer wird immer zuerst ausgewertet. Sie d�rfen Klammern auch dort verwenden, wo keine notwendig sind. �berfl�ssige Klammernpaare werden �berlesen.
Beispiel:
((a - b)) * 3 * ((c + d) * (c - d))
Achtung: Ausdr�cke, wie z. B. (a-b) oder (d**c) und auch (a) haben immer das Zugriffsrecht CONST. Einem Ausdruck kann also kein Wert zugewiesen werden.
Beispiel f�r die Abarbeitungsfolge einer Rechnung:
-2 + 3 * 2 ** 3 a) -2 b) 2 ** 3 c) 3 * (2 ** 3) d) (-2) + (3 * (2 ** 3))
Zuweisungen
Eine Zuweisung ist eine spezielle Operation, die einen Wert in eine Variable kopiert:
Variable := Wert
Diese Operation (Zuweisung) hat immer die geringste Priorit�t. Sie wird als letzte Operation einer Anweisung ausgef�hrt. Die Zuweisung wird verwendet, um einer Variablen einen neuen Wert zuzuweisen. Der Operator := liefert keinen Wert, sondern weist einem VAR-Datenobjekt den Wert des rechts vom Operator stehenden Operanden zu:
a := b;
Hier wird der Wert von b der Variablen a zugewiesen. Der vorher vorhandene Wert von a geht dabei verloren. Der Wert wird �berschrieben.
Als rechter Operand des :=-Operators darf auch ein Ausdruck stehen:
a := b + c;
In diesem Beispiel wird das Resultat von b + c der Variablen a zugewiesen. Beachten Sie dabei die Priorit�ten der Operatoren + (Priorit�t 6) und := (Priorit�t 1): die Addition wird vor der Zuweisung ausgef�hrt.
Es kann vorkommen, da� ein Objekt auf der linken und rechten Seite des Zuweisungsoperators erscheint, z. B. dann, wenn ein Wert erh�ht werden soll.
a := a + 1;
Hier wird zun�chst der alte (aktuelle) Wert von a genommen und um 1 erh�ht. Dann wird der neue Wert der Variablen a zugewiesen.
Kontrollstrukturen
IF ... THEN ... END IF
IF ... THEN ... ELSE .... END IF
END IF kann als FI abgek�rzt werden.
IF ... THEN ...
ELSE IF ... THEN ... ELSE .... END IF
SELECT ... OF CASE 1, 4: .... CASE 5 : .... CASE 12 : .... OTHERWISE .... END SELECT
REP ... END REPAuch die Kombination ist zul�ssig. END REP kann als PER abgek�rzt werden. Die politischere �u�erung END REP sollte gerade derzeit jedoch bevorzugt werden.WHILE ... REP ... END REP
REP ... UNTIL ... END REP
FOR intvar FROM a UPTO (*DOWNTO*) b REP ... END REP
gesamtl�sung: teil a; teil b; teil c. teil a: teil a1; teil a2. teil b: teil b1; ..
INT OP ** (INT CONST basis, exp): . . IF basis <> 0 AND exp = 0 THEN LEAVE ** WITH 1 END IF . . END OP **
Prozeduren und auch Operatoren sind prinzipiell generisch, d.h. Prozeduren d�rfen gleiche Namen besitzen, wenn sie durch Anzahl und/oder Typ der Parameter unterscheidbar sind.
PROC prozedur (INT VAR par1, TEXT par2, par3):
PROC prozedur (TEXT VAR par 1, par2, par3):
Eine Prozedur kann Werte beliebigen Typs liefern.
INT PROC prozedur (TEXT par1):
STRUCT (TEXT name, vorname, INT gehalt) PROC liefere person:
Bei Werten liefernden Prozeduren ist zu beachten:
Man kann Prozeduren als Parameter �bergeben, die (ggf. leere) Parameterliste mu� angegeben werden.
PROC begin (TEXT name, PROC () startproc, TASK VAR t):
Auch monadische und dyadische Operatoren k�nnen selbst definiert werden. Der Operatortyp wird nur bei wertliefernden Operatoren angegeben.
Als Operatornamen sind erlaubt:
! $ % & ' * + - / < = > ? @ ' � � � � � � �
INT OP SIGN (REAL CONST argument): IF argument < 0.0 THEN -1 ELIF argument = 0.0 THEN 0 ELSE 1 FI END OP SIGN
Pakete
Voneinander abgegrenzte Programmteile (�Moduln�) hei�en in ELAN Pakete (PACKET). Sie bestehen aus einer Zusammenfassung von
Der formale Aufbau eines Pakets sieht folgenderma�en aus:
PACKET paketname DEFINES schnittstelle : paketrumpf END PACKET paketname
Schnittstelle ist die Liste der herausgereichten Objekte. In ihr werden Prozeduren und Operatoren nur mit ihrem Namen, durch Kommata getrennt, angegeben. Weiterhin k�nnen Datentypen und mit CONST vereinbarte Datenobjekte in der Schnittstelle aufgef�hrt werden. VAR-Datenobjekte k�nnen nicht aufgef�hrt werden, da diese sonst �ber Paket-Grenzen hinweg ver�ndert werden k�nnten.
Pakete werden zu folgenden Zwecken eingesetzt:
PACKET vertausche DEFINES swap: PROC swap (INT VAR a, b): INT CONST x :: a; b := a; a := x END PROC swap END PACKET vertausche
Das Beispiel-PACKET vertausche ist ein Paket, das eine Tausch-Prozedur f�r INT-Datenobjekte bereitstellt. Diese Prozedur hei�t swap. Das Paket kann �bersetzt und dem ELAN-Compiler bekannt gemacht werden. Dieser Vorgang wird Insertieren genannt. Ist das geschehen, kann man swap wie alle anderen Prozeduren (zum Beispiel put, get) in einem Programm verwenden. Der Quellcode kann gel�scht werden. Tats�chlich werden die meisten Prozeduren und Operatoren (aber auch einige Datentypen), die in ELAN zur Verf�gung stehen, nicht durch den ELAN-Compiler realisiert, sondern durch solche PACKETs.
Schutz vor fehlerhaftem Zugriff auf Datenobjekte
Beispiel:
PACKET stack handling DEFINES push,pop,init stack: LET max = 1000; ROW max INT VAR stack; INT VAR stack pointer; PROC init stack: stack pointer := 0 END PROC init stack; PROC push (INT CONST dazu wert): stack pointer INCR 1; IF stack pointer > max THEN errorstop ("stack overflow") ELSE stack [stack pointer] := dazu wert END IF END PROC push; PROC pop (INT VAR von wert): IF stack pointer = 0 THEN errorstop ("stack empty") ELSE von wert := stack [stack pointer]; stack pointer DECR 1 END IF END PROC pop END PACKET stack handling;
Dieses PACKET realisiert einen Stack. Den Stack k�nnen Sie �ber die Prozeduren initstack, push und pop benutzen.
Beispiel:
init stack; werte auf stack bringen; werte vom stack holen. werte auf stack bringen: INT VAR anzahl :: 0, wert; REP get (wert); push (wert); anzahl INCR 1 UNTIL ende kriterium END REP. werte vom stack holen: INT VAR i; FOR i FROM 1 UPTO anzahl REP pop (wert); put (wert) END REP.
Die Datenobjekte stack und stack pointer haben nur innerhalb des PACKETs stack handling G�ltigkeit. Anweisungen wie
put (stack [3]);
stack [27] := 5
au�erhalb des Paketes stack handling sind verboten und werden vom ELAN-Compiler zur�ckgewiesen. Ein Paket bietet also Schutz vor fehlerhafter Verwendung von Programmen und Datenobjekten. Wichtig ist au�erdem: Wenn Sie die Schnittstelle nicht ver�ndern, kann die Realisierung des Stacks ohne weiteres ge�ndert werden. Dabei m�ssen Sie Benutzerprogramme nicht �ndern. Beispielsweise k�nnten Sie sich entschlie�en, den Stack nicht durch eine Reihung, sondern durch eine Struktur zu realisieren. Alle Programme, die den Stack benutzen, k�nnen in diesem Fall unver�ndert bleiben.