Fachseminar. Semantische Analyse

Ähnliche Dokumente
ÜBERPRÜFUNG VON TYPEN

Definition Compiler. Bekannte Compiler

Zwischencode-Erzeugung. 2. Juni 2009

Compilerbau für die Common Language Run-Time

Organisatorisches. Folien (u.a.) auf der Lva-Homepage Skriptum über MU Online

Organisatorisches. Folien (u.a.) gibt's auf der Lva-Homepage zum Download

1953/54 (USA) PS FORTRAN (FORmula TRANslating system) 1958/60 (Europa) ALGOL (ALGOrithmic Language)

Einleitung Typsystem Typisierung Zusammenfassung Literatur. Typisierung. Effiziente Programmierung. Thomas Schnieders

Ein kleiner Blick auf die generische Programmierung

Einführung in C. EDV1-04C-Einführung 1

4.2 Programmiersprache C

1. Referenzdatentypen: Felder und Strings. Referenz- vs. einfache Datentypen. Rückblick: Einfache Datentypen (1) 4711 r

1. Referenzdatentypen: Felder und Strings

Syntax der Sprache PASCAL

Informatik I Übung, Woche 40

zu große Programme (Bildschirmseite!) zerlegen in (weitgehend) unabhängige Einheiten: Unterprogramme

JAVA 06: Gemischte einfache Fragen zu Java

Kapitel 15: Von dynamischen zu statischen Typen. Grundlagen der Programmierung 1. Holger Karl. Wintersemester 2016/2017. Inhaltsverzeichnis 1

Einführung in C. Alexander Batoulis. 5. Mai Fakutltät IV Technische Universität Berlin

Grundlagen der Programmierung 3 A

Android-Apps Gegenüberstellung Delphi java

Gedächtnis. Während der Abarbeitung eines Algorithmus müssen sich Dinge gemerkt werden bzw. auf Dingen wird gerechnet. Zugriff.

Programmiersprachen und Übersetzer

Kurze Einführung in die Programmiersprache C++ und in Root

Lexikalische Programmanalyse der Scanner

(Aufgaben zu Wertzuweisungen siehe Vorlesungsbeilage S. 49)

Herzlich willkommen!

1 Klassen und Objekte

Grundelemente objektorientierter Sprachen (1)

Es gibt keinen Algorithmus zum Schreiben eines Programms bzw. Algorithmus.

Grundelemente objektorientierter Sprachen (1)

Schwerpunkte. 10. Felder (Arrays) Grundprinzip von Arrays. Klassifikation von Typen in Programmiersprachen

Grundlagen der Objektorientierten Programmierung - Methoden -

4.4 Imperative Algorithmen Prozeduren

2. Programmierung in C

Praxis der Programmierung

Kapitel 15: Von dynamischen zu statischen Typen. Grundlagen der Programmierung 1. Holger Karl. Wintersemester 2018/2018. Inhaltsverzeichnis 1

Programmieren in Java

Typisierung. Prüfungen zur Übersetzungszeit Type Test und Type Cast Bedingte Zuweisung Nil Übergangsparameter Grade der Typisierung. 3.

Die Definition eines Typen kann rekursiv sein, d.h. Typ-Konstruktoren dürfen Elemente des zu definierenden Typ erhalten.

7 Funktionen. 7.1 Definition. Prototyp-Syntax: {Speicherklasse} {Typ} Name ({formale Parameter});

Informatik 1. Prüfung im Wintersemester 1997/98

Inhalt. 4.5 Arbeit mit Zeigern (engl. Pointer)

Programmierung mit C Zeiger

7 Laufzeit-Speicherverwaltung

Operatoren für elementare Datentypen Bedingte Anweisungen Schleifen. Operatoren für elementare Datentypen Bedingte Anweisungen Schleifen

Programmierung und Angewandte Mathematik

Operatoren für elementare Datentypen Bedingte Anweisungen Schleifen. Programmieren I. Martin Schultheiß. Hochschule Darmstadt Wintersemester 2010/2011

Scala. Funktionale (Zustandslose) Objekte

Programmiertechnik. Teil 4. C++ Funktionen: Prototypen Overloading Parameter. C++ Funktionen: Eigenschaften

Praktikum Compilerbau Sitzung 4 Semantik und Typprüfung

II. Grundlagen der Programmierung. Beispiel: Merge Sort. Beispiel: Merge Sort (Forts. ) Beispiel: Merge Sort (Forts. )

Struktur des MicroJava-Compilers

ALGOL 68 im Aspekt einer modernen Programmiersprache???

Elementare Konzepte von

5. Übung - Kanalkodierung/Programmierung

Ausdrücke der Programmiersprache Java

3.2 Datentypen und Methoden

Martin Unold INFORMATIK. Geoinformatik und Vermessung

Haskell, Typen, und Typberechnung. Grundlagen der Programmierung 3 A. Einige andere Programmiersprachen. Typisierung in Haskell

Zeiger (engl. Pointer)

Welche Informatik-Kenntnisse bringen Sie mit?

Hydroinformatik I: Referenzen und Zeiger

Felder - Arrays. Typ feldname[] = new Typ[<ganze Zahl >]; Beispiel: double vektor[] = new double[5]; auch eine Initialisierung ist möglich.

Grundlagen der Programmierung 2 (Comp-A)

Grundelemente objektorientierter Sprachen (1)

einlesen n > 0? Ausgabe Negative Zahl

Klausur Grundlagen der Programmierung

n 1. Grundzüge der Objektorientierung n 2. Methoden, Unterprogramme und Parameter n 3. Datenabstraktion n 4. Konstruktoren n 5. Vordefinierte Klassen

JAVA BASICS. 2. Primitive Datentypen. 1. Warum Java? a) Boolean (logische Werte wahr & falsch)

Einführung Sprachfeatures Hinweise, Tipps und Styleguide Informationen. Einführung in C. Patrick Schulz

5.4 Arrays. Oft müssen viele Werte gleichen Typs gespeichert werden. Idee: Lege sie konsekutiv ab! Greife auf einzelne Werte über ihren Index zu!

Reihungen. Prof. Dr. Christian Böhm. In Zusammenarbeit mit Gefei Zhang. WS 07/08

Programmiersprachen Einführung in C

Probeklausur: Programmierung WS04/05

Algorithmen und Datenstrukturen

Repetitorium Programmieren I + II

C++ - Einführung in die Programmiersprache Zeiger, Referenzen und Strukturen. Leibniz Universität IT Services Anja Aue

Datentypen. Agenda für heute, 4. März, Pascal ist eine streng typisierte Programmiersprache

2 Programmieren in Java I noch ohne Nachbearbeitung

magnum C++ WALTER SAUMWEBER kompakt komplett kompetent

Grundlagen der Programmierung 3 A

Reihungen. Martin Wirsing. in Zusammenarbeit mit Michael Barth, Fabian Birzele und Gefei Zhang

4.Grundsätzliche Programmentwicklungsmethoden

Begleittext: Einführung in das Programmieren in Java für Nichtinformatiker

Angewandte Mathematik und Programmierung

Vorkurs Informatik WiSe 17/18

Grundlagen der Programmierung Prof. H. Mössenböck. 6. Methoden

Institut für Programmierung und Reaktive Systeme. Java 2. Markus Reschke

Kapitel 5: Semantische Analyse

Übersetzung von Datenstrukturen

2. Programmierung in C

Einführung in die Programmierung für NF. Rückgabewerte, EBNF, Fallunterscheidung, Schleifen

Vorkurs Informatik WiSe 16/17

2. Programmierung in C

4. Vererbung Die Klasse Object. Die Klasse Object

3. Java - Sprachkonstrukte I

Transkript:

Fachseminar Vortragender: Arton Berisha Thema : Semantische Analyse Kursleiter: Prof. Dr. Helmut Weber

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die semantische Analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 2

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die semantische Analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 3

1.1 Phasen eines Compilers Wir stellen uns vor das ein Compiler in verschiedene Phasen arbeitet Quellprogramm Lexikalische Analyse Syntaxanalyse Jede Phase überführt das Ergebnis der vorhergingen Phase in eine andere Darstellung In der Praxis werde einige der Phasen zusammengefasst Semantische Analyse Zwischencode Erzeugung Code-Optimierung Code-Erzeugung 4 Zielprogramm

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die Semantische-Analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 5

1.2 Symboltabelle (1/2) Was ist die Symboltabelle? Eine Datenstruktur, die zur Verwaltung von Informationen über die verschiedenen Konstrukte (Variablen, Funktionen etc. ) der Quellsprache benutzt wird. Die Informationen werden von den Analysephasen des Compilers gewonnen und von der Synthesephasen zur Erzeugung des Zielcodes verwendet. Lexikalische Analyse Syntaxanalyse Semantische Analyse Zwischencode Erzeugung Code- Optimierung Code- Erzeugung Symboltabelle 6

1.2 Symboltabelle (2/2) Objekt: Variable Attribute Ident: ObjektArt: Typ: Adresse: Wert: Bezeichner variable Datentyp T (Strukturbeschreibung) Speicherplatz, symbolische Adresse Element aus T So könnte eine Symboltabelle aussehen, in diesem Fall wurde eine DB-Modellierung gewählt. Ident ObjektArt Typ Adresse Wert x variable integer 0FF3A20 2 y variable double 0FF7048 6.5 max constant integer 0FF6032 32 ausgabe function real -> real 1AF6392 7

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die semantische Analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 8

2.1 Was ist die semantische Analyse Aufbau einer künstlichen Sprache erfolgt nach festen Regeln (Syntax, Grammatik) Wörter und Sätze besitzen wohldefinierte Bedeutungen (Semantik) Die Wirkung eines Satzes ergibt sich aus seiner Bedeutung Semantische Analyse überprüft, ob die Teile eines Programms von der Bedeutung her zusammenpassen und sammelt Typ - Informationen Eine wesentliche Aufgabe ist die Typüberprüfung, z.b überprüft der Compiler ob die Operanden eines Operators von der Spezifikation zugelassen sind 9

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die Semantische-Analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 10

2.2 dynamische-/statische-überprüfung Wir unterscheiden zwischen statische Überprüfung (während der Kompilierung) dynamischen Überprüfung (zur Laufzeit) statische Überprüfung Typüberprüfungen Überprüfungen der Kontrollflusses Überprüfung auf Eindeutigkeit Auf Namen bezogene Überprüfung dynamische Überprüfung dynamische Typüberprüfung ist erforderlich, wenn der Typ von Variablen und Objekten nur zur Laufzeit bestimmt werden kann oder Grenzüberprüfung von Feldern 11

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die semantische Analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 12

2.3 statische-überprüfung Typüberprüfungen Ein Compiler sollte einen Fehler melden wenn einem integer ein string zugewiessen werden soll. Überprüfungen der Kontrollflusses Es gibt Anweisungen wie z.b das break die den Kontrollfluss eines Konstruktes wie der while- for-schleife oder switch-anweisung verlassen, ein Compiler sollte einen Fehler melden wenn eine solche umschließende Anweisung nicht existiert. Überprüfung auf Eindeutigkeit Sollte der Name einer Variable innerhalb des gleichen Anweisungsblockes definieren, so muss der Compiler eine Fehler melden. Auf Namen bezogene Überprüfung Es gibt gewisse Definitionen die auf bestimmte Namenskonventionen basieren der Compiler muss das Überprüfen. 13

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die semantische-analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 14

2.4 semantische Fehler im Code (1/2) Anweisungen (in C) Anweisung int bsp; bsp[0] = 2; int bsp; bsp = a ; char bsp = b ; bsp = bsp + a ; char bsp; bsp = r int bsp; bsp = 3 + 2; Ergebnis der semantischen Analyse FEHLER! FEHLER! OK! OK! OK! Grund Arrayzugriff auf ein nicht Array Einem integer wird ein character zugewiesen 15

2.4 semantische Fehler im Code (2/2) Verwendung und Definition von Symbolen (in C++) Anweisung char bsp; int bsp; int max(int a) {.} int max (int a) {.} int m = max(); int max (int a, int b){..} int bsp; { int bsp; } Ergebnis der semantischen Analyse FEHLER! FEHLER! FEHLER! OK! OK! Grund Variablenname bsp doppelt definiert Funktion max wurde mehrfach definiert Die Funktion max wurde ohne Parameter aufgerufen 16

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die Semantische-Analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 17

3.1 Typsysteme (1/2) Was ist ein Typsystem? Ein Typsystem für eine Programmiersprache ist eine Menge von Regeln, die die korrekte Verwendung von Typen im Kontext bestimmen. Für bestimmte Konstrukte muss der Type gegeben sein (Definition) und für andere kann der Typ aus der Struktur bestimmt werden. Ein Typsystem heißt stark, wenn alle möglichen statischen Typkonflikte zur Übersetzungszeit erkannt werden können. Ein Typsystem besteht aus gewissen Basistypen (Typnamen) und (Typ-) Konstruktoren, mit denen neue Typen aus vorhandenen konstruiert werden können. Mit den Konstruktoren werden Typausdrücke gebildet. Selektoren sind Operatoren, mit denen auf Komponenten von strukturierten Typen zugegriffen werden kann. 18

3.1 Typsysteme (2/2) Beispiel Pascal: Basistypen: integer, real, char, boolean Konstruktoren: array, record, pointer etc. Selektoren: x[e] Arraykomponente, x.a Recordfeld, x^ Pointer Deref. 19

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die Semantische-Analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 20

3.2 Typüberprüfung von Ausdrücken (1/2) Definition einiger Basistypen Produktion E literal E num Semantikregel E.type := char E.type := integer Der Ausdruck, der durch die Anwendung der mod-operation auf zwei Teilausdrücke vom Typ integer gebildet wird, hat den Typ integer. Bei einem Fehler kommt es zum Typ type_error. Produktion E E1 mod E2 Semantikregel E.type := if E1.type = integer and E2.type = integer then integer else type_error 21

3.2 Typüberprüfung von Ausdrücken (2/2) In einer Array-Referenz E1[E2] muss der Indexausdruck E2 den Typ integer haben. In dem Fall ist das Ergebnis der Elementtyp t, den man aus dem Typ array(s,t) des Ausdrucks E1 erhält. Produktion E E1[E2] Semantikregel E.type := if E2.type = integer and E1.type = array(s,t) then t else type_error 22

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die Semantische-Analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 23

3.3 Typüberprüfung von Anweisungen Da Sprachkonstrukte wie Anweisungen typischerweise keine Werte haben, kann diesen der spezielle einfache Typ void zugewiesen werden. Sollte innerhalb eine Anweisung ein Fehler auftreten, so wird der Anweisung das Typ type_error zugewiesen. Produktion S id := E S if E then S1 S while E do S1 S S1 Semantikregeln S.type := if id.type = E.type then void else type_error S.type := if E.type = boolean then S1.type else type_error S.type := if E.type = boolean then S1.type else type_error S.type := if S1.type = void then void else type_error 24

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die Semantische-Analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 25

3.4 Typumwandlung (1/4) Szenario: Nehmen wir an wir haben einen Ausdruck wie x + i, wobei x vom Typ double ist und i vom Typ integer. Problem: Die Darstellung von integer- und double-werten unterschieden sich innerhalb eines Computers und es werden verschiedene Maschienenbefehle für integer- und double-werte benutzt. MIPS-Architektur double a = 0; li.d $f4, 0.0 a = a + 3.5; add.d $f4, $f4, 3.5 int b = 0; li $t1, 0 b = b +1 add $t1, $t1, 1 26

3.4 Typumwandlung (2/4) Lösung: Compiler muss einen der Operanden umwandeln, um so sicherzustellen dass beide Operanden vom Selben Typ sind, wenn eine Operation stattfindet. Die Sprachdefinition spezifiziert, welche Umwandlungen notwendig sind. Die Entscheidung in was für einen Typ umgewandelt wird, wird entschieden abhängig davon was der Typ auf der linken Seite ist. #include <stdio.h> int main(){ double a = 3 + 3.5; int b = 3 + 3.5; printf("variable a: %f\n",a); printf("variable b: %d",b); return 0; } // 6.5 // 6 27

3.4 Typumwandlung (3/4) Bemerkung: Es gibt zwei Wege eine Typumwandlung durchzuführen, das eine wäre die implizite -Typumwandlung, hier tut der Compiler automatisch die Typumwandlung übernehmen. Die andere Möglichkeit ist das der Programmierer eine Umwandlung selber im Kode vorsieht. Produktion E num E num.num Semmantikregel E.type := integer E.type := real E id E.type := lookup( id.entry ) E E1 op E2 E.type := if E1.type = integer and E2.type = integer then integer else if E1.type = integer and E2.type =real then real else if E1.type = real and E2.type = integer then real else if E1.type = real and E2.type = real then real else type_error 28

3.4 Typumwandlung (4/4) Explizite-Typumwandlungen Sprache Syntax C var = (int) 5.60; int * addr; addr = (int*) 0x1234; ptr = (char *)malloc (sizeof(char) * 10); C++ d = static_cast<double>(4); Java double a = (double) 4; String bsp = String.valueOf(2) int bsp = Integer.valueOf( 23 ); 29

Agenda 1. Einleitung 1.1 Phasen eines Compilers 1.2 Symboltabelle 2. Semantische Analyse 2.1 Was ist die semantische-analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 30

4.1 PL0 - Program (1/2) PL0-Program VAR x, squ; PROCEDURE square; BEGIN squ := x * x END; BEGIN x := 1; WHILE x <= 10 DO BEGIN CALL square;! squ; x := x + 1; END END. 31

4.1 call - Statement (2/2) Call Statement (aufruf einer Prozedur ) void callstmnt(){ int i; getsym(); if (sym == ident) { i = position(id, txcurr); if (i == 0) error(11); if (objkind(i)!= procobj) error(15); emit(cal, levcurr-objlevel(i), objaddr(i)); getsym(); } else error(14); } 32

Agenda 1. Einleitung 1.2 Phasen eines Compilers 1.3 Symboltabelle 2. Semantische Analyse 2.1 Was ist die Semantische-Analyse 2.2 dynamische-/statische-überprüfung 2.3 statische-überprüfung 2.4 semantische Fehler im Code 3. Typüberprüfer 3.1 Typsysteme 3.2 Typüberprüfung von Ausdrücken 3.3 Typüberprüfung von Anweisungen 3.4 Typüberprüfung von Funktionen 3.5 Typumwandlung 4. PL0 Compiler 4.1 call - Statement 4.2 read - Statement 33

4.2 read - Statement read Statement ( Einlesen von STDIN in eine Variable) void readstmnt() { int i, k; getsym(); if (sym == lparen) { do { getsym(); if (sym == ident) { i = position(id, txcurr); if (i == 0) error(11); k = objkind(i); if (k == constobj k == procobj) error(12); else if (k == varobj) { emit(inp, 0, 0); emit(sto, levcurr-objlevel(i), objaddr(i)); getsym(); } } else error(33); } while (sym == comma); match(rparen, 22); } else error(43); } 34

Fragen Danke für die Aufmerksamkeit!!! 35