Ihre Umsetzung des Compiler-Frontends soll die in diesem Dokument definierten syntaktischen Sprachelemente der Sprache Mini-Python unterstützen. Als Grundlage wird die Syntax der Sprache Python 3 verwendet. Da die gesamte Sprache zu umfangreich ist, wird in diesem Kapitel ein kleinerer und vereinfachter Sprachumfang festgelegt.
Die semantischen Eigenschaften der Sprache und die Abweichungen zu Python 3 werden im Kapitel Definition der semantischen Spracheigenschaften beschrieben.
Datentyp | Definition |
---|---|
Integer |
Integer-Literale bestehen aus einer beliebigen Folge der Ziffern 0-9 . |
String |
String-Literale bestehen aus einer beliebigen Folge an ASCII-Zeichen, die von ' oder " eingeschlossen sind. Sie müssen keine Unicode-Zeichen unterstützen. |
Boolean |
Bestehen aus einem der beiden Schlüsselwörter True oder False |
Klassen | siehe Klassen |
Kommentare werden durch das Zeichen #
eingeleitet und umfassen sämtliche Zeichen bis zum
nächsten Newline. Es existiert ein spezielles Schlüsselwort #end
, welches keinen Kommentar
darstellt.
Das Schlüsselwort #end
stellt eine Besonderheit dar und dient zum Schließen von
Funktionen, Methoden, Klassen und Kontrollstrukturen. Durch die Verwendung dieses
Schlüsselworts kann auf die Auswertung der Einrückung verzichtet werden.
Werden zur Bezeichnung von Variablen, Funktionsnamen sowie Klassennamen verwendet. Bestehen
aus einer Zeichenkette der Zeichen a-z
,A-Z
, 0-9
, _
. Bezeichner dürfen nicht mit
einer Ziffer 0-9
beginnen.
Variablen bestehen aus einem eindeutigen Bezeichner (Variablennamen). Den Variablen können
Werte zugewiesen werden und Variablen können als Werte verwendet werden. Die Zuweisung
erfolgt mithilfe des =
-Operators. Auf der rechten Seite der Zuweisung können auch einfache
Ausdrücke stehen.
a = 5
a = 2 + 3
print(a)
Eine Anweisung ist eine einzeilige Befehlsfolge, beispielsweise eine Zuweisung, ein Funktionsaufruf oder eine Operation. Sie muss immer mit einem Newline abgeschlossen werden.
a = 10 - 5
a = "foo"
func1(a, b)
...
Funktionsdefinitionen werden mit dem Schlüsselwort def
eingeleitet. Sie besitzen einen
eindeutigen Bezeichner (Funktionsnamen), eine in Klammern angegebene Parameterliste, die
auch leer sein kann und eine Abfolge von Anweisungen. Der Anweisungsblock wird durch einen
Doppelpunkt :
eingeleitet. Funktionsdefinitionen können eine Rückgabe besitzen, die über
das Schlüsselwort return
eingeleitet wird. Eine Funktionsdefinition muss immer mit dem
Schlüsselwort #end
geschlossen werden.
Hinweis: Verschachtelte Funktionsdefinitionen müssen nicht umgesetzt werden.
def bezeichner(param1, param2):
<Anweisung_1>
<Anweisung_2>
return <Bezeichner, Wert oder Operation>
#end
def func1(a, b):
c = a + b
return c == a + b
#end
Funktionsaufrufe bestehen aus einem Bezeichner (Funktionsname) gefolgt von einer in Klammern
angegebenen Parameterliste, die auch leer sein kann. Als Parameter können Variablen, Werte
der Datentypen, weitere Funktionsaufrufe und Ausdrücke wie z.B. 1 + 1
dienen.
func1(var1, 5)
func1(func2(), 1 + 1)
Operatoren definieren den Typ einer Operation. Eine Operation besitzt im Regelfall einen linken und rechten Operanden. Als Operanden können Variablen, Werte der Datentypen, Funktionsaufrufe sowie Operationen oder Ausdrücke dienen.
Die Operatoren besitzen eine Rangfolge, um verschachtelte Operationen aufzulösen. Sie dürfen daher nicht einfach von links nach rechts aufgelöst werden. Die Rangfolge der Operatoren können Sie der Python Dokumentation entnehmen.
1 == 1
7 >= 1 + 2
Operation | Operator |
---|---|
Disjunktion | or |
Konjunktion | and |
Negation | not |
Der Operator not
stellt eine Besonderheit dar und besitzt nur einen (rechten) Operanden.
Operation | Operator |
---|---|
Gleichheit | == |
Ungleichheit | != |
Größer gleich | >= |
Größer | > |
Kleiner gleich | <= |
Kleiner | < |
Operation | Operator |
---|---|
Addition / String-Literal-Verkettung | + |
Subtraktion | - |
Multiplikation | * |
Division | / |
While-Schleifen werden mit dem Schlüsselwort while
eingeleitet. Sie bestehen im Weiteren
aus einer Bedingung, die durch einen Doppelpunkt :
abgeschlossen wird, einer Folge von
Anweisungen und werden mit dem Schlüsselwort #end
abgeschlossen.
Die Bedingung kann aus einem atomaren Boolean-Wert oder einem Vergleichsausdruck bestehen.
while <Bedingung>:
<Anweisung_1>
<Anweisung_2>
#end
a = 10
while (a >= 0):
print(a)
a = a- 1
#end
Eine bedingte Anweisung besteht immer aus genau einer if
-Anweisung, keiner oder beliebig
vieler elif
-Anweisungen und einer oder keiner else
-Anweisung. Die bedingte Anweisung
muss mit dem Schlüsselwort #end
abgeschlossen werden.
Eine if
-Anweisung wird mit dem Schlüsselwort if
eingeleitet und besteht aus einer
Bedingung, die mit einem Doppelpunkt :
abgeschlossen wird und einer Folge von Anweisungen.
Eine elif
-Anweisung wird mit dem Schlüsselwort elif
eingeleitet und ist ansonsten
identisch zur if
-Anweisung.
Eine else
-Anweisung wird mit dem Schlüsselwort else
eingeleitet. Auf das Schlüsselwort
folgt ein Doppelpunkt :
und eine Folge von Anweisungen.
if <Bedingung>:
<Anweisung_1>
<Anweisung_2>
#end
if <Bedingung>:
<Anweisung>
elif <Bedingung>:
<Anweisung>
else:
<Anweisung>
#end
a = "abc"
if a < "adc":
print("a kleiner als ", "adc")
elif a == "adf":
print("a ist ", "adf")
else:
print("a passt nicht")
#end
Klassendefinitionen werden mit dem Schlüsselwort class
eingeleitet. Nach dem Schlüsselwort
folgt ein eindeutiger Bezeichner (Klassenname). Auf den Bezeichner kann in Klammern die
Angabe des Bezeichners einer Superklasse folgen. Nach dem Bezeichner und der möglicherweise
vorhandenen Angabe der Superklasse folgt ein Doppelpunkt :
sowie eine Auflistung von
Methodendefinitionen. Klassendefinitionen müssen immer mit dem Schlüsselwort #end
beendet
werden.
Die Methodendefinitionen sind wie Funktionsdefinitionen aufgebaut.
Dabei besteht die Einschränkung, dass als erster Parameter das Schlüsselwort self
übergeben werden muss. Zudem erfolgt der Zugriff auf Klassenattribute über das Schlüsselwort
self
gefolgt von einem Punkt .
und dem Bezeichner des Attributes.
Hinweis: Weitere Sprachelemente wie Mehrfachvererbung oder statische Klassenattribute und -methoden müssen nicht umgesetzt werden.
class Bezeichner(<Bezeichner der Superklasse>):
<Methodendefinition_1>
<Methodendefinition_2>
#end
class A:
def method_1(self):
...
#end
#end
class B(A):
def setA(self, a):
self.a = a
#end
def getA(self):
return self.a
#end
#end
Die Erzeugung von Klassenobjekten erfolgt wie ein Funktionsaufruf mit dem Klassennamen als “Funktionsnamen”.
a = A(<Parameterliste oder leer>)
Methodenaufrufe besitzen einen zusammengesetzten Bezeichner und sind ansonsten wie
Funktionsaufrufe aufgebaut. Der Bezeichner setzt sich aus dem
Bezeichner des Objektes, einem Punkt .
und dem Bezeichner der Methode zusammen.
a = B()
a.setA(5)