Pārlūkot izejas kodu

Abschnitt 'Compilerbau' begonnen.

Martin Thoma 11 gadi atpakaļ
vecāks
revīzija
ff9e624576

+ 1 - 0
documents/Programmierparadigmen/Arbeitszeit.md

@@ -9,3 +9,4 @@ in dem Erstellen dieses Skripts steckt:
 |01.02.2014 | 11:15 - 11:45 | Thoma | Haskell Class Hierachy
 |01.02.2014 | 16:00 - 17:00 | Thoma | Abschnitt über Rekursion hinzugefügt
 |04.02.2014 | 13:00 - 14:00 | Thoma | Viel zu Haskell ergänzt; Funktionen höherer Ordnung beschrieben
+|14.02.2014 | 08:30 - 09:30 | Thoma | Abschnitt über Compilerbau begonnen

+ 1 - 1
documents/Programmierparadigmen/C.tex

@@ -34,7 +34,7 @@ unterscheiden.
     \centering
     \begin{tabular}{|l|l||l|l||l|l||l|l|}
     \hline
-    \textbf{Dez.} & \textbf{Zeichen} & \textbf{Dez.} & \textbf{Zeichen} & \textbf{Dez.} & \textbf{Zeichen} & \textbf{Dez.} & \textbf{Zeichen} \\ \hline\hline
+    \textbf{Dez.} & \textbf{Z.} & \textbf{Dez.} & \textbf{Z.} & \textbf{Dez.} & \textbf{Z.} & \textbf{Dez.} & \textbf{Z.} \\ \hline\hline
     0    & ~       & 31   & ~       & 64   & @       & 96   & '       \\ \hline
     1    & ~       & ~    & ~       & 65   & A       & 97   & a       \\ \hline
     2    & ~       & ~    & ~       & 66   & B       & 98   & b       \\ \hline

+ 121 - 2
documents/Programmierparadigmen/Compilerbau.tex

@@ -1,7 +1,126 @@
 \chapter{Compilerbau}
 \index{Compilerbau|(}
 
-TODO
+Wenn man über Compiler redet, meint man üblicherweise \enquote{vollständige Übersetzer}:
 
-\index{Compilerbau|)}
+\begin{definition}\xindex{Compiler}%
+	Ein \textbf{Compiler} ist ein Programm $C$, das den Quelltext eines Programms
+	$A$ in eine ausführbare Form übersetzen kann.
+\end{definition}
 
+Jedoch gibt es verschiedene Ebenen der Interpretation bzw. Übersetzung:
+\begin{enumerate}
+	\item \textbf{Reiner Interpretierer}: TCL, Unix-Shell
+	\item \textbf{Vorübersetzung}: Java-Bytecode, Pascal P-Code, Python\footnote{Python hat auch \texttt{.pyc}-Dateien, die Python-Bytecode enthalten.}, Smalltalk-Bytecode
+	\item \textbf{Laufzeitübersetzung}: JavaScript\footnote{JavaScript wird nicht immer zur Laufzeit übersetzt. Früher war es üblich, dass JavaScript nur interpretiert wurde.}
+	\item \textbf{Vollständige Übersetzung}: C, C++, Fortran
+\end{enumerate}
+
+Zu sagen, dass Python eine interpretierte Sprache ist, ist in etwa so korrekt 
+wie zu sagen, dass die Bibel ein Hardcover-Buch ist.\footnote{Quelle: stackoverflow.com/a/2998544, danke Alex Martelli für diesen Vergleich.}
+
+Reine Interpretierer lesen den Quelltext Anweisung für Anweisung und führen 
+diese direkt aus.
+
+\todo[inline]{Bild}
+
+Bei der \textit{Interpretation nach Vorübersetzung} wird der Quelltext analysiert
+und in eine für den Interpretierer günstigere Form übersetzt. Das kann z.~B.
+durch
+\begin{itemize}
+	\item Zuordnung Bezeichnergebrauch - Vereinbarung\todo{?}
+	\item Transformation in Postfixbaum
+	\item Typcheck, wo statisch möglich
+\end{itemize}
+geschehen. Diese Vorübersetzung ist nicht unbedingt maschinennah.
+
+\todo[inline]{Bild}
+
+Die \textit{Just-in-time-Compiler}\xindex{Compiler!Just-in-time}\index{JIT|see{Just-in-time Compiler}} (kurz: JIT-Compiler) betreiben
+Laufzeitübersetzung. Folgendes sind Vor- bzw. Nachteile von Just-in-time Compilern:
+\begin{itemize}
+	\item schneller als reine Interpretierer
+	\item Speichergewinn: Quelle kompakter als Zielprogramm\todo{Was ist hier gemeint?}
+	\item Schnellerer Start des Programms
+	\item Langsamer (pro Funktion) als vollständige Übersetzung
+	\item kann dynamisch ermittelte Laufzeiteigenschaften berücksichtigen (dynamische Optimierung)
+\end{itemize}
+
+Moderne virtuelle Maschinen für Java und für .NET nutzen JIT-Compiler.
+
+Bei der \textit{vollständigen Übersetzung} wird der Quelltext vor der ersten
+Ausführung des Programms $A$ in Maschinencode (z.~B. x86, SPARC) übersetzt.
+
+\todo[inline]{Bild}
+
+\section{Funktionsweise}
+Üblicherweise führt ein Compiler folgende Schritte aus:
+\begin{enumerate}
+	\item Lexikalische Analyse
+	\item Syntaktische Analyse
+	\item Semantische Analyse
+	\item Zwischencodeoptimierung
+	\item Codegenerierung
+    \item Assemblieren und Binden
+\end{enumerate}
+
+\subsection{Lexikalische Analyse}\xindex{Analyse!lexikalische}%
+In der lexikalischen Analyse wird der Quelltext als Sequenz von Zeichen betrachtet.
+Sie soll bedeutungstragende Zeichengruppen, sog. \textit{Tokens}\xindex{Token},
+erkennen und unwichtige Zeichen, wie z.~B. Kommentare überspringen. Außerdem
+sollen Bezeichner identifiziert und in einer \textit{Stringtabelle}\xindex{Stringtabelle}
+zusammengefasst werden.
+
+\begin{beispiel}
+	\todo[inline]{Beispiel erstellen}
+\end{beispiel}
+
+\section{Syntaktische Analyse}\xindex{Analyse!syntaktische}%
+In der syntaktischen Analyse wird überprüft, ob die Tokenfolge zur 
+kontextfreien Sprache\todo{Warum kontextfrei?} gehört. Außerdem soll die 
+hierarchische Struktur der Eingabe erkannt werden.\todo{Was ist gemeint?}
+
+Ausgegeben wird ein \textbf{abstrakter Syntaxbaum}\xindex{Syntaxbaum!abstrakter}.
+
+\begin{beispiel}[Abstrakter Syntaxbaum]
+	TODO
+\end{beispiel}
+
+\section{Semantische Analyse}\xindex{Analyse!semantische}%
+Die semantische Analyse arbeitet auf einem abstrakten Syntaxbaum und generiert
+einen attributierten Syntaxbaum\xindex{Syntaxbaum!attributeriter}.
+
+Sie führt eine kontextsensitive Analyse durch. Dazu gehören:
+\begin{itemize}
+	\item \textbf{Namensanalyse}: Beziehung zwischen Deklaration und Verwendung\todo{?}
+	\item \textbf{Typanalyse}: Bestimme und prüfe Typen von Variablen, Funktionen, \dots \todo{?}
+	\item \textbf{Konsistenzprüfung}: Wurden alle Einschränkungen der Programmiersprache eingehalten?\todo{?}
+\end{itemize}
+
+\begin{beispiel}[Attributeriter Syntaxbaum]
+    TODO
+\end{beispiel}
+
+\section{Zwischencodeoptimierung}
+Hier wird der Code in eine sprach- und zielunabhängige Zwischensprache transformiert.
+Dabei sind viele Optimierungen vorstellbar. Ein paar davon sind:
+\begin{itemize}
+    \item \textbf{Konstantenfaltung}: Ersetze z.~B. $3+5$ durch $8$.
+    \item \textbf{Kopienfortschaffung}: Setze Werte von Variablen direkt ein
+    \item \textbf{Code verschieben}: Führe Befehle vor der Schleife aus, statt in der Schleife \todo{?}
+    \item \textbf{Gemeinsame Teilausdrücke entfernen}: Es sollen doppelte Berechnungen vermieden werden \todo{Beispiel?}
+    \item \textbf{Inlining}: Statt Methode aufzurufen, kann der Code der Methode an der Aufrufstelle eingebaut werden.
+\end{itemize}
+
+\section{Codegenerierung}
+Der letzte Schritt besteht darin, aus dem generiertem Zwischencode den 
+Maschinencode oder Assembler zu erstellen. Dabei muss folgendes beachtet werden:
+\begin{itemize}
+    \item \textbf{Konventionen}: Wie werden z.~B. im Laufzeitsystem Methoden aufgerufen?
+    \item \textbf{Codeauswahl}: Welche Befehle kennt das Zielsystem?
+    \item \textbf{Scheduling}: In welcher Reihenfolge sollen die Befehle angeordnet werden?
+    \item \textbf{Registerallokation}: Welche Zwischenergebnisse sollen in welchen Prozessorregistern gehalten werden?
+    \item \textbf{Nachoptimierung}\todo{?}
+\end{itemize}
+
+\index{Compilerbau|)}

BIN
documents/Programmierparadigmen/Programmierparadigmen.pdf


+ 37 - 0
documents/Programmierparadigmen/Programmiersprachen.tex

@@ -2,6 +2,43 @@
 Im folgenden werden einige Begriffe definiert anhand derer
 Programmiersprachen unterschieden werden können.
 
+\begin{definition}\xindex{Programmiersprache}\xindex{Programm}%
+    Eine \textbf{Programmiersprache} ist eine formale Sprache, die durch eine
+    Spezifikation definiert wird und mit der Algorithmen beschrieben werden
+    können. Elemente dieser Sprache heißen \textbf{Programme}.
+\end{definition}
+
+Ein Beispiel für eine Sprachspezifikation ist die \textit{Java Language Specification}.\footnote{Zu finden unter \url{http://docs.oracle.com/javase/specs/}} Obwohl es kein guter Stil ist, ist auch
+eine Referenzimplementierung eine Form der Spezifikation.
+
+Im Folgenden wird darauf eingegangen, anhand welcher Kriterien man 
+Programmiersprachen unterscheiden kann.
+
+\section{Abstraktion}
+Wie nah an den physikalischen Prozessen im Computer ist die Sprache?
+Wie nah ist sie an einer mathematisch / algorithmischen Beschreibung?
+
+\begin{definition}\xindex{Maschinensprache}\xindex{Befehlssatz}%
+    Eine \textbf{Maschinensprache} beinhaltet ausschließlich Instruktionen, die direkt
+    von einer CPU ausgeführt werden können. Die Menge dieser Instruktionen 
+    sowie deren Syntax wird \textbf{Befehlssatz} genannt.
+\end{definition}
+
+\begin{beispiel}[Maschinensprachen]
+    \begin{bspenum}
+        \item \xindex{x86}x86: 
+        \item \xindex{SPARC}SPARC:
+    \end{bspenum}
+\end{beispiel}
+
+\begin{definition}\xindex{Assembler}%
+    \textbf{Assembler} TODO
+\end{definition}
+
+\begin{beispiel}[Assembler]%
+    TODO
+\end{beispiel}
+
 \section{Paradigmen}
 Die grundlegendste Art, wie man Programmiersprachen unterscheiden
 kann ist das sog. \enquote{Programmierparadigma}, also die Art wie

+ 2 - 1
documents/Programmierparadigmen/Vorwort.tex

@@ -5,7 +5,8 @@ in der Klausur als Nachschlagewerk zu dienen; es soll jedoch auch
 vorher schon für die Vorbereitung genutzt werden können und nach
 der Klausur als Nachschlagewerk dienen.
 
-Ein Link auf das Skript ist unter \href{http://martin-thoma.com/programmierparadigmen/}{\path{martin-thoma.com/programmierparadigmen}}
+Ein Link auf das Skript ist unter \\
+\href{http://martin-thoma.com/programmierparadigmen/}{\path{martin-thoma.com/programmierparadigmen}}\\
 zu finden.
 
 \section*{Anregungen, Verbesserungsvorschläge, Ergänzungen}