Dynamische Struktur: Zeichenstrom => Lexikalische Analyse (Scanning) => Tokenstrom => Syntaxanalyse (Parsing) => Syntaxbaum => Semantische Analyse (Typprüfung, etc) => Zwischensprache => Optimierung => Codeerzeugung => Maschinencode
Mehrpass-Compiler: Jede Phase liest und schreibt in eine Datei. Nützlich bei zu wenig Hauptspeicher, komplexen Programmen oder für eifache Portierbarkeit.
Einpass-Compiler: Zielprogramm wird direkt aus Quellprogramm erzeugt.
Front-End: sprachabhängig => Scanning, Parsing, Sem. Analyse.
Back-End: maschinenabhängig => Codeerzeugung
Quellcode => Front-End => Zwischensprache/Datenstruktur => Back-End => Maschinencode
Führt das Quellprogramm direkt aus:
Quellcode => Scanner => Parser => Interpretation
oder mit einer virtuellen Maschine welche den Code interpretiert und eine physische Maschine simuliert:
Quellcode => Compiler => Zwischencode => VM
Just-In-Time compilation heisst, dass der Code für die virtuelle Maschine zur Ladezeit in Maschinencode übersetzt wird. Effektiv wird dann der Maschinencode ausgeführt, was schneller ist.
all-in-one: Code wir beim Laden übersetzt. Verzögert den Programmstart.
incremental: Code wir vor der ersten Ausführung übersetzt (z.B. auf Methoden-Ebene).
hot-spot: Code wird interpretiert und das Programm startet sofort. Häufig verwendete Abschnitte werden in Maschinencode übersetzt.
Scanner: Liefert Tokens aus dem Quelltext
Parser: Steuert die gesamte Übersetzung
Symbolliste: Verwaltet deklarierte Namen und Typen
Codeerzeugung: Erzeugt Maschinencode
Terminalsymbole (TS): Werden nicht zerlegt (e.g. if, >=, ident, number)
Nonterminalsymbole (NTS): Werden zerlegt (e.g.Condition, Statement, Type)
Produktionen: Ableitungsregel (e.g. Statement = Designator = Expr;)
Startsymbol: Oberstes NTS (e.g. Expression, Java, CSharp)
Extended Backus-Naur Form
Symbol | Bedeutung | Beispiele |
---|---|---|
String | beddeutet sich selbst | =, while |
Name | T- oder NT-Symbol | ident, Statement |
= | trennt Regelseiten | A = b c d . |
. | schliesst Regel ab | |
| | trennt Alternativen | a | b | c -> a oder b oder c |
(…) | fasst Alternativen zusammen | a (b | c) -> ab | ac |
[…] | Option | [a]b -> ab | b |
{…} | Wiederholung | {a}b -> b | ab | aab | … |
̣Konvetion
Alphabet: Menge der TS und NTS einer Grammatik
Kette: Endliche Folge von Symbolen aus einem Alphabet -> α, β,…
Leere Kette: Kette, die kein Symbol enthält -> ε
Phrase: Aus NTS ableitbare Kette (e.g. ident * Factor)
Satzform: Aus dem Startsymbol ableitbare Kette (e.g. Term + Factor * ident + Term)
Satz: Satzform, welche nur aus TS besteht (e.g. ident * number + ident)
Sprache (Formale Sprache): Menge aller Sätze einer Grammatik (meist unendlich), e.g. Sprache Java ist Menge aller gültigen Java Programme
Eine Produktion is rekursiv, wenn A -> w1 A w2
Direkte Rekursion
A = b | A a.
=> A -> A a -> A a a
A = b | a A.
=> A -> a A -> a a A
A = b | "(" A ")".
=> A -> (A) -> ((A))
Indirekte Rekursion: Expr -> Term -> Factor -> "(" Expr ")"
Linkrekursion stört bei der Topdown-Syntaxanalyse
Umwandlung von Rekursion in Iteration: E = T | E "+" T
=> EBNF-Regel E = T { "+" T }.
Hierarchie von Noam Chomsky 1956
Im Übersetzungsbau sind nur Klasse 2 und 3 relevant
Zeigt die Ableitungsstruktur für einen Satz einer Grammatik
Abstrakter Syntaxbaum (Abstract Syntax Tree)
Expression Baum
Eine Grammatik ist mehrdeutig, wenn man für einen Satz mehrere Satzbäume angeben kann -> sind zur Syntaxanalyse ungeeignet
e.g. id * id * id
kann mit zwei Syntaxbäume dargestellt werden
Grammatik kann umgeformt werden, sodass nur eine Reihenfolge zulässig ist
Inhärente Mehrdeutigkeit -> lässt sich keine eindeutige Grammatik finden (e.g. Dangling Else)
Grammatik ist regulär, wenn sie sich durch Regeln der folgenden Art ausdrückt
A = a.
A = b B.
mit a,b in TS und A,B in NTS
Ident = letter
| letter Rest.
Rest = letter
| digit
| letter Rest
| digit Rest.
oder wenn sie sich durch eine einzige EBNF-Regel ohne rekursion ausdrücken lässt
Ident = letter { letter | digit }.
Kann keine Klammerstrukturen ausdrücken -> keine Zentralrekursion möglich, für das braucht man kontextfreie Grammatiken
a b
(a | b)
(a)? ε | a
(a)* ε | a | aa | ...
(a)+ a | aaa | aaa | ...
Automat zur Erkennung einer regulären Sprache (DFA = deterministic finite automaton)
Scanner als DFA: Beginnt nach jedem erkannten Symbol wieder in Zustand 0
Nichtdeterministischer DFA (NDFA)
Simon Anliker Someone has to write all this stuff.