Durchschnittlicher Fortschritt
Gewusst0
Nicht gewusst0
Noch nicht gestartet31

Empfohlene Karteikarten-Sets

Karteikarten im Karteikarten-Set

Noch nicht gestartet (31)

Die Backus-Naur-Form
 

Die Backus-Naur-Form (kurz BNF) ist eine formale Metasprache (aus dem Griechischen „meta“ [über] – „Sprache über Sprache“) zur Darstellung von Grammatiken und Syntaxregeln von Programmiersprachen. I.d.R. - und im Rahmen dieser Vorlesung - wird die Erweiterte Backus-Naur-Form (EBNF) verwendet.
 

Formale Grammatiken

Syntax

Sprache

Ermöglichen die Beschreibung und Analyse von Sprachen (u.a. Programmiersprachen) sowie die Definition einer Syntax. 

 

Die bestimmte Menge von erlaubten Zeichenketten, die aus einem Zeichenvorrat zusammengesetzt werden können.

 

Alle Wörter, die eine Grammatik erzeugen können, nennt man deren Sprache.
 

Eine Grammatik G besteht aus 4 Teilen (V, E, R, S)

Eine endliche Menge V von Variablen (oder Nichtterminalsymbole), die ersetzt werden können. Variablen werden als „Platzhalter“ benutzt. 

 

Eine Menge E von Endsymbolen (oder Terminalsymbole), die nicht mehr ersetzt werden können. E wird auch als Alphabet bezeichnet. 

 

Eine Menge R von (Produktions-)Regeln, für die Ersetzung von Variablen. 

 

Die Startvariable S, für den Ableitungsvorgang

Ableitungsvorgang

Mit einem Ableitungsvorgang lassen sich ausgehend von der Startvariable (S) Produktionsregeln (R) anwenden, die neue Zeichenfolgen erzeugen, welche wiederum weiter ersetzt werden können. 

 

Zeichenfolgen werden als Worte bezeichnet, wobei „Wort“ eine breitere Bedeutung als in der natürlichen Sprache hat (kann z.B.  „Satz“ oder „Programm“ umfassen).
 

Der Algorithmus, durch den aus einer Grammatik Wörter erzeugt werden können, lautet

 

1. Beginne mit Startvariable S

 

2. Ersetze eine Variable im aktuellen Wort mit Hilfe einer Regel aus R

 

3. Enthält das aktuelle Wort noch Variablen, wiederhole Schritt 2 

Die Chomsky-Hierarchie
 

12531424715d38220d4e5cc2.60946985phphvvZCx.png

Compiler

1934943855d38223fcd2573.54512868phpiip76c.png

Lexikalische Analyse 

  • Der Quelltext wird in Token zerlegt. 
  • Jeder Token ist eine lexikalische Einheit der Sprache, eine sprachliche Bedeutungseinheit (auch Lexem genannt). 
  • Kommentare und Leerplätze (inkl. Leerzeichen, Zeilenumbrüche, Einrückungen) werden entfernt, sodass sie keine Bedeutung haben. 
  • Der Teil des Compilers, welcher die lexikalische Analyse durchführt, heißt „scanner“ bzw. „lexer“. 
  • Lexikalische Fehler werden durch den „scanner“ identifiziert. Der Programmierer muss die identifizierten Fehler danach beheben.
     

Syntaktische Analyse

  • Überprüft die Korrektheit der Reihenfolge der Tokens, d.h. ob die Tokenfolge aus der Grammatik ableitbar ist. 
  • Der Teil des Compilers, der die syntaktische Analyse durchführt heißt „parser“. 
  • Durch die Erzeugung eines Syntaxbaums, entdeckt der Parser Zusammenhänge zwischen den angegebenen Lexemen. 
  • Syntaktische Fehler werden identifiziert. Der Programmierer muss die identifizierten Fehler danach beheben.
     

Semantische Analyse 

  • Namensauflösung: Erzeugung der Symboltabelle, die den Datentyp, die Tragweite und den Speicherplatz jedes Bezeichners registriert. 
  • Kompatibilität der Datentypen wird überprüft. 
  • Überprüft: 

--> Ob Variablen deklariert und initialisiert werden, bevor sie überhaupt benutzt werden. 

--> Es kann nicht mehrere Variablen geben, die den gleichen Namen haben (Ambiguität).

 

Codeoptimierung und Codegenerierung

Zwischencode wird erzeugt 

Erzeugter Zwischencode wird optimiert 

 

  • Elimination von totem Programmcode 
  • Erkennung unbenutzter Variablen 
  • Einsparung von Maschinenbefehlen 
  • Optimierung von Schleifen

 

 

Objektdateien werden erzeugt
 

Interpreter

Ein Interpreter ist ein Programm, welches Quellcode im Gegensatz zu Compilern nicht in eine auf dem System direkt ausführbare Datei umwandelt, sondern den Code einliest, analysiert und ausführt. 

 

Vorteil: Unabhängigkeit von Betriebssystem und Hardwarearchitektur. 

 

Nachteil: Langsamere Ausführung im Vergleich zu kompilierten Programmen.

Programmiersprachen – Klassifizierung
 

6923726275d3823da386e47.60791864phpzH1qDu.png

Wirkung 

Die Zustände, in denen sich ein Programm befinden kann, werden durch die Werte seiner Variablen bestimmt. Die Werte aller Variablen eines Programms definieren den globalen Zustand. Die Wirkung (side effect) eines Programms bezeichnet die Veränderung des Zustands, in dem sich eine abstrakte Maschine befindet. Ein Programm hat eine Wirkung, wenn sich mehr als dessen return statement ändert.
 

 referenzielle Transparenz
 

Die referenzielle Transparenz besagt, dass der Wert eines Ausdrucks ausgetauscht werden kann, ohne das Programm zu verändern. Voraussetzung dafür ist, dass:

• der Wert eines Ausdrucks in einem Quelltext nur von seiner Umgebung abhängt und nicht vom Zeitpunkt seiner Auswertung und

• der Ausdruck keine Wirkung hat.
 

Bei zustandsfreien Programmiersprachen: 

 

  • Es wird eine referenzielle Transparenz angestrebt und 

es existiert kein globaler Zustand. 

--> Dadurch führen gleiche Eingaben immer zu gleichen Ausgaben. 

--> Daten werden lokal erzeugt, aber Programme haben keine Wirkung (side effects)
 

Bei zustandsbehafteten Programmiersprachen:

 

  • Abhängig vom globalen Zustand ergeben gleiche Eingaben unterschiedliche Ausgaben. 

--> Wirken auf den Zustand der Maschine (z.B. Verändern von Inhalten des Speichers). 

--> Daten werden erzeugt und global/dauerhaft verändert.
 

Bei imperativen Programmiersprachen

 

  • Wird der Quellcode als eine Reihenfolge von Befehlen aufgefasst, die eine Sequenz von durchzuführenden Aktivitäten darstellen. 
  • Wird die Befehlsführung durch Kontrollstrukturen gesteuert (z.B. Sequenz, Schleife, Verzweigung). 

--> Die Imperative Programmierung ist die Grundlage der meisten Programmiersprachen (inkl. Assemblersprache). 

Bei deklarativen Programmiersprachen

 

  • Steht die Beschreibung des Problems im Vordergrund. Es wird beschrieben, was zu berechnen ist – weniger, wie es berechnet werden soll.
     

Funktionale Programmierung 

  • Das Programm besteht aus einer Menge von (mathematischen) Funktionen.
  • Das Hauptprogramm ist eine Funktion, wobei die Eingabedaten das Argument bilden und der Funktionswert die Ausgabe ist.
  • Die Hauptfunktion kann aus anderen Funktionen, deren Definition oder deren „Aufruf“ bestehen.
  • Die Hauptfunktion und andere Funktionen sind Gebilde aus Grundfunktionen (Bsp.: Multiplikation). Zur Funktionsdefinition können eigenhändig andere Funktionen verwendet werden, bis letztendlich nur noch die Grundfunktionen benutzt werden.
  • Es existieren keine Schleifen und keine wiederholten Zuweisungen.
  • Die Berechnung der Funktion gilt als Ablaufstruktur. Wiederholungen werden durch Rekursion realisiert.

Vorteile funktionaler Programmierung

 

  • Kurze Programme und dadurch leicht zu warten 
  • Vereinfachtes Parallelisieren 
  • Referenzielle Transparenz unterstützt Beweise der Korrektheit eines Programms
     

Nachteile funktionaler Programmierung

 

  • Nicht intuitiv, da Befehlsfolge und damit Abarbeitungsfolge nicht explizit gegeben 
  • Konzept des globalen Zustands durch Variablen nicht gegeben 
  • Im Allgemeinen langsamer als imperative Sprachen 
  • Limitierte Einsatzbereiche
     

Logische Programmierung 

Basiert auf der Prädikatenlogik

  • Ein Prädikat ist eine atomare Aussage, die die Eigenschaft von einem Gegenstand beschreibt (z.B. „der Beamer ist an“). 
  • Prädikate können falsch oder wahr sein (z.B. „der Lehrer ist deutsch“) 
  • Prädikate und ihre Wahrheit lassen sich durch logische Verknüpfungen (Junktoren) manipulieren und berechnen (z.B. Konjunktion)

Logische Programmierung 

Ein Programm besteht aus: 

 

  • einer Menge von Fakten und Annahmen (Axiome) 
  • einer Menge von Regeln, die auf die Axiome angewandt werden (Schlussregeln) 

 

Ein Interpreter wird befragt und berechnet eine Lösungsaussage aus den Axiomen und den Schlussregeln.

 

Einsatzgebiete: 

 

  • Künstliche Intelligenz 
  • Expertensysteme 
  • Medizin: Diagnosesysteme 
  • Mathematik: Theorembeweiser
     

Imperatives Paradigma: 

  • Lineare Sequenz von Anweisungen 
  • Anweisungen arbeiten auf einem Maschinenzustand 
  • Spiegelt stark die von Neumann- Architektur wider
     

Prozedurales-modulares Paradigma:  

  • Erweitert das imperative Paradigma um die Möglichkeit der Modularisierung von Code in kleinere Einheiten 
  • Ziel ist es: 

--> Algorithmen in überschaubare Teile zu zerlegen 

--> den Quellcode universeller und wiederverwendbar zu machen 

  • Alle aktuellen imperativen Programmiersprachen beinhalten das prozedurale Paradigma
     

Objektorientierte Programmierung

Die Objektorientierung (OO) dient der Beschreibung von Problemumgebungen, bei der einzelne Komponenten durch Objekte modelliert werden. Zu deren Beschreibung werden nicht nur deren Eigenschaften (Attribute) herangezogen, sondern auch die zugehörigen Verhalten/Fähigkeiten (Methoden).
 

Vorteile der Objektorientierung

• Intuitive Modellierung von Problemen aus der realen Welt. Abstraktionskonzepte der OO sind der Realität nachempfunden (Klassen, Objekte/Ausprägungen, Vererbung, Nachrichtenaustausch)

• Durch Datenkapselung:

    • ist Software modularer und gut wiederverwendbar

    • wird die Gültigkeit von Variablen klarer

    • wird Klarheit geschaffen wenn vieles in Programmen parallel          laufen muss (z.B. Logik und grafische Benutzeroberfläche)

• Geeignet für große Softwareprojekte

Objektorientierte Programmierung – Vor- und Nachteile
 

16248045885d3827ebabb725.48661809phpvq33gA.png

Objektorientierte Programmierung
 

5339687585d3827c30381c1.42023451phprV9vJS.png

Einsatzbereiche der Programmiersprache JAVA
 

3765021265d38283753bd25.55574414phpbuwCOw.png

JAVA Vor- und Nachteile

4353340735d38284c4b68f8.64817832php6eVBJZ.png

Einsatzbereiche der Programmiersprache C++

17803018905d3828914e98f5.13639875phpUaGiFD.png

C++ Vor- und Nachteile

14752537435d3828a6b8d439.52225524phppbgeSL.png