___________________________________________________________________________________________________________________________________
Programmiersprachenentwurf
Folien zu Vorlesung
Herbert Kopp, Václav Matoušek
Lexik. Analyse synt.Analyse Optimierung Speicherverw. Codegener.
Quellcode Res. Wörter
Zwischencode
Int.form Quelle Zwischencode Zielcode
Symboltabelle
Interpretation
1. Grundlagen der formalen Sprachen
1 1 . . G G r r u u n n d d l l a a g g e e n n d d e e r r f f o o r r m m a a l l e e n n S S p p r r a a c c h h e e n n
1. Grundlagen der formalen Sprachen
Historischer Rückblick
► 1956 versucht N.Chomsky den Aufbau natürlicher Sprachen formal zu beschreiben.
► Er verwendet dabei Methoden aus der formalen Logik
► Der Ansatz scheitert zwar bei natürlichen Sprachen,
► Er ist für formalen Sprachen aber gut geeignet.
1. Grundlagen der formalen Sprachen
Noam Chomsky
Institute Professor; Professor of Linguistics
Linguistic Theory, Syntax, Semantics, Philosophy of Language
Biography
Noam Chomsky was born on December 7, 1928 in Philadelphia, Pennsylvania. His undergraduate and graduate years were spent at the University of Pennsylvania where he received his PhD in linguistics in 1955. During the years 1951 to 1955, Chomsky was a Junior Fellow of the Harvard University Society of Fellows. While a Junior Fellow he completed his doctoral dissertation entitled, "Transformational Analysis." The major theoretical viewpoints of the dissertation appeared in the monograph Syntactic Structure, which was published in 1957. This formed part of a more extensive work, The Logical Structure of Linguistic Theory, published in 1975.
Chomsky joined the staff of the Massachusetts Institute of Technology in 1955 and in 1961 was appointed full professor in the Department of Modern Languages and Linguistics (now the Department of Linguistics and Philosophy.) From 1966 to 1976 he held the Ferrari P. Ward Professorship of Modern Languages and Linguistics. In 1976 he was appointed Institute Professor.
During the years 1958 to 1959 Chomsky was in residence at the Institute for Advanced Study at Princeton, NJ. In the spring of 1969 he delivered the John Locke Lectures at Oxford; in January 1970 he delivered the Bertrand Russell Memorial Lecture at Cambridge University; in 1972, the Nehru Memorial Lecture in New Delhi, and in 1977, the Huizinga Lecture in Leiden, among many others.
Professor Chomsky has received honorary degrees from many universities of the world, he is a Fellow of the American Academy of Arts
and Sciences and the National Academy of Science. In addition, he is a member of other professional and learned societies in the United
States and abroad, and is a recipient of the Distinguished Scientific Contribution Award of the American Psychological Association, the
Kyoto Prize in Basic Sciences, the Helmholtz Medal, the Dorothy Eldridge Peacemaker Award, the Ben Franklin Medal in Computer and
Cognitive Science, and others. Chomsky has written and lectured widely on linguistics, philosophy, intellectual history, contemporary
issues, international affairs and U.S. foreign policy.
1. Grundlagen der formalen Sprachen
Regelsystem
Regel 1: satz → subjekt prädikat objekt Regel 2: subjekt → artikel substantiv
Regel 3: objekt → artikel substantiv Regel 4: prädikat → verb
Regel 5: substantiv → hund | briefträger Regel 6: verb → beißt
Regel 7: artikel → den | der
1. Grundlagen der formalen Sprachen
Generierung eines Satzes mit dem Regelsystem
satz → subjekt prädikat objekt
→ artikel substantiv prädikat objekt
→ der substantiv prädikat objekt
→ der hund prädikat objekt
→ der hund verb objekt
→ der hund beißt objekt
→ der hund beißt artikel substantiv
→ der hund beißt den substantiv
→ der hund beißt den briefträger
1. Grundlagen der formalen Sprachen
Beispiel-Alphabete
Beispiel-Strings
σ
1= verb hund den # σ
1= 3
σ
2= der briefträger beißt den hund
# σ
2= 5
σ
3= ε # σ
3= 0
{ }
{ }
+ −
=
=
=
1 2
3
A , , ,
A , , ,
, , , , , , , A
, , ,
* /
,
satz subjekt prädikat objekt arti begin end if then
der den hund b
kel ver riefträger bei
b substanti t
v
ß
1. Grundlagen der formalen Sprachen
Produktionsregeln
► Produktionsregeln sind Vorschriften zum Ersetzen von Strings
► σ
1→ σ
2bedeutet: ersetze den String σ
1durch den String σ
2► mehrere Produktionsregeln mit gleicher linker Seite notiert man so:
1
|
2| |
kσ → σ σ σ
1. Grundlagen der formalen Sprachen
Ein Regelsystem für Namen
Regel 1: Name → Bu NRest | Bu
Regel 2: NRest → BuZi NRest | BuZi
Regel 3: BuZi → a | b | ... | z | 0 | 1 | 2 | ... | 9 Regel 4: Bu → a | b | ... | z
.... ....
=
, , , , A , , , , , , , ,
Name NRest Bu BuZ a b c z 0 1 9
i
1. Grundlagen der formalen Sprachen
Generierung von Namen mit dem Regelsystem
Name → Bu NRest
→ Bu BuZi NRest
→ Bu BuZi Buzi NRest
→ Bu BuZi Buzi BuZi NRest
→ Bu BuZi Buzi BuZi BuZi
→ Bu BuZi Buzi BuZi 0
→ Bu BuZi Buzi a 0
→ Bu BuZi t a 0
→ Bu e t a 0
→ b e t a 0
1. Grundlagen der formalen Sprachen
terminale / nichtterminale Alphabetzeichen
Mit Bezug auf ein fest vorgegebenes Alphabet unterscheidet man:
► terminale Alphabetzeichen:
diese kommen nicht auf der linken Seite einer Produktion vor und können daher nicht weiter ersetzt werden
.► nichtterminale Alphabetzeichen:
diese kommen auf der linken Seite mindestens einer Produktion vor.
1. Grundlagen der formalen Sprachen
Beispiel eines Strukturbaumes
Bu NRest
BuZi NRest
BuZi NRest
BuZi NRest
b e t a 0
BuZi
Name
1. Grundlagen der formalen Sprachen
Grammatiken
Eine Grammatik besitzt die folgenden Bestandteile:
• ein nichtterminales Alphabet : N
• ein terminales Alphabet : T
• ein Produktionensystem : P
• ein Startsymbol (Axiom) : X
Man schreibt dafür kurz: Γ = 〈 T , N , P , X 〉 ; X ∈ N
Das Gesamtalphabet der Grammatik ist V = N ∪ T
1. Grundlagen der formalen Sprachen
direkte Ableitungen
► τ ist direkt ableitbar aus σ: σ → τ
wenn es eine Produktionsregel gibt
mit σ = σ 1 σ 2 σ 3 und τ = σ 1 τ 2 σ 3
Ableitungen
► τ ist ableitbar aus σ: σ ⇒ τ
wenn es eine Folge direkter Ableitungsschritte gibt von der Form:
σ = σ 1 σ 2 σ 3 → τ 1 σ 2 σ 3 → τ 1 τ 2 σ 3 → τ 1 τ 2 τ 3 = τ
2 2
σ → τ
1. Grundlagen der formalen Sprachen
direkte Reduktionen
► statt τ direkt ableitbar aus σ sagen wir auch:
τ ist direkt reduzierbar zu σ: τ ← σ
Reduktionen
► statt τ ableitbar aus σ sagen wir auch:
τ ist reduzierbar zu σ: τ ⇐ σ
1. Grundlagen der formalen Sprachen
Satzformen
► ein String σ heißt Satzform bzgl. einer Grammatik Γ = N , T , P , X , wenn X ⇒ σ gilt.
Sätze
► ein String σ heißt Satz bzgl. einer Grammatik Γ = N , T , P , X , wenn X ⇒ σ und σ ∈ T
∗gilt.
Sprachen
► Die Sprache einer Grammatik Γ = N , T , P , X ist die Menge
L ( ) Γ = { σ | X ⇒ ∧ ∈ σ σ T * }
1. Grundlagen der formalen Sprachen
Vollständig geklammerte arithmetische Ausdrücke
= N , T , P ,
1 1 1expr
Γ
1mit:
{ }
{ }
( )
( )
( )
( )
=
=
→
→
− ∗
→
→ +
= →
+
−
∗
1 1
1
N
T , , , , , ,
P
expr
expr expr expr expr expr
v / ( )
v
expr expr
expr expr
expr expr
expr / exp r
1. Grundlagen der formalen Sprachen
Aufgaben
► Ist der String ( ( v v v + ∗ ) ) aus L ( ) Γ
1?:
► Geben Sie zum Satz ( ( v v + ) ∗ v ) den Strukturbaum und verschiedene Ableitungen an.
► Ist ein Zusammenhang erkennbar zwischen der Reihenfolge der Ableitungssschritte und der Reihenfolge, in der Teilausdrücke des obigen Ausdrucks auszuwerten sind ?
► Finden Sie zu Γ
1Beispiele für terminale Strings, die keine Sätze darstellen
► Finden Sie zu Γ
1Beispiele für Strings, die keine Satzformen sind!
1. Grundlagen der formalen Sprachen
Eigenschaften kontextfreier Sprachen
(Übersicht)
► Chomsky-Hierarchie
► kanonische Ableitungen
► Mehrdeutigkeit von Grammatiken
► Top-down und Bottom-up - Analysetechniken
► Sackgassen
1. Grundlagen der formalen Sprachen
Chomsky-Hierarchie
Typ 0-Sprachen Typ 1-Sprachen Typ 2-Sprachen
Typ 3- Sprachen
1. Grundlagen der formalen Sprachen
Die Grammatik-Klassen der Chomsky-Hierarchie
► Typ 0 - Grammatiken
Die Produktionen σ → τ mit σ τ ∈ , V * unterliegen keinen Einschränkungen. σ → ε erlaubt
► Typ 1 - Grammatiken
Produktionen sind von der Form σ → τ mit σ τ ∈ , V * und # σ ≤ τ # (nichtkontrahierend) äquivalente Form: σ τ → σατ A mit A ∈ N und σ τ α ∈ , , V * , wobei # α ≥ 1
(kontextsensitiv)
► Typ 2 - Grammatiken
Produktionen sind von der Form A → σ mit A ∈ N und σ ∈ V * (kontextfrei)
► Typ 3 - Grammatiken
Alle ihre Produktionen haben die Gestalt A → Ba (regulär, einseitig linear) A → a
oder alle Produktionen sind von der Form: A → aB
A → a
1. Grundlagen der formalen Sprachen
Eine reguläre Grammatik für Namen
= N , T , P
2 2 2, Name
Γ
2{ }
{ }
|
|
|
=
=
→
= →
→
…
…
…
2 2
2
N
T , , , , , , , , ,
P
Name
Name Name Nam a b c z 0 1 2 9
e Name
Name Name Name Name Na
| |
e
| |
|
m |
a b z
0 1 9
a b z
1. Grundlagen der formalen Sprachen
Eine Grammatik für "Klammergebirge"
3
=
Γ N , T , P ,
3 3 3S
{ }
{ }
{ }
(
( ε
=
=
= →
3 3 3
N
T ,
P S
) S
S S ) |
1. Grundlagen der formalen Sprachen
Eine Typ 2 - Grammatik für die natürlichen Zahlen
= I
Γ
4N , T , P ,
4 4 4{ }
{ }
I I
I
=
=
= →
→
…
…
4
4
4
N ,
T , , , ,
P Z | Z
Z | | | |
0 1 2 9
0 1 2 9
Z
► Aufgabe: Geben Sie eine Typ3-Grammatik für die natürlichen Zahlen an !
1. Grundlagen der formalen Sprachen
I → Z I → ZZI → ZZZI → ZZZZ → ZZZ1 → ZZ11 → Z711 → 4711 I → Z I → 4I → 4Z I → 47 I → 47Z I → 471 I → 471Z → 4711 I → Z I → ZZI → 4ZI → 4ZZI → 4ZZZ → 4ZZ1 → 47Z1 → 4711
Ein Strukturbaum und
verschiedene Ableitungen dazu
4 7 1 1
I
Z I
Z I
Z I
Z
1. Grundlagen der formalen Sprachen
Eine Satzform ohne kanonische Ableitungen
I → Z I → 4 I → 4ZI → 4ZZ → 4Z1 I → Z I → ZZI → ZZZ → ZZ1 → 4Z1 I → Z I → ZZI → ZZZ → 4ZZ → 4Z1 I → Z I → ZZI → 4ZI → 4ZZ → 4Z1
► keine dieser Ableitungen für die Satzform 4Z1 ist kanonisch, aber
es gibt keine weitere Ableitung dafür !
1. Grundlagen der formalen Sprachen
Eine mehrdeutige kontextfreie Grammatik
5
=
Γ N , T , P ,
5 5 5expr
{ }
{ + ∗ }
=
=
→
= →
→
+
∗
5
5
5
N
T , ,
P
expr
expr
expr expr expr expr expr expr
v
v
1. Grundlagen der formalen Sprachen
Zwei Strukturbäume zum selben Satz
expr expr
expr expr
expr
v + v ∗ v
expr expr
expr expr
expr
v + v ∗ v
1. Grundlagen der formalen Sprachen
Standard-Grammatik für arithmetische Ausdrücke
6
=
Γ N , T , P ,
6 6 6expr
{ }
{ }
|
/ ( )
( )
+ − ∗
+ −
=
→
= → ∗
=
→
6
6
6
N , ,
T , , , , , ,
P
expr term fact
expr term | term | term
term fact | term fact | term fact
fact ex
/ pr
v
expr expr
v
1. Grundlagen der formalen Sprachen
einziger Strukturbaum zu v v v + ∗ bezüglich Γ
6expr term
term fact
expr
v + v ∗ v
term
fact fact
1. Grundlagen der formalen Sprachen
linkskanonische Ableitung des Ausdrucks v v v + ∗
expr → expr + term
→ term + term
→ fact + term
→ v + term
→ v + term * fact
→ v + fact * fact
→ v + v * fact
→ v + v * v
1. Grundlagen der formalen Sprachen
rechtskanonische Ableitung des Ausdrucks
v v v+ ∗expr → expr + term
→ expr + term * fact
→ expr + term * v
→ expr + fact * v
→ expr + v * v
→ term + v * v
→ fact + v * v
→ v + v * v
1. Grundlagen der formalen Sprachen
Top down-Analyse (I)
I
4 7
? Z I
I
4 7
?
Z I
I
4 7
?
1. Grundlagen der formalen Sprachen
Top down-Analyse (II)
Z I
I
4 7
? Z
Z I
I
4 7
Z
1. Grundlagen der formalen Sprachen
Bottom up-Analyse (I)
I
4 7
? Z
I
4 7
?
Z
I
4 7
?
Z
1. Grundlagen der formalen Sprachen
Bottom up-Analyse (II)
Z
I
4 7
?
Z
I
Z
I
4 7
Z
I
1. Grundlagen der formalen Sprachen
Sackgassen bei der Analyse
Z
4 7
?
Z I Z
4 7
?
Z I
Z
I
4 7
?
Z
1. Grundlagen der formalen Sprachen Die Syntaxgraphen einer Grammatik (I)
1 | 2 | | k
σ σ σ
→ A
1 2 k
σ σ σ = σ
σ
1σ
2σ
kσ
2σ
kσ
11. Grundlagen der formalen Sprachen
Die Syntaxgraphen einer Grammatik (II)
{ } σ
σ
[ ] σ
A
Nichtterminalzeichen
σ
1. Grundlagen der formalen Sprachen
Grammatik für geklammerte Summen und ihre Syntaxgraphen
7
= N , T , P ,
7 7 7E
Γ
{ }
{ }
{ }
( )
( )
|
=
=
→ +
= +
→
7 7
7
N ,
T , , ,
P
E T
E T T
T E
v
v
T
T +
E )
(
v
1. Grundlagen der formalen Sprachen
const c=10;
var n,f;
procedure fakultaet;
var i;
begin
f := 1;
i := 2;
while i <= n do begin
f := f*i;
i := i+1;
end end;
begin
n := c;
call fakultaet;
end.
PL/0-Beispielprogramm
Syntax of PL/0
<PROGRAM> --> <CONSTDCL> <VARDCL> <PROCDCL> <STMT> .
<CONSTDCL> --> <CONSTDCL> const Iden = Numeral ; | EmptyString
<VARDCL> --> <VARDCL> var Iden ; | EmptyString
<PROCDCL> --> <PROCDCL> procedure Iden ; <CONSTDCL> <VARDCL> <STMT> ; | EmptyString
<STMTLIST> --> <STMT> | <STMT> ; <STMTLIST>
<STMT> --> Iden := <EXPR> | call Iden | begin <STMTLIST> end | if <COND> then <STMT> | while <COND> do <STMT>
<COND> --> <EXPR> <RELOP> <EXPR>
<RELOP> --> = | <> | < | > | <= | >=
<EXPR> --> <TERM> | <EXPR> + <TERM> | <EXPR> - <TERM>
<TERM> --> <FACTOR> | <TERM> * <FACTOR> | <TERM> / <FACTOR>
<FACTOR> --> Iden | Numeral | ( <EXPR> )
Note
1. Iden is an identifier of at most 8 characters long. The first character is an alphabet, and the remaining characters can be an alphabet, a digit, or the underscore symbol ( _ ).
2. Numerial is made up digits and can be of any length.
3. EmptyString is an empty string.
4. Comments, blanks, and newline characters are allowed anywhere in a program.
1. Grundlagen der formalen Sprachen
PL/0-Syntax-Diagramme (I)
const
var
ident
;
procedure
ident
block
;
,
; ;
,
ident = number
block
ident
number ident
1. Grundlagen der formalen Sprachen
PL/0-Syntax-Diagramme (II)
ident
call
ident
begin
end
then
if
do
while
statement
; :=
expr
statement statement
condition statement
condition statement
1. Grundlagen der formalen Sprachen
PL/0-Syntax-Diagramme (III)
≤
<
odd
expr
expr expr
>
=
#
condition
1. Grundlagen der formalen Sprachen
PL/0-Syntax-Diagramme (IV)
∗
term
fact
fact +
− +
term
term expr
−
1. Grundlagen der formalen Sprachen
PL/0-Syntax-Diagramme (IV)
program
block .
ident
number
) (
fact
expr
1. Grundlagen der formalen Sprachen
Einführungsbeispiel zur Analyse regulärer Sprachen
8
=
Γ N , T , P ,
8 8 8S
{ }
{ }
|
|
=
=
→
= →
→
8 8
8
N , ,
T ,
P
0 1
1 0
S T U
S T | U T S U
0 0 1 1 S
0 1
1 0
0 1
0 1
1 0 0
U
0 1
0 1 S
0 1 1
T
1 0 S
0 U
S
Startsituation
1. Reduktionsschritt
2. Reduktionsschritt
3. Reduktionsschritt
4. Reduktionsschritt
5. Reduktionsschritt
6. Reduktionsschritt
1. Grundlagen der formalen Sprachen
Modell eines Endlichen Automaten
b e t a 0
Schaltwerk
Eingabeband
Lesekopf
1. Grundlagen der formalen Sprachen
Zustandsgraphen für Endliche Automaten
1
T S
Σ U
0 Ω
0
0
0 1
1
1 Startzustand
Endzustand
1. Grundlagen der formalen Sprachen
Schaltverhalten Endlicher Automaten
{Lesekopf auf das erste Eingabezeichen positionieren}
{Startzustand einstellen}
while {Eingabe noch nicht erschöpft} do begin
{Lies das aktuelle Zeichen und gehe zum nächsten}
{Nimm den Folgezustand an gemäß dem Zustandsgraphen}
end;
if {Endzustand erreicht} then {akzeptiere die Eingabe}
else {akzeptiere die Eingabe nicht}
1. Grundlagen der formalen Sprachen
Schaltverhalten Endlicher Automaten
sigma: {lies nächstes Zeichen ein}
if Zeichen in [a..z] then goto name else goto omega;
name: while { Ende der Eingabe noch nicht erreicht}
do {lies nächstes Zeichen ein};
{akzeptiere den Eingabestring};
stop;
omega: while { Ende der Eingabe noch nicht erreicht}
do {lies nächstes Zeichen ein};
{akzeptiere den Eingabestring nicht};
stop;
Name
Σ
a | b | c | .... | z
Ω
0 | 1 | 2 | .... | 9
Startzustand
Endzustand a | b | c | .... | z
a | b | c | .... | z 0 | 1 | 2 | .... | 9 0 | 1 | 2 | .... | 9
1. Grundlagen der formalen Sprachen Modell eines Stack-Automaten
v + ( v + v )
Schaltwerk
T ( + E
Eingabeband Lesekopf
Lese-/
Schreib- kopf
Stack
2. Prinzipien der Compilierung
2 2 . . P P r r i i n n z z i i p p i i e e n n d d e e r r C C o o m m p p i i l l i i e e r r u u n n g g
2. Prinzipien der Compilierung
Grundfragen bei sprachorientierten Werkzeugen
Welche sprachlichen Mittel soll eine Programmiersprache bieten ?
(z.B. Datentypen, Kontrollstrukturen, Prozedurmechanismen, Objekte, ... ) Wie sollen diese Sprachmittel syntaktisch und semantisch definiert werden?
Wie sollen Sprachkonstruktionen in eine ausführbare Form übersetzt werden?
Grundschema der Übersetzung
Quellcode Zielcode
2. Prinzipien der Compilierung
Übersetzer-Typen
⇒ Assembler: Zielcode ist Maschinencode,
symbolische Namen, Makrotechniken
⇒ Compiler: Zielcode ist Assembler | Zwischencode | Maschinencode Prozedurtechniken, ausgereifte Entwurfswerkzeuge
⇒ Interpreter: kein Zielcode, einfache Sprachstruktur
⇒ Präprozessoren: kostengünstige Erweiterung existierender Übersetzer
2. Prinzipien der Compilierung
Beispiel-Programm
void Polar (float x1, float y1, double& radius, double& winkel) {
// Funktion zur Umrechnung kartesischer Koordinaten in Polarkoordinaten radius = sqrt ( x1*x1 + y1*y1 );
winkel = atan ( y1 / x1 );
return;
}
2. Prinzipien der Compilierung
Phasenmodell der Compilierung
Lexikalische Analyse
Code- generierung Speicher-
verwaltung syntaktische
Analyse Optimierung
Quellcode Reservierte Wörter
Zwischen- code Internform
der Quelle Zwischen-
Zielcode
code
Symboltabelle
Interpretation
2. Prinzipien der Compilierung
Ergebnis der lexikalischen Analyse
void
Polar
( float x1 , float y1 ,
double& radius , double& winkel ) {
// Funktion zur Umrechnung kartesischer Koordinaten in Polarkoordinaten radius = sqrt ( x1
* x1 + y1 * y1 ) ;
winkel = atan ( y1 / x1 ) ; return ;
}
2. Prinzipien der Compilierung
Aufgaben der lexikalischen Analyse
⇒ Erkennen der Grundbausteine der Quelle (Tokens | Atome )
⇒ Umwandeln der Tokens in eine Interndarstellung
⇒ Erkennen und Behandeln lexikalischer Fehler
⇒ Entfernen irrelevanter Quellcode-Bestandteile (z.B. von Kommentar)
2. Prinzipien der Compilierung
Aufgaben der syntaktischen Analyse
⇒ Erkennen syntaktischer Strukturen ( Bestandteile = Tokens | Atome )
⇒ Erkennen syntaktischer Fehler und Fehlerdiagnose
⇒ Fehlerbehandlung, um die Analyse fortsetzen zu können
⇒ Aufbau der Symboltabelle
2. Prinzipien der Compilierung
Generierung von Zwischencode
• Quellcode-Anweisung:
radius = sqrt ( x1*x1 + y1*y1 );
• Zwischencode:
MPY x1 x1 $v1 MPY y1 y1 $v2 ADD $v1 $v2 $v3 CALL sqrt $v3 $v4
STORE $v4 radius
2. Prinzipien der Compilierung
Maschinenunabhängige Optimierung
Maßnahmen im Zuge der maschinenunabhängigen Optimierung sind:
Einsparung von Hilfsvariablen
Vorabauswertung konstanter Ausdrücke Optimierung logischer Ausdrücke
Vorziehen gemeinsamer Teilausdrücke
Herausziehen invarianter Teile von Schleifen
Elimination nicht erreichbarer Quellcode-Abschnitte
2. Prinzipien der Compilierung
Aufgaben der Speicherplatzvergabe
ordnet den Objekten eines Programms Adreßinformationen zu mit:
− statischen Speicherzuordnungstechniken
− dynamischen Speicherzuordnungstechniken
Aufgaben der Codegenerierung
Sie erzeugt Objektcode (z.B. relokativen Maschinencode für den Linker), ist abhängig von der Ziel-Architektur,
führt maschinenabhängige Optimierung durch.
3. Die lexikalische Analyse
lexikalische Analyse
3. Die lexikalische Analyse
3. Die lexikalische Analyse
3. Die lexikalische Analyse
Aufgaben der lexikalischen Analyse
» Pufferung des Quellprogramms beim Einlesen vom Externspeicher
» Erstellen eines Compiler-Listing
» Entfernen irrelevanter Quellcode-Bestandteile
» Erkennen der Tokens und Umwandlung in Internform
» Erkennen und Behandeln lexikalischer Fehler
3. Die lexikalische Analyse
Implementierungstechniken für den Scanner
» Der Scanner kann implementiert werden
−
als Unterprogramm
−
als untergeordnete Klasse des Parsers
−
als selbständiger Prozeß
−
als selbständiger Compiler-Pass
» Look-Ahead
» Scanner-Generatoren
−
erhalten eine Beschreibung der Tokens einer Sprache
−
erstellen einen Scanner, der Tokens aus dem Quellprogramm herausfiltert
3. Die lexikalische Analyse
Die Atome von PL/0
Zu den Atomen der Sprache PL/0 gehören
» reservierte Wortsymbole ( begin | end | if | .... )
» Namen (für Konstanten, Variablen, Funktionen)
» ganzzahlige numerische Konstanten
» zweistellige Operatoren ( := | <= | >= )
» einstellige Operatoren ( + | - | ∗ | .... )
» einstellige Sonderzeichen, Trennzeichen ( ; | , | ( | ) | .... )
Zustands-Diagramm für den Scanner
Wortsymbol
ident
number
becomes nul
leq lss
geq andere Zeichen gt
andere Zeichen
andere Zeichen 0, 1, 2, .... , 9
andere Zeichen
a, b, c, .... , z, 0, 1, 2, .... , 9
a, b, .... , z
0, .... , 9
Wort- symbol ?
=
=
= :
<
>
Σ A
B
C
D
E
3. Die lexikalische Analyse
Die Datenstrukturen des Scanner (I)
Index word[NORW] wsym[NORW] Index ssym[CHSIZE]
0 "begin " beginsym
1 "call " callsym ...
2 "const " constsym '+' plus
3 "do " dosym '(' lparen
'<' lss
'§' nul NORW -1 "while " whilesym
...
3. Die lexikalische Analyse
Die Datenstrukturen des Scanner (II)
line: x = a + b ;
linepos linelen
3. Die lexikalische Analyse
Die Funktion getChar()
void Scanner::getChar(void) {
// refill line buffer ist it is empty if (linePos == lineLen)
{
if (inFile.eof()) {
< unerwartetes Dateiende erreicht >
}
linePos = 0;
lineNr++;
inFile.getline(line, LINMAX);
cout << setw(3) << lineNr << " " << line << endl;
strcat(line, " ");
lineLen = strlen(line);
}
// return next character to function getSym ch = line[linePos++];
}
3. Die lexikalische Analyse
Die Funktion getSym()
void Scanner::getSym() {
while (ch == ' ') { getChar(); } switch (charType[ch])
{
case letter: ...
case digit: ...
case special:
case other: switch (ch) {
case ':': ...
case '>': ...
case '<': ...
default: ...
} }
}
4. Top down-Parser
syntaktische Analyse
4. Top down-Parser
4. Top down-Parser
4. Top down-Parser
a b
...
X Z
V U
S
Y
c d ...
Das Floyd'sche Modell der Top down-Analyse
→
→
→
→
S X Y Z | X Y Z X U
U a b
V
V c d
4. Top down-Parser
Beseitigung von Linksrekursivitäten bei Ausdrucksgrammatiken
| ( )
v
→ + −
→ ∗
→
expr term | expr term | expr term term fact | term fact | term / fact
fact expr
{ }
{ }
| ( )
v
→ + −
→ ∗
→
expr term term | term term fact fact | / fact
fact expr
/
| ( )
v
→ + −
→ ∗
→
expr term | term expr | term expr term fact | fact term | fact term
fact expr
4. Top down-Parser
Vorbereitende Schritte zum LL(1)-Parser
» Beseitigung von Linksrekursivitäten
» Grammatiken wählen, bei denen keine Sackgassen auftreten können
» Implementierungstechnik wählen:
− Recursive Descent-Parser
− Tabellengesteurte Parser
4. Top down-Parser
FIRST- und FOLLOW-Mengen
» Zu einer Grammatik Γ = N , T , P , S und einem String ist:
{ } { }
{ }
( ) | ....
( ) | ....
σ σ ε σ ε
σ σ
= ∈ ⇒ ∪ ⇒
= ∈ ⇒
FIRST t T t falls gilt und
FIRST t T t andernfalls
» Zu einem nichtterminalen Zeichen N ist:
FOLLOW N ( ) = ∈ { t T X | ⇒ ...Nt.... }
4. Top down-Parser
Grammatiken, die nicht vom Typ LL(1) sind
» Γ
9= N , T , P ,
9 9 9S mit
{ }
{ }
=
=
→
= →
→
9 9
9
N , , T , ,
P
S A B a b c
S A | B A cA | a B cB | b
» Γ
10= N
10, T
10, P ,
10E mit:
{ }
{ }
{ ε }
=
= +
= → +
10 10
N
T , P
E t
E E t |
4. Top down-Parser
Charakterisierung von LL(1)-Grammatiken
» Die LL(1)-Eigenschaft E 1
Falls es zu N ∈ N zwei alternative Produktionen N → σ
1und N → σ
2gibt, so muß gelten:
( )
1( ) σ ∩ σ 2 = ∅ FIRST FIRST
» Die LL(1)-Eigenschaft E 2
Falls aus einem N ∈ N der Leerstring ε abgeleitet werden kann, d.h. N ⇒ ε , so muß gelten:
FIRST N ( ) ∩ FOLLOW N ( ) = ∅
4. Top down-Parser
Verfahren zur Konstruktion der Menge FIRST(N) für N ∈ V
für {alle Terminalzeichen t ∈ T } setze FIRST ( t ) = { t } ; wiederhole
für { alle Produktionen A → σ } {
falls { A ⇒ ε } nimm ε in FIRST(A) auf ;
falls die Produktion die Form A → y y
1 2" y
khat {
nimm ( ) ( )
1 ∩
FIRST y T in FIRST A auf ;
falls { y y
1 2" y
p⇒ ε für 1 ≤ ≤ − p k 1 } nimm FIRST y (
p+1) ∩ T in FIRST A auf ( ) ; }
}
4. Top down-Parser
Verfahren zur Konstruktion der Menge FIRST(σ) für σ ∈ V
*falls { σ ⇒ ε } nimm ε in FIRST ( ) σ auf Nimm { FIRST A ( )
1∩ T } in FIRST ( ) σ auf für { i = 1, 2, ... n -1 }
falls { A A
1 2" A
i⇒ ε } nimm (
1) ( )
i
σ
+
∩
FIRST A T in FIRST auf
4. Top down-Parser
Verfahren zur Konstruktion der Menge FOLLOW(N) für N ∈ V
wiederhole
für { alle Vorkommen von N in der rechten Seite einer Produktion p } {
falls { p A = → ... N σ mit σ ε ≠ }
nimm { FIRST ( ) σ ∩ T } in FOLLOW N ( ) auf ; falls { p A = → ... N σ mit σ ⇒ ε }
nimm { FOLLOW A ( ) ∩ T } in FOLLOW N ( ) auf;
}
solange bis alle FOLLOW-Mengen stabil sind
4. Top down-Parser
Die Code-Struktur eines Recursive Descent-Parser
S
0() { ... }
S
1() { ... } syntaktische Prozeduren ...
S
k() { ... }
error () { ... } Fehlerbehandlung main parser ()
{
getSym(); erstes Symbol holen S(); Analyse starten
}
4. Top down-Parser
Syntax-Diagramm und syntaktische Prozeduren (I)
Teilgraph des Syntax-Diagramms: zugeordneter Programm-Code:
T
1T
2T
#
switch (FIRST_Type (symbol)) {
case FIRST_T1 : P(T1) ; break;
case FIRST_T2 : P(T2) ; break;
...
case FIRST_Tk: P(Tk) default: error() ;
}
4. Top down-Parser
Syntax-Diagramm und syntaktische Prozeduren (II)
Teilgraph des Syntax-Diagramms:
zugeordneter Programm-Code:
P(T1) ; P(T2) ; ... ; P(Tk) ;
T1 T2 Tk
4. Top down-Parser
Syntax-Diagramm und syntaktische Prozeduren (III)
Teilgraph des Syntax-Diagramms:
zugeordneter Programm-Code:
if ( FIRST_Type (symbol) = FIRST_T) { P(T) } ;
T
4. Top down-Parser
Syntax-Diagramm und syntaktische Prozeduren (IV)
Teilgraph des Syntax-Diagramms:
zugeordneter Programm-Code:
while ( FIRST_Type (symbol) = FIRST_T) { P(T) } ;
T
4. Top down-Parser
Syntax-Diagramm und syntaktische Prozeduren (V)
Teilgraph des Syntax-Diagramms: zugeordneter Programm-Code:
Teilgraph des Syntax-Diagramms: zugeordneter Programm-Code:
if (symbol = 'a' ) { lies nächstes Symbol } ;
X
a
P(X);
4. Top down-Parser
Parser für arithmetische Ausdrücke:
1. Iterative Grammatik für arithmetische Ausdrücke
{ }
{ }
{ }
{ }
/ ( ) [ | ]
| | ( )
=
= + − ∗
→ + − + −
= → ∗
→
11 11
11