Compilerbau.tex 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. \chapter{Compilerbau}
  2. \index{Compilerbau|(}
  3. Wenn man über Compiler redet, meint man üblicherweise \enquote{vollständige Übersetzer}:
  4. \begin{definition}\xindex{Compiler}%
  5. Ein \textbf{Compiler} ist ein Programm $C$, das den Quelltext eines Programms
  6. $A$ in eine ausführbare Form übersetzen kann.
  7. \end{definition}
  8. Jedoch gibt es verschiedene Ebenen der Interpretation bzw. Übersetzung:
  9. \begin{enumerate}
  10. \item \textbf{Reiner Interpretierer}: TCL, Unix-Shell
  11. \item \textbf{Vorübersetzung}: Java-Bytecode, Pascal P-Code, Python\footnote{Python hat auch \texttt{.pyc}-Dateien, die Python-Bytecode enthalten.}, Smalltalk-Bytecode
  12. \item \textbf{Laufzeitübersetzung}: JavaScript\footnote{JavaScript wird nicht immer zur Laufzeit übersetzt. Früher war es üblich, dass JavaScript nur interpretiert wurde.}
  13. \item \textbf{Vollständige Übersetzung}: C, C++, Fortran
  14. \end{enumerate}
  15. Zu sagen, dass Python eine interpretierte Sprache ist, ist in etwa so korrekt
  16. wie zu sagen, dass die Bibel ein Hardcover-Buch ist.\footnote{Quelle: stackoverflow.com/a/2998544, danke Alex Martelli für diesen Vergleich.}
  17. Reine Interpretierer lesen den Quelltext Anweisung für Anweisung und führen
  18. diese direkt aus.
  19. \todo[inline]{Bild}
  20. Bei der \textit{Interpretation nach Vorübersetzung} wird der Quelltext analysiert
  21. und in eine für den Interpretierer günstigere Form übersetzt. Das kann z.~B.
  22. durch
  23. \begin{itemize}
  24. \item Zuordnung Bezeichnergebrauch - Vereinbarung\todo{?}
  25. \item Transformation in Postfixbaum
  26. \item Typcheck, wo statisch möglich
  27. \end{itemize}
  28. geschehen. Diese Vorübersetzung ist nicht unbedingt maschinennah.
  29. \todo[inline]{Bild}
  30. Die \textit{Just-in-time-Compiler}\xindex{Compiler!Just-in-time}\index{JIT|see{Just-in-time Compiler}} (kurz: JIT-Compiler) betreiben
  31. Laufzeitübersetzung. Folgendes sind Vor- bzw. Nachteile von Just-in-time Compilern:
  32. \begin{itemize}
  33. \item schneller als reine Interpretierer
  34. \item Speichergewinn: Quelle kompakter als Zielprogramm\todo{Was ist hier gemeint?}
  35. \item Schnellerer Start des Programms
  36. \item Langsamer (pro Funktion) als vollständige Übersetzung
  37. \item kann dynamisch ermittelte Laufzeiteigenschaften berücksichtigen (dynamische Optimierung)
  38. \end{itemize}
  39. Moderne virtuelle Maschinen für Java und für .NET nutzen JIT-Compiler.
  40. Bei der \textit{vollständigen Übersetzung} wird der Quelltext vor der ersten
  41. Ausführung des Programms $A$ in Maschinencode (z.~B. x86, SPARC) übersetzt.
  42. \todo[inline]{Bild}
  43. \section{Funktionsweise}
  44. Üblicherweise führt ein Compiler folgende Schritte aus:
  45. \begin{enumerate}
  46. \item Lexikalische Analyse
  47. \item Syntaktische Analyse
  48. \item Semantische Analyse
  49. \item Zwischencodeoptimierung
  50. \item Codegenerierung
  51. \item Assemblieren und Binden
  52. \end{enumerate}
  53. \subsection{Lexikalische Analyse}\xindex{Analyse!lexikalische}%
  54. In der lexikalischen Analyse wird der Quelltext als Sequenz von Zeichen betrachtet.
  55. Sie soll bedeutungstragende Zeichengruppen, sog. \textit{Tokens}\xindex{Token},
  56. erkennen und unwichtige Zeichen, wie z.~B. Kommentare überspringen. Außerdem
  57. sollen Bezeichner identifiziert und in einer \textit{Stringtabelle}\xindex{Stringtabelle}
  58. zusammengefasst werden.
  59. \begin{beispiel}
  60. \todo[inline]{Beispiel erstellen}
  61. \end{beispiel}
  62. \section{Syntaktische Analyse}\xindex{Analyse!syntaktische}%
  63. In der syntaktischen Analyse wird überprüft, ob die Tokenfolge zur
  64. kontextfreien Sprache\todo{Warum kontextfrei?} gehört. Außerdem soll die
  65. hierarchische Struktur der Eingabe erkannt werden.\todo{Was ist gemeint?}
  66. Ausgegeben wird ein \textbf{abstrakter Syntaxbaum}\xindex{Syntaxbaum!abstrakter}.
  67. \begin{beispiel}[Abstrakter Syntaxbaum]
  68. TODO
  69. \end{beispiel}
  70. \section{Semantische Analyse}\xindex{Analyse!semantische}%
  71. Die semantische Analyse arbeitet auf einem abstrakten Syntaxbaum und generiert
  72. einen attributierten Syntaxbaum\xindex{Syntaxbaum!attributeriter}.
  73. Sie führt eine kontextsensitive Analyse durch. Dazu gehören:
  74. \begin{itemize}
  75. \item \textbf{Namensanalyse}: Beziehung zwischen Deklaration und Verwendung\todo{?}
  76. \item \textbf{Typanalyse}: Bestimme und prüfe Typen von Variablen, Funktionen, \dots \todo{?}
  77. \item \textbf{Konsistenzprüfung}: Wurden alle Einschränkungen der Programmiersprache eingehalten?\todo{?}
  78. \end{itemize}
  79. \begin{beispiel}[Attributeriter Syntaxbaum]
  80. TODO
  81. \end{beispiel}
  82. \section{Zwischencodeoptimierung}
  83. Hier wird der Code in eine sprach- und zielunabhängige Zwischensprache transformiert.
  84. Dabei sind viele Optimierungen vorstellbar. Ein paar davon sind:
  85. \begin{itemize}
  86. \item \textbf{Konstantenfaltung}: Ersetze z.~B. $3+5$ durch $8$.
  87. \item \textbf{Kopienfortschaffung}: Setze Werte von Variablen direkt ein
  88. \item \textbf{Code verschieben}: Führe Befehle vor der Schleife aus, statt in der Schleife \todo{?}
  89. \item \textbf{Gemeinsame Teilausdrücke entfernen}: Es sollen doppelte Berechnungen vermieden werden \todo{Beispiel?}
  90. \item \textbf{Inlining}: Statt Methode aufzurufen, kann der Code der Methode an der Aufrufstelle eingebaut werden.
  91. \end{itemize}
  92. \section{Codegenerierung}
  93. Der letzte Schritt besteht darin, aus dem generiertem Zwischencode den
  94. Maschinencode oder Assembler zu erstellen. Dabei muss folgendes beachtet werden:
  95. \begin{itemize}
  96. \item \textbf{Konventionen}: Wie werden z.~B. im Laufzeitsystem Methoden aufgerufen?
  97. \item \textbf{Codeauswahl}: Welche Befehle kennt das Zielsystem?
  98. \item \textbf{Scheduling}: In welcher Reihenfolge sollen die Befehle angeordnet werden?
  99. \item \textbf{Registerallokation}: Welche Zwischenergebnisse sollen in welchen Prozessorregistern gehalten werden?
  100. \item \textbf{Nachoptimierung}\todo{?}
  101. \end{itemize}
  102. \index{Compilerbau|)}