Diskussion:Compiler
Füge neue Diskussionsthemen unten an:
Klicke auf , um ein neues Diskussionsthema zu beginnen.Archiv |
Wie wird ein Archiv angelegt? |
Liste von Compilern und Interpretern
BearbeitenKann hier vielleicht mal jemand eine Liste von Compilern und Interpretern anfangen?--134.106.87.55 19:44, 3. Nov. 2014 (CET)
- Das erscheint mir wenig sinnvoll. Wie soll sich eine solche Liste zur Liste von Programmiersprachen verhalten bzw. sich davon absetzen? --Herbert Klaeren (Diskussion) 22:12, 5. Nov. 2014 (CET)
Hoffentlich eine verständliche Anleitung
BearbeitenSkriptcodeuebersetzer Es gibt fuer jeden Operator Eingrenzregeln, mit der man zwei Schiebezeiger auf bestimmte Tokens des Ausdrucks schiebt. Die Schieberegeln werden nach- einander in der Prioritaet absteigend angewandt und anschliessend erfolgt nach einer Reduktionsregel eine Ersetzung des begrenzten Teilausdrucks durch in der Regel eine Ergebnisvariable ("ein R-Wert") und die Ausgabe eines Assemblerfragments, in das als Platzhalter Variablen aus dem Teilausdruck eingefuegt werden koennen. Das wird solange wiederholt, bis der Ausdruck leergefegt ist oder aufgrund eines Syntaxfehlers nicht reduziert werden kann.
Was sich kompliziert anhoert, ist im Wesentlichen das Gleiche wie "Punkt vor Strich und Klammern haben Vorfahrt".
Beispiel: ( 7 + 5 ) * a ;
1. Schiebe den rechten Eingrenz-Zeiger auf die erste geschlossene Klammer von links und den linken Zeiger auf die erste offene Klammer von dort. 2. In dem eventuell eingegrenzten Bereich, schiebe die beiden Zeiger auf das erste Muster "Variabel * Variabel" oder "Variabel / Variabel" von links. 3. In dem eventuell erneut eingegrenzten Bereich, schiebe die beiden Zeiger auf das erste Muster "Variabel + Variabel" oder "Variabel - Variabel" von links.
Nun schau, auf welches Muster die beiden Zeiger zeigen, in dem Fall "7 + 5" und loesche nun das raus und ersetze es durch Ergebniswert_n, also im ersten Fall Ergebniswert_1 . Dann wuerde das Assemblerfragment
"mov ax,7 add ax,5 mov [Ergebniswert_1],ax " ausgegeben werden.
Das bedeutet im Klartext nichts anderes als Zaehle 7 und 5 zusammen Speichere das Ergebnis in Ergebniswert_1 .
Der Prozessor kann nur die Grundrechenarten, den Befehlsspeicher im RAM abarbeiten und bedingt seine Register umladen und Werte aus dem RAM lesen oder schreiben. Assembler ist ganz einfach.
( 7 und 5 werden aus dem Ausdruck uebernommen und ins Assemblerfragment gefuegt. )
4. Wiederhole alles von Vorne, reduziere auf aehnliche Weise die Klammern und die Multiplikation ( oder Division ) und breche mit der letzten Reduktion ab und mache weiter beim naechsten Ausdruck.
Dann gibt es noch Bedingungen, also Ifs und Schleifen . Dafuer nimmt man einen Stapelspeicher, auf dem man Sprunglabels ablegt und bei Verlassen der Schachtelung in den Code einfuegt. Beispiel
if ( 1 ) wird uebersetzt zu
Vergleiche Wert mit eins Springe ("goto, jnz") falls unwahr zu Marke "Marke_1", die sogleich auf dem Stapel landet. {
if ( 0 ) wird uebersetzt zu Vergleiche Wert mit eins Springe falls unwahr zu Marke "Marke_2", die sogleich auf dem Stapel landet. {
} hole hier die oberste Sprungmarke vom Stapel und fuege sie an der entsprechenden Stelle im Assemblercode ein. Also
Marke_2 :
} hole hier die zweite (genauer: oberste) Sprungmarke vom Stabel und fuege sie in den Assemblercode ein, also
Marke_1 :
Dann gibt es auch noch Schleifen. Da ist bei der Uebersetzung manchmal das Count-Register involviert. Nur Switch Case ist ein wenig vertrackter. Man kann aber auch Steuersequenzen auf dem Stack unterbringen. Literaturtip: Drachenbuch, die Seite mit dem LR1-Algorithmus. Ist aber eher als Anregung zu verstehen, denn als Anleitung.
Datentypdeklarationen werden wahrscheinlich auch mit einem Stapel und mit einem Eintrageverzeichnis aufgebaut. Also so Zeug wie verschachtelte Structs, was dann schon ins Pseudo-Komplexe ausarten kann.
Ob ein Compiler zu Maschinencode oder zu Bytecode uebersetzt, steht jedem frei. Ein Bytecodeinterpreter ist nichts weiter als ein Programm, das anhand des Befehlssatzes einen Prozessor simuliert. So wie man einem Emulator ein Set Variablen fuer die Register des zu simulierenden Prozessors mit auf den Weg gibt, mit denen er dann den Speicher der zu emulierenden Maschine genauso manipuliert, wie deren Prozessor es tun wuerde. Die Schnittstelle zur Aussenwelt ist bei einer Emulation die emulierte Peripherie und bei einem Bytecodeinterpreter sind es einige Spezialroutinen oder Containervariablen.
Man kann auch mit Codegeneratoren oder von Hand im Quellcode schaffen, aber viele Entwickler schreiben Bytecodeinterpreter, damit sie nicht dauernd im Hauptprogramm ( der "Engine") rumpfuschen muessen.
Zum Thema "lexikalischen Analyse" stand in meinem ausgeliehenen Drachenbuch von 1989 was ganz brauchbares drin. Scanner: Lese ein Zeichen, gehe anhand dieses Zeichens in einen anderen Zustand über, lese weiter und immer so weiter und gebe bei einem bestimmten Zustand das passende Token aus (das man dann wohl in eine Datenstruktur einliest). Hätte man also z.B. " a1 ", dann wäre das Leerzeichen die Ursache für Zustand 1, das a führte dann bei Zustand 1 zu Zustand 2, käme nun eine Zahl, ergäbe sich Zustand 3, beim Leerzeichen würde er das Token a1 ausgeben und wäre dann wohl wieder bei Zustand 1. Für jeden Zustand können nur bestimmte Zeichensorten folgen, die dann wiederum abhängig vom Zustand eine Zustandsänderung forcieren.
Noch was zu den Eingrenzregeln: manchmal hängen sie auch von den Ausdruck umgebenden Zeichen ab, die aber dann nicht ersetzt oder "reduziert" werden. Pointer haben zusätzlich die Information gespeichert, ob sie zu referenzieren sind. Datentyp und sonstige Angaben stehen auch in der Datenstruktur für die Tokens. Die Datenstruktur ist linear. Einfach ein Struct-Array von nebeneinanderliegenden Tokens mit diversen zusätzlichen Angaben.
(nicht signierter Beitrag von 87.143.79.37 (Diskussion) 02:59, 25. Jul 2015 (CEST))
- Und was genau willst du uns damit sagen? --Sebastian.Dietrich ✉ 09:47, 25. Jul. 2015 (CEST)
"Keine Verbesserung des Artikels"
BearbeitenWarum sollte das Erwähnen von Synonymen, die in der Literatur auftauchen, keine Verbesserung sein? -Random187056 (Diskussion) 05:02, 9. Mär. 2016 (CET)
Böse Links
BearbeitenLinks 17 (Transcompiler) und 18 (Transpiler) sind offenbar problematisch. --91.64.172.54 (ohne (gültigen) Zeitstempel signierter Beitrag von 91.64.172.54 (Diskussion) 00:12, 13. Dez. 2021 (CET))
"Lexem"
BearbeitenDieser Begriff ist hier undefiniert. In einer früheren Version des Artikels Lexem war eine Erwähnung von Kompilerbau mit dabei, die hab ich jetzt dort rausgemacht, weil es nicht dazupasste, und durch einen Verweis auf diesen Artikel hier ersetzt. Bitte also hier eine passende Definition einfügen; Verlinkung nach Lexem ginge also auf einen rein linguistischen Artikel, der als Hintergrund für die Bedeutung in der Informatik hilfreich sein mag, es aber nicht wie hier nötig definiert. --Alazon (Diskussion) 22:46, 9. Jun. 2023 (CEST)