Übersetzertechnik (in Arbeit!!!) © Günter Riedewald Die Folien sind eine Ergänzung der Vorlesung und nur für den internen Gebrauch konzipiert.
bersetzertechnik (in Arbeit!!!) Gnter RiedewaldDie Folien sind eine Ergnzung der Vorlesung und nur fr den internen Gebrauch konzipiert.
MotivationProgrammiersprachen als wichtiges Mittel der Softwaretechnik Weiterentwicklung der Softwaretechnik erfordert neue Sprachen einschlielich deren ImplementationProgrammiersprachen:- universell (Universalsprachen, general purpose languages): allgemein einsetzbar und unabhngig von einem konkreten Einsatzgebiet; Compilerentwicklung durch Spezialisten
- spezialisiert (Fachprogrammiersprachen, Spezialsprachen, special purpose languages, domain specific languages): in Syntax und Semantik zugeschnitten auf ein bestimmtes Fachgebiet; wegen stetig wachsendem Bedarf Entwicklung von Compilern/Interpretern auch durch NichtspezialistenProbleme des bersetzerbaus treten auch in anderen Gebieten der Informatik auf (z.B. XML)Abstrakte Betrachtung einer bersetzung:- Analyse der Struktur der Eingabedaten- Strukturabhngige Erzeugung der Ausgabedaten
Gute Kenntnisse ber Programmiersprachen und deren Compiler als Voraussetzung fr QualittssoftwareDidaktische Grnde:- Exemplarisches Vorgehen fr die Entwicklung grerer Softwaresysteme: klarer logischer Aufbau, Modularisierung, Nutzung von Werkzeugen, Wartbarkeit, Wiederverwendbarkeit- Fachbergreifende Rolle bzgl. Voraussetzungen und eingesetzten Techniken: Automatentheorie, Theorie der formalen Sprachen, Theorie der Programmiersprachen, Prinzipien der Softwaretechnik, Rechnerarchitektur/ Rechnersysteme ...
- Enger Zusammenhang zwischen Theorie und Praxis: gute theoretische Basis als Voraussetzung der Automatisierung der Compilerentwicklung Vorbildcharakter fr andere Informatikbereiche
LiteraturA.V. Aho, J.D. Ullman: The Theory of Parsing, Translation and Compiling, Prentice Hall, 1972
A.V. Aho, J.D. Ullman: Principles of Compiler DesignAddison-Wesley, 1977
A.V. Aho, R. Sethi, J.D. Ullman (2007 zustzlich: M. S. Lam): Compilers Principles, Techniques and Tools, (Drachenbuch), Addison Wesley, 1986, 2007
A.V. Aho, R. Sethi, J.D. Ullman: Compilerbau, (Drachenbuch), Addison-Wesley, 1988, 1990
H. Alblas, A. Nymeyer: Practice and Principles of Compiler Building with C, Prentice Hall, 1996
A. W. Appel: modern compiler implementation in Java (in C) basic techniques, Cambridge University Press, 1997
J. Elder: Compiler Construction A Recursive Descent Model, Prentice Hall, 1994
D. Gries: Compiler Construction for Digital Computers, Wiley, 1971In Russ.: Konstruirovanije kompiljatorov dlja cifrovych vyislitelnych main, Mir, 1975
J. Holmes: Object-Oriented Compiler Construction, Prentice-Hall, 1995
U. Kastens: bersetzerbau, Oldenbourg Verlag, 1990
H. Loeper, W. Otter, H.-J. Jkel: Compiler und Interpreter fr hhere Programmiersprachen, Akademie-Verlag, 1987
K. C. Louden: Compiler Construction Principles and Practice, PWS Publ. Com., 1997
S. S. Muchnik: Advanced Compiler Design and Implementation, Morgan Kaufmann Publishers, 1997
S. Naumann, H. Langer: Parsing, Teubner Stuttgart, 1994
P. Rechenberg, M. Mssenbeck: Ein Compiler-Generator fr Mikrocomputer, Hanser Verlag, 1985
W.M. Waite, G. Goos: Compiler Construction, Springer, 1984
D.A. Watt: Programming Language Processors, Prentice Hall International Series in Computer Science, 1993
D.A. Watt, D. F. Brown: Programming Language Processors in Java Compilers and Interpreters, Prentice-Hall, 2000
R. Wilhelm, D. Maurer: bersetzerbau Theorie, Konstruktion, Generierung, Springer-Lehrbuch, 1992
N. Wirth: Compilerbau, Teubner Studienbcher Informatik, Teubner Stuttgart, 1986
P. D. Terry: Compilers & Compiler Generators An Introduction with C++, Intern. Thomson Computer Press, 1997
H. Zima: Compilerbau I, II , BI Mannheim, Reihe Informatik 36,37, 1982, 1983
Translatoren - ArtenAssemblierer (Assembler): bersetzt aus einer Sprache niederen Niveaus (Sprache mit symbolischer Adressierung, Assemblersprache) in Maschinensprache meist im Verhltnis 1:1Makroassembler: bersetzt aus einer Sprache niederen Niveaus in Maschinensprache meist im Verhltnis 1:n mit n 1Compiler: bersetzt aus Sprache von hohem Niveau in Maschinensprache (letztendlich)
Prprozessor: bersetzt aus Obermenge zu einer Sprache in AusgangsspracheTranslator auf hohem Niveau: bersetzt aus Sprache hohen Niveaus in andere Sprache hohen NiveausDecompiler (Disassembler): Regeneriert Quellcode aus ZielcodeSelf-resident translator: Erzeugung von Zielcode fr die Wirtsmaschine (host)Cross-translator: Erzeugung von Zielcode fr andere MaschineInterpreter: anweisungsweise bersetzung und sofortige Ausfhrung von Quellcode
Interpretativer Compiler: bersetzung aus einer Sprache hohen Niveaus in eine Zwischensprache mit anschlieender InterpretationEmulator: Interpretation des Codes einer anderen Maschine
1 bersetzerbau - Einfhrung1.1 Symbolische DarstellungenbersetzerbersetzungProgramm P bersetzerProgramm Pvon Pin Quell-in Iin Zielsprache Zsprache Q
AbarbeitungEingabe-P Ausgabe-von Pdatenin Z daten
InterpretationProgramm P Inter-Ausgabedatenvon Pin Quell-pretersprache QEingabedaten
T-Diagramme (tombstones)bersetzerP PQ Q Z Z I
Abarbeitung eines ProgrammsE P A Z
InterpreterE P A Q Q Z
Modifikationen der T-DiagrammeProgramm P in L geschriebenPL
Maschine MM
Bezeichneter Compiler
1.2 Einfhrungsbeispielbersetzung von Pascal in P-CodeP-Code: - Sprache der P-Maschine (abstrakter Rechner) - Zwischensprache in Compilern
P P PPascal Pascal P-Code P-Code P-Code M M M M
1.2.1 Implementierungsprinzipien fr ausgewhlte imperative SprachkonzepteImperative KonzepteVariablenkonzept:- Variable als Modell fr einen Speicherplatz- Mglichkeit des Lesens und der Wertnderung (Schreiben) Compilersicht: Speicherplatzzuordnung + Zugriff zum Wert als Ganzes oder in Teilen + Lebensdauer + Gltigkeitsbereich (Zugriffsrechte)Strukturierungskonzept fr Datenstrukturen Compilersicht: Abspeicherungskonzept + Zugriff
Sprachkonzepte zur Ablaufsteuerung Compilersicht: Umsetzung in Sprnge unterschiedlicher ArtProzedurkonzept:- Nichtrekursive Prozedur Compilersicht: Ersetzen des Aufrufs durch Anweisungen der Prozedur oder Sprnge mit Rckkehr zur Anweisungsfolge- Rekursive Prozedur Compilersicht: mehrere gleichzeitige Aufrufe erfordern mehrere Inkarnationen des Speicherbereichs der Prozedur (Verwendung von Kellertechnik)- Parameterbergabe Compilersicht: zustzliche Anweisungen
P-MaschineDatenspeicherSTORE0SP maxstr
ProgrammspeicherCODE0 PC codemax
Befehlsausfhrung:Steuerung durch Steuerschleifedo PC := PC + 1;Ausfhrung des Befehls in CODE[PC-1]od- Initialisierung PC := 0
1.2.2 Ausgewhlte Sprachkonstrukte und ihre bersetzungVoraussetzungen:Die Kontextbedingungen sind erfllt (durch semantische Analyse geprft).Alle Konstrukte sind syntaktisch eindeutig zerlegbar (Durchfhrung durch syntaktische Analyse).
Ausdrckebersetzungsfunktion:- code: Ausdruck x Umgebung P-Code(Umgebung: u: Variablen Adressen)
Unterschiedliche Ausdruckbehandlung auf linker und rechter Seite einer Zuweisung codeR : bersetzung in Befehle zur Berechnung eines Werts codeL : bersetzung in Befehle zur Berechnung einer Adresse
Wertzuweisungcodex := eu = codeLxu ; codeReu ; sto TT Typ; u Umgebung; x Variable; e Ausdruck
Wirkung von sto:STORE vor wAbarbeitung SP-2SP
Adresse von x (u(x) = ); w Wert von e
STORE nach w Abarbeitung SP
codeRe1 + e2u = codeRe1u; codeRe2u; add TT Typ; e1, e2 Ausdrcke
Wirkung von add: STORE vor w1 w2Abarbeitung SP
STORE nach wAbarbeitungw = w1 + w2 SP
codeRcu = ldc T c, c Konstante vom Typ T
STORE vor Abarbeitung SP
STORE nach cAbarbeitung SP
codeLxu = ldc a u(x) , x Variable
STORE vor Abarbeitung SP
STORE nach u(x)Abarbeitung SP
codeRxu = codeLxu; ind T = ldc a u(x); ind T , x VariableSTORE vorw Abarbeitungu(x) = SP
STORE nachw Abarbeitungvon ldc a u(x) SP
STORE nachw wAbarbeitungvon ind T SP
Beispiel: bersetzung von x := (x + (3 + y)) , x, y vom Typ i
code x := (x + (3 + y))u = codeL xu; codeR(x + (3 + y))u; sto i =ldc a u(x); codeR xu; codeR(3 + y)u; add i; sto i =ldc a u(x); ldc a u(x); ind i; codeR3u; codeRyu;add i; add i; sto i =ldc a u(x); ldc a u(x); ind i; ldc i 3; ldc a u(y); ind i; add i; add i; sto i
Abarbeitungsschritte:u(x) = , u(y) = , w1 Wert von x, w2 Wert von y, w3 = 3 + w2,w4 = w1 + w3STORE-Zustnde
w1w2kw1w2k w1w2k w1w2k w1w1w2k w1 3w1w2k w1 3 w1w2k w1 3 w2w1w2k w1 w3w1w2k w4w4w2k
Bedingte Anweisungencodeif e then st1 else st2 fiu = codeReu; fjp l1; codest1u; ujp l2; l1: codest2u; l2:... Wirkung von fjp l1:k falsekPC := l1k truek
Wirkung von ujp l2: PC := l2
Anweisungsfolgencodest1; st2u = codest1u; codest2u
Wiederholungencodewhile e do st odu = l1: codeReu; fjp l2; codestu; ujp l1; l2:...
Beispiel: codewhile a > b do a := a - b odu = l1: codeRa > bu; fjp l2; code a := a - b u; ujp l1; l2:...=l1: ldc a u(a); ind i; ldc a u(b); ind i; grt i; fjp l2; ldc a u(a); ldc a u(a); ind i; ldc a u(b); ind i; sub i; sto i; ujp l1; l2:...
1.3 Logische CompilerstrukturPhysische Compilerstruktur
Treiber
SyntaktischeSemantischeSemantischeAnalyseAnalyseSynthese
LexikalischeAnalyse
Physische Compilerstruktur (Fortsetzung)
Treiber
SyntaktischeAnalyse
LexikalischeSemantischeSemantischeAnalyseAnalyseSynthese
Logische Compilerstruktur (1)
QuellprogrammAnalyseLexikalischerDatentabellenAnalysatorCodierteTerminalfolgeSyntaktischerDatenmoduleAnalysatorSyntaxbaumSemantischerAnalysatorDekorierterSyntaxbaumSemantischeSyntheseZielprogramm
Logische Compilerstruktur (2)QuellprogrammLexikalischeAnalyse
Symbol-SyntaktischeFehlerbehandlungtabellen-AnalyseverwaltungSemantischeAnalyse
Zwischencode-Code-Code-ErzeugungOptimierungErzeugung
Zielprogramm
2 Lexikalischer AnalysatorAufgabe: Transformation des Quellprogramms aus einer Zeichenfolge in eine codierte Folge von Terminalen (Tokenfolge, Grundsymbolfolge) mit Sammlung spezieller Informationen in TabellenTeilaufgaben:Auffinden und Erkennen eines Lexems ( Terminal)Codierung der LexemeAuslassung berflssiger ZeichenfolgenErstellung von Datentabellen
2.1 Auffinden und Erkennen von Lexemen
Fakt: Lexeme sind berwiegend durch regulre Grammatikregeln beschreibbar. Es existieren endliche Automaten, die genau diese Lexeme akzeptieren.Beispiel: ::= 0|1|...|9|0 |...|9 ::= A|...|Z|A |...|Z ::= A|...|Z|0|...|9| A |...|9 ::= +|-|(|)|/|/ |* |: |;|, ::= / ::= * ::= =
Endliche Automaten zu den Regeln:0,...,9SgZ0,...,9
A,...,ZSIdA,...,9
+ - ( ) ; ,**SSSt
//:=Sgl
Endlicher Automat fr Akzeptanz aller Lexeme:A,...,ZA,...,Z,0,...,9
0,...,90,...,9
+ - ( ) ; ,
**
//
:=
2.2 Kodierung der Lexeme KodierungLexem KodierungLexem1Identifikator9**2ganze Zahl10(3BEGIN11)4END12//5REAL13:=6/14;7+15.8-
Semantische AktionenADDAufsammeln von Zeichen eines Lexems in einer Puffervariablen AGCLesen des nchsten Quellprogrammzeichens, Zwischenablage in der Variablen Char sowie Bestimmung der Art des ZeichensLOOKUPBestimmung der Kodierung des in A abgelegten Lexems gem Tabelle der internen Kodierung (Kodierung 1 bei Nichtvorhandensein)OUT(C,A)Ausgabe eines Lexems (in A) zusammen mit seiner Kodierung (in C)GPCberlesen aller bedeutungslosen Zeichen und Fortsetzung wie GC sowie Lschen von A
Endlicher Automat mit semantischen Aktionen:A,...,Z LOOKUP(A,C);OUT(C,A) ADD;GCA,...,Z,0,...,9ADD;GC0,...,9OUT(2,A)ADD;GC0,...,9GPCADD;GC+ - ( ) ; ,ADD;GCLOOKUP(A,C);OUT(C,A)**ADD;GC ADD;GCOUT(9,A)/ADD;GC /OUT(6,A) ADD;GCOUT(12,A):=ADD;GCADD;GCOUT(13,A)
2.5 Automatische Erzeugung von lexikalischen Analysatoren
LexembeschreibungLexikalischer(regulre Ausdrcke,Analysator -semantischeRahmensystemAktionen)
GeneratorSteuerung
Lex-Spezifikation
%% {}...%%
Beispiel:# include y.tab.hextern int yyz, yyli;extern symbol *lookup(), *install();%%\n{yyli ++;}[ ];[0-9][0-9]*{symbol *s;if ((s=lookup(yytext))==0) s=install(yytext); ...; return (ZAHL);}if{return (IF);}...true{keys *k; k=lookkey(yytext); yylval.yyk=k; return (TRUE);}[a-z][a-z 0-9]*{symbol *s;if ((s=lookup(yytext))==0) s=install(yytext); yylval.yysym=s;return (IDENTIFIKATOR);}%%
3 Syntaktische AnalyseBeispiel:Aus Id ( Aus )Aus Id [ Aus ] Aus Id Id aId fId z
Syntaxbaum von f(a[z])AusTop-down Analyse11IdAus1215Id Aus 13 14IdBottom-up Analyse 16f(a[z])
3.1 Kellerspeicher in der SyntaxanalyseTop-down Analyse - GrundalgorithmusVoraussetzung: Verwendung eines AnalysekellersSchritte des Algorithmus:Startsymbol in den KellerWiederholung folgender Schritte bis zum Erreichen eines leeren Kellers:- Nichtterminal an Kellerspitze: Expansion (Ersetzen des Nichtterminals durch rechte Seite einer geeigneten Syntaxregel)- Terminal an Kellerspitze: Vergleich mit aktuellem Element des analysierten Wortes; bei Gleichheit Streichen aus dem Keller, nchstes Element des Wortes wird aktuelles Element;bei Ungleichheit Backtracking
Beispiel:Top-down Analyse von f(a[z])
Aktuelles ElementKeller (Spitze links)Operationf(a[z])AusAus Id ( Aus )f(a[z])Id ( Aus )Id ff(a[z])f ( Aus )2x Vergleicha[z])Aus )Aus Id [ Aus ]a[z])Id [ Aus ] )Id aa[z])a [ Aus ] )2x Vergleichz])Aus ] )Aus Id zz])z] )3x Vergleich
Bottom-up Analyse - GrundalgorithmusSchritte des Algorithmus:Start mit leerem KellerWiederholung folgender Schritte, bis das Startsymbol allein im Keller ist:- Reduktion: nur mglich, wenn an der Kellerspitze die rechte Seite einer Regel ist ( Ersetzen durch linke Seite)- Einlesen (Verschiebung): Einlesen des nchsten Elements des Wortes in den Keller
Beispiel: Bottom-up Analyse von f(a[z])
RestwortKeller (Spitze rechts)Operationf(a[z])Lesen f(a[z])fReduktion f zu Id(a[z])IdLesen (a[z])Id (aReduktion a zu Id[z])Id ( IdLesen [z])Id ( Id [zReduktionen z zu Id, Id zu Aus])Id ( Id [ AusLesen ])Id ( Id [ Aus ]Reduktion Id [ Aus ] zu Aus)Id ( AusLesen )Id ( Aus )Reduktion Id ( Aus ) zu AusAus
3.2 Deterministische Syntaxanalyse3.2.1 Top-down Verfahren - Methode des rekursiven Abstiegs
Grundmethode:Idee: Syntaktische Regel A ...wird als Prozedur zur Erkennung von Zeichenketten aus L(A) betrachtet, wobei die rechte Seite der Regel die Struktur vorgibt:Terminal: erwartetes TerminalNichtterminal: Aufruf der entsprechenden ProzedurAlternativen: Code-Alternativen in der Prozedur
Beispiel: Prozedur zur Regel T ( Aus )| [ Aus ]procedure T;begincase token of(: match( ( ); Aus; match( ) );[: match( [ ); Aus; match( ] );else error;end case;end T;Vor.: token enthlt aktuelles Terminal der zu analysierenden Zeichenkette
Definition der Prozedur match:
procedure match(expectok);beginif token = expectokthen gettokenelse errorfi;end match;gettoken liest das nchste Zeichen aus der Zeichenkette und ordnet es token zu.
Konstruktion der ZerlegungsprozedurenN X : procedure N; bedeutet Anweisungen zur Erkennung von X, wobei- X = einer Leeranweisung- X = t (Terminal, token) match(t)- X = M (Nichtterminal) M (Aufruf der Prozedur)- X = A B ;
- X = A| B case token ofe1: ;e2: ;else error;end case;e1 DS(N, A), e2 DS(N, B)- X = A*while token DS(N, A) do odentspricht.
Definition der Entscheidungsmenge (director set)Vor.: A 1| ...| nDS(A, i) = {a T| a FIRST1(i) (i * a FOLLOW1(A))}
Beispiel: 1A I T 11/12/13T ( A )| [ A ]| 14/15/16I a| f| zDS(T, 1) = { ( }DS(I, 1) = {a}DS(T, 2) = { [ }DS(I, 2) = {f}DS(T, 3) = { ], ), }DS(I, 3) = {z}
Top-down Analyse von f(a[z])
Keller ()ZeichenketteKeller ZeichenketteAf(a[z])[ A ] )I TA ] )z])f TI T ] )T(a[z])z T ] )( A )T ] )])A )a[z])] )I T )))a T )T )[z])
LL(k)-Grammatik G = (N, T, P, S)G ist eine kontextfreie GrammatikFr beliebige Paare von Linksableitungen S + A * xS + A * ymit FIRSTk(x) = FIRSTk(y)gilt = .
Starke LL(k)-Grammatik G = (N, T, P, S)
Fr jedes Paar von Regeln aus P A x und A y(A x | y)giltFIRSTk(x FOLLOWk(A)) FIRSTk(y FOLLOWk(A)) =
Tabellengesteuerte LL(1)-AnalyseAnalysealgorithmus:Eingabe: Analysetabelle M, Zeichenkette w T*Ausgabe: Fehlermeldung oder RegelnummernfolgeStartkonfiguration: (w, S#, )Schritte:1. (ax, A, r) (ax, , r i) fr M(A, a) = (, i)2. (ax, a, r) (x, , r), a T3. (, #, r) erfolgreicher Abschluss4. Fehler sonst
Analysetabelle fr obige Grammatik und Analyse von f(a[z])
afz( [ ) ] AIT,1IT,1IT,1T(A),11 [A],12 ,13 ,13 , 13Ia,14f,15z,16
(f(a[z]), A#, ) (f(a[z]), IT#, (1)) (f(a[z]), fT#, (1 15)) ((a[z]), T#, (1 15)) ((a[z]), (A)#, (1 15 11)) (a[z]), A)#, (1 15 11)) (a[z]), IT)#, (1 15 11 1)) (a[z]), aT)#, (1 15 11 1 14)) ([z]), T)#, (1 15 11 1 14))
([z]), T)#, (1 15 11 1 14)) ([z]),[A])#, (1 15 11 1 14 12)) (z]), A])#, (1 15 11 1 14 12)) (z]), IT])#, (1 15 11 1 14 12 1)) (z]), zT])#, (1 15 11 1 14 12 1 16)) (]), T])#, (1 15 11 1 14 12 1 16)) (]), ])#, (1 15 11 1 14 12 1 16 13)) (), )#, (1 15 11 1 14 12 1 16 13)) (, #, (1 15 11 1 14 12 1 16 13))
Deterministische Syntaxanalyse3.2.2 Bottom-up Verfahren - Einfache PrzedenzEinfache PrzedenzRelationen:R S: Es existiert eine Regel U ...V W... Und V + ...R sowie W * S... .
Przedenzmatrix fr Beispielgrammatik
Aus Id()[]afzAusId> >( f>> >>z>> >>
Analyseprozess unter Nutzung der PrzedenzmatrixWiederholung folgender Schritte:1. Einspeicherung der Zeichen der Zeichenkette in den Keller, bis an der Kellerspitze ein Zeichen E steht , das in der Relation > mit dem nchsten einzulesenden Zeichen steht2. Abstieg im Keller bis zum Erreichen des ersten Zeichens A mit y
Analyse von f(a[z])
KellerRestwort( a [ z ] )
LR(k)- AnalyseCharakterisierung:Entspricht Grundverfahren modifiziert durch Vorausschau auf k ElementeDarstellung durch eine Zustandsmenge zusammen mit bergangsfunktion in Form einer Analysetabelle, bestehend aus Aktionstabelle (Einlesen und Reduktion) und Sprungtabelle (Fortsetzung nach Reduktion)
Beispiel: Konstruktion der Analysetabelle frT A A I ( A )| I [ A ]| II a| f| zZustnde und bergnge des charakteristischen endlichen AutomatenZustand Q0:Zustand Q1:Zustand Q2:T . A T A .A I .( A )A .I ( A )A I .[ A ]A .I [ A ]A I.A .IZustand Q3:Zustand Q4:I .aI a. I f. I .fI .z Zustand Q5: I z.
Zustand Q6:Zustand Q7:Zustand Q8:A I ( .A )A I [ .A ]A I ( A .)A .I ( A )A .I ( A )A .I [ A ]A .I [ A ]Zustand Q9:A .IA .IA I [ A .]I .aI .aI .fI .fZustand Q10:I .zI .zA I ( A ).
Zustand Q11:A I [ A ].
Q0A I Q1afzQ2 Q3 Q4 Q5[ ( IQ7afzA I af zQ9Q6 Q2 Q3Q4 Q5 A ]Q8 )Q11Q10Charakteristischer endlicher Automat
Analysetabelle ( [afz]) A I
Q0Q3 Q4 Q5 Q1 Q2Q1 T AQ2 Q6 Q7 ... A I ...Q3 ... I a ...Q4 ... I f ...Q5 ... I z ...Q6 Q3 Q4 Q5 Q8 Q2 Q7 Q3 Q4 Q5 Q9 Q2Q8Q10Q9Q11Q10... A I ( A ) ...Q11... A I [ A ] ...
Syntaxanalyse unter Verwendung einer Analysetabelle (AT):Verwendung zweier Keller: Elementekeller (EK) wie im Grundalgorithmus und Zustandskeller (ZK)Start der Analyse: Q0 im ZustandskellerEnde der Analyse: Altes Startsymbol im Elementekeller; Endezeichen als aktuelles ZeichenSchritte:1. Einlesen: Aktuelles Zeichen der Eingabe in EK und neuer Zustand gem AT (bestimmt aus altem Zustand und Zeichen) in ZK2. Reduktion:- Reduktion an EK-Spitze gem Regel aus AT (bestimmt durch alten Zustand und aktuelles Zeichen)- Entfernen von Zustnden aus ZK (Anzahl gleich Anzahl der Elemente auf r. S. der Regel)- Neuer Zustand gem AT (bestimmt durch Zustand an ZK-Spitze und Nichtterminal auf l. S. der Regel) in ZK
Beispiel: Analyse von f ( a [ z ] ) ElementekellerRestwortZustandskeller Aktionf(a[z])Q0 Einlesenf(a[z])Q0Q4ReduktionI(a[z])Q0Q2EinlesenI (a[z])Q0Q2Q6EinlesenI ( a[z])Q0Q2Q6Q3ReduktionI ( I[z])Q0Q2Q6Q2EinlesenI ( I [z])Q0Q2Q6Q2Q7EinlesenI ( I [ z])Q0Q2Q6Q2Q7Q5ReduktionI ( I [ I])Q0Q2Q6Q2Q7Q2ReduktionI ( I [ A])Q0Q2Q6Q2Q7Q9EinlesenI ( I [ A ])Q0Q2Q6Q2Q7Q9Q11ReduktionI ( A)Q0Q2Q6Q8EinlesenI ( A )Q0Q2Q6Q8Q10ReduktionAQ0Q1
Konflikte im charakteristischen endlichen AutomatenReduktion-Reduktion: zwei unterschiedliche Reduktionen im gleichen ZustandBeispiel: T S S a A bA A bA c
T . S a S a .A b A S a A .b b S a A b.S .a A b A .A b A A .b A A b. A .c S c
T S. A c.
Reduktion-Einlesen: Aus einem Zustand mit einer Reduktion fhrt eine mit einem Terminal bewertete Kante.Beispiel: siehe Zustand Q2 im charakteristischen endlichen Automaten des Standardbeispiels
GrammatikklassifizierungLR(0)-Grammatik: Der charakteristische endliche Automat ist konfliktfrei.
SLR(1)-Grammatik: Konflikte lassen sich auf der Basis von einem Element Vorausschau unter Nutzung der FOLLOW-Mengen auflsen.
Beispiele: Zustand Q2 im StandardbeispielA I .( A )Einlesen (bentigt werden ( oder [ ) oderA I .[ A ]Reduktion von I zu A?A I.
FOLLOW1(A) = { ), ], }, (, [ FOLLOW1(A) - Ist das aktuelle Zeichen ( oder [, dann erfolgt Einlesen.- Ist das aktuelle Zeichen aus FOLLOW1(A), dann erfolgt Reduktion.- Sonst liegt ein syntaktischer Fehler vor.Obiger Reduktion-Reduktion-Konflikt lt sich auflsen:FOLLOW1(S) = { } FOLLOW1(A) = { b }
LALR(1)-Grammatik: analog zur SLR(1)-Grammatik, aber mit Verfeinerung der FOLLOW-Mengen
Beispiel:dST S .
c A A cFOLLOW1(A) = { a, b}FOLLOW1 1 (A) = { b } A c.1 2 A c.FOLLOW1 2 (A) = { a }
a b a b
S d c a. S d A b. S A a. S c b.
LR(k)-Grammatik (-frei)
Fr beliebige Paare von AbleitungsfolgenS * w1 z w2 w1 v w2 , z v P, w2 T*S * w1 z w2 w1 v w2 , z v P, w2 T*mit w1 v = w1 v und FIRSTk(w2) = FIRSTk(w2)Folgt z = z und v = v.
Zustnde des charakteristischen endlichen Automaten fr LR(k)-GrammatikenErgnzung einer Situation A x. X z durch einen Kontext K, wobei folgende Eigenschaften erfllt sein mssen:Anfangszustand enthlt Situation S .w Zustand q enthalte Situation A u .X, K und zu X existieren die RegelnX w1 ; ...; X wn , dann enthlt q ebenfalls X .w1 , K; ...; X wn , K mit K= FIRSTk( K)
Enthlt der Zustand q die Situation A u. x , K , dann erfolgt ein bergang in einen Zustand mit der Situation A u. x , K
Konflikte im charakteristischen endlichen Automaten:Reduktion-Reduktion: Ein Zustand enthlt die Situationen A u. , K1 und A v. , K2 mit A B oder u v, aber t K1 K2Reduktion-Einlesen: Ein Zustand enthlt die Situation A u. , K und besitzt einen bergang mit dem Terminal t und t K .
Beispiel: LR(1)-Zustnde fr Standardbeispiele (Auswahl)
Q0: T .A Q0 Q2: A I.(A) , A .I(A) , A I.[A] , A .I[A] , A I. , A .I , I .a , {(, [, } I .f , {(, [, } I .z , {(, [, }
3.4 Syntaktische FehlerAufgaben der Fehlerbehandlung:Lokalisierung des FehlersKlassifizierung des FehlersFehlernachricht:- Fehlerposition- Grad oder Art des Fehlers- Genauere Angaben zum FehlerStabilisierung und Fortsetzung der Analyse
Fehlerposition:w T* und es existiert w T* , wobei w w L(G)(w lsst sich durch w zum Wort aus L(G) ergnzen)Fr w x, x T, existiert keine Ergnzung v T* , so dass w x v L(G). x ist eine Fehlerposition
Beispiel:In x * (3 z / y ; ist das ; eine Fehlerposition, da x * (3 z / y richtig ergnzt werden kann, aber x * (3 z / y ; nicht.
Bemerkungen:Bei LL(1)- und LR(1)-Verfahren der syntaktischen Analyse wird ein Fehler immer an einer Fehlerposition erkannt.Der Fehler muss nicht durch das Zeichen an der Fehlerposition verursacht worden sein.
3.5 Automatische Erzeugung von Syntaxanalysatoren
Kontextfreie GrammatikAnalysatorRahmen-programm
GeneratorTabellen
yacc-Spezifikation
%%
%%
4 Semantische Analyse4.1 Symboltabellen Einfache StrukturHashtabelle mit Verkettungstechnik
Beispiel:1DE2 0A1B03CAESAR4FAUL5 0F06D10C50frei
Symboltabellen mit abgetrennter SchlssellisteHashtabelle mit Verkettungstechnik und abgetrennter SchlssellisteBeispiel:12 00345 00600 frei
2 D E 3 A 1 B 6 C A E S A R 4 F A U L 1 F 2 D 1 2 C 5
Beispiel: Programm mit BlockstrukturBEGIN REAL a, b, c, d;...BEGIN REAL c, f;...L1:...END;BEGIN REAL g, d;...L2: BEGIN REAL a;... END;L3:...ENDEND
Symboltabelle mit Blockstruktur 1Beispiel: Symboltabelle fr obiges Programm
1 0 4 L1Blocknummer2 1 3f3 1 4cbergeordneter Block4 3 1aL3Anzahl EintragungenL2dAdressegdcba
Symboltabelle mit Blockstruktur 2Form der Listenelemente:DeklarationenBlockZeiger aufVerkettungVerkettungnummerInformationim BlockIdentifikatoren
BlockstrukturBlockAnfangbergeordneternummerBlockketteBlock
Beispiel: Symboltabelle zum obigen Programm
a14 / 1 / /b21 1 /c32 / 1 2 /d 43 71 3 / 5f 62 3 /g 73 / / 8L192 6 /L2 103 4 /L3 113 10 /
Blockstrukturtabelle
11 4 /22 9 133 11 144 1 3
4.2 Realisierung der semantischen AnalyseBeispiel: Attributierte Grammatik fr DeklarationsfolgenKontextfreie Basisgrammatik ::= VAR ; 0 ::= ; 1 ::= ::= ::= BOOL ::= INT
Kontextbedingung: Kein Identifikator darf mehrfach deklariert werden.
Zuordnung der AttributeAttributArtBedeutungZuordnungSvSymboltabellevorlufigSnSymboltabelle neu, IT(Identifikator, Typ)TTypIIdentifikatorerrortrue, false,
Semantische Regeln1.Sn := .Sn.error := .error.Sv := INIT(.IT)
20.Sn := 1.Sn 0.error := 1.error IN(0.Sv, .IT) 1.Sv := ENTRY(0.Sv, .IT), wenn IN(0.Sv, .IT)
3.Sn := .Sv .error := false4.IT := IDDECL(.I, .T)
5.T := bool 6.T := nt
Dekorierter Syntaxbaum von VAR INT x; BOOL y;{(x,int),(y,bool)}, false
VAR ; (x,int) {(x,int)}, {(x,int),(y,bool)}, false
;intx(y,bool) {(x,int),(y,bool)},INTx {(x,int),(y,bool)}, booly false
BOOLy
Schachtelung von ProgrammeinheitenBeispiel: ProgrammPROGRAM H;PROC B;PROC D;...; call C;...END B;END D;...call B;PROC A;END A;PROC C; ...; call A;...; call D;......; call D; END H;END C;
Statische Schachtelung mit SchachtelungstiefeH/0
D/1A/1
C/2B/2
Dynamische SchachtelungHAD
BC
D
Datenbereich (Prozedurschachtel, Kellerrahmen) einer Prozedur (eines Blocks) zur LaufzeitAllgemeiner AufbauFunktions Statischer Dynamischer alter EP Rcksprungwert Vorgnger Vorgnger Wert adresse
MPParameter Lokale Felder Zwischen(statisch) Variablen (semidyn.) ergebnisse
SPEP
Variablenadressierung: (Schachtelungstiefe, Relativadresse)Beispiel:PROGRAM H;Adressierung:VAR x1, y;In H: x1 (0, 5)PROC p; y (0, 6)VAR i, x1, k;In p: i (1, 5)...x1...x1 (1, 6)...k...k (1, 7)...y...END p;call p;...x1...END H;
Aktionen bei Eintritt in eine Prozedur q (p ruft q auf)Setzen des statischen Vorgngers von qSetzen des dynamischen Vorgngers von q (Anfangsadresse des Datenbereichs von p alter MP-Wert)Retten des alten EP-WertesBerechnung der aktuellen ParameterSetzen des MP-Registers auf Anfangsadresse des Datenbereiches von q (SP + 1)
Abspeicherung der RckkehradresseAusfhrung des Sprungs auf ersten Befehl des bersetzten q-Programms-----------------------------------------------------------------------------------Setzen des SP-RegistersBerechnung des EP-Wertes und Setzen des EP-Registers sowie berprfung auf mgliche Kollision zwischen Keller und Halde
Aktionen bei Verlassen der Prozedur q (Rckkehr nach p)
Freigabe des Datenbereichs bis auf eventuellen FunktionswertSetzen der MP-, EP- und SP-Register fr die Prozedur pRckkehr nach p
Beispiel: rekursiver FunktionsaufrufPROGRAM Fak;VAR r : integer;FUNCTION F(n: integer): integer;IF n = 1 THEN F := 1 ELSE F := n * F(n 1);END F;r := F(3);END Fak;
Adressierungr(0, 5)n(1, 5)F(1, 0)
bersetzung von Fak; lda i 0 6; ; M1: sto i;
bersetzung von F(n); lod i 0 5; ldc i 1; equ i; fjp l1; lda i 0 0;ldc i 1; sto i; ujp l2; l1: lda i 0 0;lod i 0 5; ; M2: mul i; sto i; l2:
Abspeicherung von DatenstrukturenMehrdimensionale FelderA: ARRAY [u1.. o1, ..., un.. on] OF
SpeicherabbildungsfunktionAdresse(A[i1, ..., in]) = Adresse(A[u1, ..., un])+ (i1 u1) * d2 * ...* dn+ (i2 u2) * d3 * ...* dn+ ...+ (in un) = k + v (di = oi ui + 1)
Semidynamische FelderBeispiel: semidynamische Felder in ALGOL 68begin...n := ...; ...; m := ...; ...begin [n] int A; [m] int B;...A[i] := B[j+3] * k;...end...end
Schablone (Felddeskriptor) eines semidynamischen FeldesA: ARRAY [u1.. o1, ..., un.. on] OF u1o1d1...unondnnkadr
adr = Adresse(A[u1, ..., un])k= u1 * d2 * dn + u2 * d3 * dn + ... + un
Datenbereich fr inneren Block0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 20 21 25 26
1 4 4 1 1 17 1 5 5 1 1 21 ... ...
Schablone fr ASchablone fr B
1 4 4 1 5 5 1 1 17 1 1 21
Voraussetzung: Zur Laufzeit gilt n = 4 und m = 5 .
Erzeugte Befehlsfolgen (im Beispiel):Aufbau des DB einschlielich der teilweise gefllten SchablonenBerechnung von n und der fehlenden Elemente der Schablone fr ANeuberechnung der ersten freien Adresse des freien dynamischen SpeicherteilsBerechnung von m und der fehlenden Elemente der Schablone fr BNeuberechnung der ersten freien Adresse des freien dynamischen SpeicherteilsAdressberechnung fr A[i] aus der Schablone fr AAdressberechnung fr B[j+3] aus der Schablone fr B
Datenmllbeseitigung (garbage collection)Arbeitsschritte:Zeigerverfolgung und Markierung besetzter Speicherbereiche SpeicherkarteHerstellung eines Adressbuchs (alte Adressen, neue Adressen)Zeigertransformation (auf neue Adressen)Komprimierung des Speichers (Auslassung von Mllbereichen)
ParameterbergabenReferenzaufruf (call by reference):PROC del(VAR t: Elem;...);Befehlsfolgen:BEGIN ...t := ...END;- Berechnung ...- Abspeicherung von aufdel(T,...); Platz von tTt
LDLDDB aufrufende ProzedurDB von del
Werteaufruf (call by value):PROC del1 (k: Key;...);Befehlsfolgen:BEGIN...z := k;...END;- Berechnung von w... aus adel1(a,...);- Abspeicherung vonk w auf Platz von k
LDww Wert von a
DB von del1
Werte-Resultatsaufruf (call by value-result):Kombination von call by reference und call by value mit nderung des aktuellen Parameters erst bei Rckkehr (zustzlicher Umspeicherungsbefehl)Tt
LDwLD wAufruf
LDwLD wRckkehr
DB aufrufende Prozedur DB aufgerufene Prozedur
Namensaufruf (call by name):Beispiele: ALGOL 60procedure p(x); integer x;begin ...i := 2; x := 9;...end;...array a[1 : 9];Realisierung:integer i;begin ......i := 2; a[i] := 9;i := 1;...p(a[i]);end
procedure R(X, I);begin I := 2; X := 5; I := 3; X := 1 end;...R(B[J * 2], J);
Realisierung:beginJ := 2;B[J * 2] := 5;J := 3;B[J * 2] := 1end
Konkreter Syntaxbaum abstrakter SyntaxbaumBeispiel: Ausdruck 5 * aKonkreter SyntaxbaumAbstrakte Syntaxbume*
num(5)id(a)
* *num(5) id(a) ...
... a 5
Quadrupel (Dreiadresscode)Allgemeine Form:[, , , ]mitOperand, Resultat: - Bezeichner (deklarierte oder temporre Variable) - Zahl (Konstante, Sprungziel) - leer (ohne Bedeutung)
Ausdrcke: [, , , ]Beispiel: [add-int, t1, t2, h]
Zuweisung:[sto-T, , , ] , T TypBeispiel: [sto-int, x, , y]
Unbedingter Sprung: [ujp, ]Bedingter Sprung: [fjp, , ]Ausfhrung des Sprungs zur Anweisung mit der Marke, wenn der Wert der Variablen false ist
If-Anweisung IF e THEN st1 ELSE st2 FI:Quad(e)Quadrupel zur Berechnung von e; Wert von e wird h1 zugewiesen[fjp, h1, l1]Quad(st1)Quadrupelfolge fr st1[ujp, l2]l1:Quad(st2)Quadrupelfolge fr st2l2: ...
Andere Darstellung von Marken: [label, ]
Beispiel: IF a < b THEN a := a + 1 ELSE b := b + 1 FI
[les-int, a, b, h1][fjp, h1, l1][add-int, a, 1, h1][sto-int, h1, a][ujp, l2]l1:[add-int, b, 1, h1][sto-int, h1, b]l2: ...
Tripel (Binrbaum)Allgemeine Form:(, , )Reprsentation des Ergebnisses durch das Tripel selbst
Graphische Darstellung:Operator
Operand1 Operand2
Beispiel: IF a < b THEN a := a + 1 ELSE b := b + 1 FI
(1)(les-int, a, b)(2)(fjp, (1), l1)(3)(add-int, a, 1)(4)(sto-int, a, (3))(5)(ujp, l2)l1:(6)(add-int, b, 1)(7)(sto-int, b, (6))l2:(8) ...
Erzeugung von ZwischensprachreprsentationenMethoden:Aufruf semantischer Routinen in Verbindung mit syntaktischer AnalyseVerwendung attributierter GrammatikenVerwendung attributierter TranslationsgrammatikenBaumtransformation
Beispiel:Voraussetzungen: Bezeichnungen: P Feld fr P-Code mit Zeiger p auf nchste Eintragstelle, S Analysekeller mit Spitze iSpeicherbedarf: Die Befehle ldc i, ldc a, ind i, add i, mul i, neg i bentigen (kodiert) nur je 1 Speicherplatz. Bezeichner und Konstanten brauchen 2 Speicherpltze (Kenncode, Adresse in entsprechender Tabelle).Regeln: ::= ::=
::= + P[p] := add i; p := p + 1; P[p] := ;; p := p + 1;
::= - P[p] := neg i; p := p + 1; P[p] := ;; p := p + 1;
::=
::= * P[p] := mul i; p := p + 1; P[p] := ;; p := p + 1;
::= P[p] := ldc a; p := p + 1; P[p] := S[i]; p := p + 2; P[p] := ;; p := p + 1; P[p] := ind i; p := p + 1; P[p] := ;; p := p + 1;
::= P[p] := ldc i; p := p + 1; P[p] := S[i]; p := p + 2; P[p] := ;; p := p + 1;
9 ::= ()
Beispiel: Syntaxanalyse und Erzeugung von P-CodeAusdruck: a * (b + 5)Tokenfolge (symbolisch):Beza * ( Bezb + Kon5)
Analysekeller SRegelP[p]Beza7ldc a a; ind i;5 * (Bezb7ldc a b; ind i; * (5, 2 * ( + Kon58ldc i 5; * ( + 5 * ( + 3add i; * ()9 * 6mul i2, 1
Beispiel: vorheriges Beispiel unter Verwendung einer attributierten GrammatikAttribute:PsynthetisiertP-CodeIsynthetisiertBezeichnerKsynthetisiertKonstanteSyntaktische Regeln: s.o.Semantische Regeln:P() := P()
P() := P()
P(0) := CONCAT(P(1), P(), add i;)
P() := CONCAT(P(), neg i;)
5P() := P()
6P(0) := CONCAT(P(1), P(), mul i;)
7P() := CONCAT(ldc a , I(), ; ind i;)
8P() := CONCAT(ldc i , K(), ;)
9P() := P()
Beispiel:ZABCDE
E
TABCDE
T*FBCD
FA(EBCD)
Beza E +T A ldc a a; ind i;B ldc a b; ind i; T F CC ldc i 5;D add i; F BKon 5E mul i; Bez b
Beispiel: Attributierte Translationsgrammatik fr arithmetische Ausdrckex px := p
x px := p
x q + r ADDy,z,p := NEWT; y := q; z := r
x - q NEGy,p := NEWT; y := q
x px := p
x q * r MULTy,z,p := NEWT; y := q; z := r
x px := p
x px := p
x (p)x := p
Attributwerte: Speicheradressen :=NEWT: a und b wird die Adresse eines freien Speicherplatzes im Speicher T zugewiesen
Translation (ohne Attribute):Bez * (Bez + Kon) ADD MULT
Codeerzeugung im engeren SinneArten von Zielcode:Maschinenprogramm mit absoluten Adressen (Load-and-go-Compiler)Maschinenprogramm mit relativen Adressen (relocatable Code) Bearbeitung vor Abarbeitung:- Zusammenstellung unabhngig voneinander bersetzter Programmkomponenten mit externen Referenzen aufeinander zu einem Lademodul (load module)- Auflsung der externen Referenzen durch Binder (linker)- berfhrung in absolut adressiertes, ausfhrbares Programm durch Ladeprogramm (loader)
Programm in Assemblersprache Notwendigkeit eines AssemblerlaufesProgramm in Programmiersprache einer abstrakten Maschine zweistufige bersetzung: Quellsprache Sprache der abstrakten Maschine Zielsprache
Beispiel: bersetzung von Pascal in P-Code (Code der P-Maschine) und bersetzung des P-Codes in Zielsprache
bersetzung Zwischensprache ZielspracheGrundlegende TechnikenVoraussetzungen:Befehle der ZielmaschineLOAD R O RSTORE R O OSTORE O1 O2 O2ADD-I R O + RSUB-I R O - R
Inhalt von Speicherplatz a aAbspeicherung auf Speicherplatz a
RRegisteradresse (im Falle 1 Registers ACC)O kann sein:RegisteradresseHauptspeicheradresse= Konstante(Direktoperand)
STACKAdresse der Spitze des Kellerspeichers
Beispiel: Tabellengesteuerte CodeerzeugungVoraussetzungen:bersetzung aus Tripeldarstellung in Befehle obiger Zielmaschinegen(a)erzeugt Befehl acode(t)vertritt Befehlsfolge, die durch bersetzung des Teilbaums t entstandLBlinker TeilbaumRBrechter TeilbaumEine Variable in den erzeugten Befehlen vertritt den ihr im Hauptspeicher zugeordneten Speicherplatz.
Tabelle fr SUB-I (bzw. DIV-I)Variable/KonstanteUnterbaumVar.gen( LOAD ACC LB )code( RB )/gen( SUB-I ACC RB )gen( STORE ACC STACK )Kon.gen( LOAD ACC LB )gen( SUB-I ACC STACK )Uncode( LB )code( RB )tergen( SUB-I ACC RB )gen( STORE ACC STACK )bacode( LB )umgen( SUB-I ACC STACK )
Tabelle fr ADD-I (bzw. MUL-I)Variable/KonstanteUnterbaumVar.gen( LOAD ACC LB )code( RB )/gen( ADD-I ACC RB )gen( ADD-I ACC LB )Kon.Uncode( LB )code( LB )tergen( ADD-I ACC RB )gen( STORE ACC STACK )bacode( RB )umgen( ADD-I ACC STACK )
Tabelle fr ZuweisungVariable/KonstanteUnterbaumVar.gen( STORE RB LB )code( RB )gen( STORE ACC LB )Uncode( LB )code( RB )tergen( STORE RB )gen( STORE ACC STACK )bacode( LB )umgen( STORE STACK )
Beispiel: Zuweisungh := a * ((c + 5 * a) (c * d))
Tripel(mul-int, 5, a)(add-int, c, (1))(mul-int, c, d)(sub-int, (2), (3))(mul-int, a, (4))(sto-int, (5), h)
Tripel als Binrbaum:= (6)
h* (5)
a- (4)
+ (2)* (3)
c * (1) c d
5a
Erzeugte BefehlsfolgenLOAD ACC =5code((1))code((4))code((5))MUL-I ACC aMUL-I ACC a
code((1))code((2))code((5))code((6))ADD-I ACC cSTORE ACC h
LOAD ACC ccode((3))MUL-I ACC d
code((3))code((4))STORE ACC STACKcode((2))SUB-I ACC STACK
Generatoren fr CodegeneratorenVerwendung von Baumgrammatiken
Vorgehensweise:Beschreibung der Codeerzeugung:- Regeln der Baumgrammatik beschreiben die Zwischensprache: ::= - Zuordnung von Schablonenfolgen fr Erzeugung der Zielsprachbefehle zu Regeln
Erzeugung des Codegenerators aus vorheriger BeschreibungCodeerzeugung durch Codegenerator:- berdeckung des Baums zum Zwischensprachprogramm durch Baummuster (in Form von Termen); Auflsung von Mehrdeutigkeiten durch Kostenfunktion- Erzeugung von Zielcode aus Schablonenfolgen gem berdeckung
Beispiel: Baumgrammatikregeln mit Schablonen1r.2 ::= word( d.1 ){ LOAD R.2 D.1 }
2r.1 ::= iadd( r.1, r.2 ){ ADD-I R.1 R.2 }
3 ::= store( word( d.1 ), r.2 ){ STORE R.2 D.1 }
r.i Registeradresse; d.i Hauptspeicheradresse einer deklarierten Variableword, iadd, store Operatoren der Zwischensprache (Prfixform)
QuellspracheZwischenspracheA := A + Bstore(word(d.a), iadd(word(d.a), word(d.b)))
berdeckungsbaum
store
wordiadd
d.awordword
d.ad.b
Objektorientierte Compilerstruktur(nach D. A. Watt, D. F. Brown: Programming Language Processors in Java)Compilertreiber
Treiber
ParserCheckerEncoder
Scanner
Compilertreiberpublic class Compiler {public static void compileProgram(...) {//Generierung des ParsersParser parser = new Parser(...);//Generierung des semantischen AnalysatorsChecker checker = new Checker(...);
//Generierung des ZielcodegeneratorsEncoder generator = new Encoder(...);
//Aufruf des Parsers mit Erzeugung des abstrakten Syntaxbaums //ASTProgram theAST = parser.parse();
//Aufruf des semantischen Analysators mit Dekoration von ASTchecker.check(theAST);
//Aufruf des Codegenerators mit Erzeugung des Zielprogrammsgenerator.encode(theAST);}public static void main(String[] args) {...compileProgram(...); ...}}
Pakete:AbstractSyntaxTrees:- Klassen zur Definition der AST-Datenstrukturen Je Klasse: Konstruktor zum AST-Aufbau und visitor-Methode zur Verknpfung mit semantischer Analyse (contextual analyzer) und Codeerzeugung (code generator)- Manipulation der AST-FelderSyntacticAnalyzer:- Parserklassen zur syntaktischen Analyse (Methode des rekursiven Abstiegs) und zur AST-Konstruktion- Hilfsklassen
ContextualAnalyzer:Checker-Klasse zur Durchfhrung der semantischen AnalyseCodeGenerator:Encoder-Klasse fhrt ausgehend vom AST Speicherzuteilung durch und erzeugt Zielcode
Parserpublic class Parser{//Aktuelles Symbol im analysierten Programmprivate Token currentToken;
//Vergleich aktuelles Symbol erwartetes Symbolprivate void accept(byte expectedKind){if (currentToken.kind == expectedKind)currentToken = scanner.scan();else Fehlermeldung;}
//Nchstes Symbol wird zum aktuellen Symbolprivate void acceptIt(){currentToken = scanner.scan();}//Hilfsmethoden
//Parsingmethodenprivate Program parseProgram(){//Instanzvariable fr AST//Syntaxanalyse fr Programme//AST-Erzeugung fr Programmereturn //AST fr Programm }...
public Program parse(){currentToken = scanner.scan();Program progAST = parseProgram();if (currentToken.kind != Token.EOT) Fehlermeldungreturn progAST}... }
ASTAbstrakte Klasse fr AST:public abstract class AST{...}AST-Knoten als Unterklassen der AST-KlasseAbstrakte Klasse fr Expression:public abstract class Expression extends AST{...}Konkrete Klassen mit Konstruktor fr ASTBeispiel:AST-Konstruktor der Klasse AssignCommandpublic AssignCommand(Vname V, Expression E){this.V = V;this.E = E;}
Lexikalische Analysepublic class Scanner{...private boolean isDigit(char c){...}//true, falls c eine Ziffer ist...public Token scan(){...return new Token(currentKind, currentSpelling.toString());}}public class Token{...}//Lexembeschreibungen in Aufbau und Codierung
Semantische AnalyseAnwendung des visitor pattern:1. Einrichtung einer Schnittstelle Visitor2. Fr jeden konkreten AST einer Unterklasse A Verwendung einer Visitor-Methode visitA3. Anreicherung der abstrakten AST-Klasse mit der visit-Methode zum Besuch von AST-Knoten4. Implementation von visit in jeder Unterklasse5. Implementation der eigentlichen semantischen Analyseprozeduren im Checker (semantischer Analysator)
Schnittstelle Visitorpublic interface Visitor{//visitA-Methodenpublic Object visitProgram(Program prog, Object arg);...public Object visitAssignCommand(AssignCommand com, Object arg);}
Implementierung von Visitor in Checkerpublic final class Checker implements Visitor{//Symboltabelleprivate IdentificationTable idTable;//Visitor-Methodenpublic Object visitAssignCommand(Assigncommand com, Object arg){Type vType = (Type) com.V.visit(this, null);Type eType = (Type) com.E.visit(this, null);if(! eType.equals(vType)) Fehlermeldungreturn null;}
...//Start der semantischen Analysepublic void check(Program prog){//Initialisierung der SymboltabelleidTable = new IdentificationTable();...prog.visit(this, null);}}
Erweiterung der AST-Klassepublic abstract class AST{...public abstract Object visit(Visitor v, Object arg);}
Implementierung von visit in den AST-Unterklassenpublic class A extends ...{...public Object visit(Visitor v, Object arg){return v.visitA(this, arg);}}
CodeerzeugungNutzung des visitor patterns mit Implementierung der Visitor-Methoden in der Klasse Encoder:public final class Encoder implements Visitor{...//Visitor-Methodenpublic Object visitAssignCommand(AssignCommand com, Object arg){com.E.visit(this, arg);encodeAssign(com.V);return null;}public void encode(Program prog){prog.visit(this, null);}}