Skip to content

Commit 9ba7e1b

Browse files
authored
[SPLIT] Move CBuilder documentation to cbuilder sub-project (#107)
1 parent 3aa9341 commit 9ba7e1b

4 files changed

Lines changed: 1099 additions & 0 deletions

File tree

docs/semantic_definition.md

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
# Definition der semantischen Spracheigenschaften von Mini-Python
2+
3+
Ihre Umsetzung des Compiler-Frontends soll die in diesem Dokument definierten semantischen
4+
Sprachelemente der Sprache “Mini-Python” unterstützen. Als Grundlage werden die semantischen
5+
Sprachelemente der Sprache Python 3 verwendet. Da die gesamte Sprache zu umfangreich ist,
6+
wird in diesem Kapitel ein kleinerer und vereinfachter Sprachumfang festgelegt.
7+
8+
Die syntaktischen Eigenschaften der Sprache “Mini-Python” und die Abweichungen zu Python 3
9+
werden im Kapitel [Definition der syntaktischen Spracheigenschaften](syntax_definition.md)
10+
beschrieben.
11+
12+
Einige Angaben zur Semantik sind für den AST und die Symboltabelle noch nicht relevant und
13+
werden erst bei der Verwendung des CBuilders wichtig. Um die Verwendung des CBuilders zu
14+
erleichtern, sollten Sie diese Punkte allerdings schon in der semantischen Analyse
15+
betrachten.
16+
17+
Die Verwendung des CBuilders wird im Kapitel [Verwendung des CBuilders](usage_cbuilder.md)
18+
beschrieben. (Wird rechtzeitig ergänzt.)
19+
20+
## Scopes
21+
22+
Die Scopes sind im Vergleich zu Python 3 deutlich vereinfacht. Es gibt den globalen Scope,
23+
und es gibt weitere (lokale) Scopes für die Funktionen, für Klassen und Klassenobjekte
24+
(`self`).
25+
26+
Die Hierarchie der Scopes kann an dem folgenden Graphen abgelesen werden:
27+
28+
``` mermaid
29+
graph BT;
30+
Klasse_A-->Global;
31+
Funktion-->Global;
32+
Klasse_B_geerbt-->Klasse_B_super;
33+
Klasse_B_super-->Global;
34+
Objekt_A-->Klasse_A;
35+
Objekt_B_geerbt-->Klasse_B_geerbt;
36+
Objekt_B_super-->Klasse_B_super;
37+
```
38+
39+
Sollte das jeweilige Symbol nicht in einem Scope gefunden werden, muss im übergeordneten
40+
Scope danach gesucht werden. Dies erfolgt, bis der globale Scope erreicht wird. Eventuelle
41+
Besonderheiten zu den Scopes werden bei der jeweiligen Funktionalität in diesem Dokument
42+
beschrieben.
43+
44+
## Objekte
45+
46+
Wie in Python 3 werden intern alle Datentypen als Objekte der Klasse `Object` betrachtet.
47+
Zur Laufzeit soll eine dynamische Typisierung realisiert werden, d.h. die Variablen werden
48+
ohne Typdeklaration angelegt und können zur Laufzeit ihren Typ verändern.
49+
50+
## Builtin-Datentypen
51+
52+
Die in der syntaktischen Definition festgelegten [eingebauten
53+
Datentypen](syntax_definition.md#datentypen) sollen implizit angelegt werden können. Sie
54+
verhalten sich zur Laufzeit wie Objekte mit einem festgelegten Umfang unterstützter Methoden
55+
(u.a. `to_string`, Operatoren).
56+
57+
``` python
58+
a = 1 # Integer
59+
b = "foo" # String
60+
c = True # Boolean
61+
```
62+
63+
## Funktionen
64+
65+
Alle Funktionen besitzen einen eigenen Scope. In diesem müssen die Parameter sowie die in
66+
der Funktion definierten Variablen zugreifbar sein.
67+
68+
Um eine Funktion zu verwenden, muss diese zuerst definiert werden.
69+
70+
Es müssen nur einfache Funktionen unterstützt werden - verschachtelte Funktionen können Sie
71+
ignorieren.
72+
73+
### Globale Builtin-Funktionen
74+
75+
Die folgenden Funktionen sind immer vorhanden und global verfügbar. Abweichend zu den selbst
76+
definierten Funktionen müssen Builtin-Funktionen nicht vor der Verwendung definiert werden.
77+
78+
| Python-Funktion | Beschreibung | Rückgabe |
79+
|:----------------|:---------------------------------------------------------------------|:---------|
80+
| `print()` | Gibt ein oder mehrere übergeben String-Literale auf der Konsole aus. | `void` |
81+
| `input()` | Liest eine Zeile von der Konsole ein. | `String` |
82+
83+
### Funktionen für Builtin-Datentypen
84+
85+
Die Funktionen für Builtin-Datentypen verhalten sich intern wie Methodenaufrufe auf dem
86+
Datenobjekt. Sie können unter der Verwendung der passenden Methodennamen auch für Klassen
87+
überladen werden. Die folgende Liste stellt die unterstützten Datentypen sowie die
88+
Methodennamen dar:
89+
90+
| Python-Funktion | Beschreibung | Integer | String | Boolean | Methodenname |
91+
|:----------------|:---------------------------------------------------------------|:-------:|:------:|:-------:|:------------:|
92+
| `str()` | Gibt die String Representation des übergebenen Objekts zurück. |||| `__str__` |
93+
| `int()` | Cast zu Integer |||| `__int__` |
94+
95+
Der CBuilder unterstützt keine direkte Übergabe dieser Funktionen, sondern erwartet die
96+
Übergabe als Methodenaufruf auf dem Datenobjekt. Sie können diese Funktionsaufrufe bereits
97+
bei der semantischen Analyse durch passende Methodenaufrufe ersetzen.
98+
99+
``` python
100+
a = "5"
101+
102+
b = int(a) # Verwendung als Funktion
103+
b = a.__int__() # äquivalent als Methodenaufruf
104+
```
105+
106+
## Operatoren
107+
108+
Die Builtin-Datentypen unterstützen jeweils nur einige der vorhandenen Operatoren. Zudem
109+
sind die Operatoren für die Builtin-Datentypen nur jeweils für die Verwendung mit den selben
110+
Datentypen vorgesehen.
111+
112+
Für Klassen können alle Operatoren überladen werden, indem die Methode für den jeweiligen
113+
Operator implementiert wird (beispielsweise `__add__()` für den Operator `+`, siehe unten).
114+
115+
Im Folgenden sehen Sie Listen, welche Operatoren von welchen Datentypen unterstützt werden
116+
sollen. Hier sind auch die Methodennamen zur Verwendung bei Klassen mit angegeben.
117+
118+
Der CBuilder unterstützt keine direkte Übergabe von Operatoren, sondern erwartet die
119+
Übergabe als Methodenaufruf auf dem linken Wert (Objekt) mit dem rechten Wert (Objekt) als
120+
Parameter. Sie können also bereits bei der semantischen Analyse die Operatoren durch
121+
passende Methodenaufrufe ersetzen.
122+
123+
Der Zuweisungsoperator und die logischen Operatoren besitzen explizite Aufrufe und müssen
124+
nicht umgewandelt werden.
125+
126+
``` python
127+
a = 3
128+
b = 4
129+
130+
c = a + b # Verwendung eines Operators
131+
c = a.__add__(b) # äquivalent als Methodenaufruf
132+
```
133+
134+
### Logische Operatoren
135+
136+
Die logischen Operatoren stellen eine Abweichung dar und sollen nicht in Methodenaufrufe
137+
umgewandelt werden. Im CBuilder sind dafür explizite Aufrufe vorgesehen.
138+
139+
In Python 3 können Sie über die Methode `__bool__` Bool-Werte für eigenen Klassen
140+
implementieren. Allerdings wird die Methode `__bool__` dabei nicht implizit aufgerufen. Sie
141+
müssen diese Methode explizit aufrufen. Überlegen Sie sich, wie Sie den Methodenaufruf von
142+
`__bool__` dennoch vor dem Nutzer ihres Compilers verbergen können.
143+
144+
| Operation | Operator | Integer | String | Boolean |
145+
|:------------|:--------:|:-------:|:------:|:-------:|
146+
| Disjunktion | `or` ||||
147+
| Konjunktion | `and` ||||
148+
| Negation | `not` ||||
149+
150+
### Vergleichsoperatoren
151+
152+
| Operation | Operator | Integer | String | Boolean | Methodenname |
153+
|:---------------|:--------:|:-------:|:------:|:-------:|:------------:|
154+
| Gleichheit | `==` |||| `__eq__` |
155+
| Ungleichheit | `!=` |||| `__ne__` |
156+
| Größer gleich | `>=` |||| `__ge__` |
157+
| Größer | `>` |||| `__gt__` |
158+
| Kleiner gleich | `<=` |||| `__le__` |
159+
| Kleiner | `<` |||| `__lt__` |
160+
161+
### Arithmetische Operatoren
162+
163+
| Operation | Operator | Integer | String | Boolean | Methodenname |
164+
|:-------------------------------------|:--------:|:-------:|:------:|:-------:|:------------:|
165+
| Addition / String-Literal-Verkettung | `+` |||| `__add__` |
166+
| Subtraktion / negative Werte | `-` |||| `__sub__` |
167+
| Multiplikation | `*` |||| `__mul__` |
168+
| Division | `/` |||| `__div__` |
169+
170+
## Klassen
171+
172+
Die Klassen müssen wie die Funktionen vor der Verwendung definiert werden.
173+
174+
Alle Klassen besitzen einen eigenen Scope in dem die Methoden definiert sind. Der
175+
übergeordnete Scope von Klassen ist der Scope der Superklasse oder der globale Scope.
176+
177+
Statische Methoden und Attribute müssen nicht unterstützt werden.
178+
179+
### Konstruktor
180+
181+
Alle Klassen erben implizit von `Object`.
182+
183+
Die Objekte von Klassen sollen wie in Python 3 üblich über den Konstruktor, also die Methode
184+
`__init__`, erzeugt werden. Der Aufruf des Konstruktors der Superklasse soll im Gegensatz zu
185+
Python 3 vereinfacht und abweichend realisiert werden. Dieser Aufruf entspricht syntaktisch
186+
einem Funktionsaufruf mit einer Parameterliste, die auch leer sein kann. Semantisch ist
187+
dieser Aufruf allerdings ein Sonderfall und entspricht dem Aufruf des nächst höheren
188+
Superkonstruktors für das aktuell zu erzeugende Objekt.
189+
190+
``` python
191+
class A:
192+
def __init__(self, x):
193+
...
194+
#end
195+
#end
196+
197+
class B(A):
198+
def __init__(self, x):
199+
super(x)
200+
#end
201+
#end
202+
```
203+
204+
Der CBuilder erwartet für alle Klassen die Methode `__init__` mit dem Aufruf des
205+
Konstruktors der Superklasse als erste Anweisung. Sie können also zur Vorbereitung für den
206+
nächsten Schritt bereits bei allen Klassen die Methode `__init__` mit dem Aufruf von
207+
`super()` ergänzen.
208+
209+
Klassen ohne selbst definierte Superklasse müssen im CBuilder explizit von der Klasse
210+
`__MPyType_Object` erben.
211+
212+
### Klassenobjekte
213+
214+
Klassenobjekte besitzen jeweils einen eigenen Scope, der über das Schlüsselwort `self`
215+
zugreifbar ist.
216+
217+
``` python
218+
class A:
219+
def __init(self, x):
220+
self.x = x
221+
#end
222+
223+
def foo(self):
224+
return self.x
225+
#end
226+
#end
227+
```
228+
229+
### Methoden
230+
231+
Die Methoden verhalten sich im Wesentlichen wie Funktionen. Folgende Unterschiede zu
232+
Funktionen müssen beachtet werden:
233+
234+
1. Bei der Definition von Methoden muss der Parameter `self` immer als erster Parameter
235+
definiert/übergeben werden.
236+
237+
Somit wird nicht wie in Python 3 der erste Parameter implizit als Objektreferenz
238+
interpretiert, sondern immer der erste Parameter mit dem festgelegten Namen `self`.
239+
240+
2. Abweichend zu Funktionen sind Methoden immer Aufrufe auf einem Objekt und besitzen als
241+
übergeordneten Scope den Scope ihrer Klasse bzw. den Scope des Objekts, falls auf `self`
242+
zugegriffen wird.
243+
244+
3. Beim Aufruf von Methoden darf der Parameter `self` im Gegensatz zur Definition nicht
245+
vorhanden sein bzw. übergeben werden. Der CBuilder ergänzt `self` implizit mit der
246+
Objektreferenz, auf dem die Methode aufgerufen wurde.

0 commit comments

Comments
 (0)