Compilerbau Prof. Dr. Wolfgang Schramm
SYNTAXANALYSE -‐
BOTTOM-‐UP-‐ANALYSE
3. Kapitel (Teil 2)
1
Umgekehrter Analyseprozess zu Top-‐Down-‐Analyse.
AuCau des Syntaxbaums von den BläIern her.
Entdeckung von rechten Seiten von ProdukLonen und RedukLon dieser rechten Seiten zum NTS von deren linker Seite.
Dabei wird der AuCau des Baums (irgendwie) durch Betrachtung der Eingabefolge kontrolliert.
Rechtsableitungen werden in umgekehrter Reihenfolge erkannt.
BoIom-‐Up-‐Parser
Operator-‐Vorrangmethode (Operator-‐precedence-‐Parser)
LR-‐Parser
BoIom-‐Up-‐Analyse – Allgemeine Strategie 1/2
2
BoIom-‐Up-‐Analyse – Allgemeine Strategie 2/2
Strategie:
¤
Suche den „oberen“ Rand des aktuellen Ableitungsbaums nach einer passenden rechten Seite ab.
¤
Wenn eine passende rechte Seite gefunden ist, reduziere sie zu dem NTS der linken Seite
¤
Solange nicht bis auf das Startsymbol reduziert worden ist, verfahre so weiter.
Zentrales Problem der BoIom-‐Up-‐Analyse:
¤
Wenn die kompleIe rechte Seite einer ProdukLon erkannt worden ist, soll dann reduziert werden, oder sollen noch weitere Symbole
hinzugenommen werden (shi\ oder reduce)?
3
BoIom-‐Up-‐Analyse – Beispiel
S → aABe.
A → Abc | b.
B → d.
Eingabe: abbcde
RedukLon auf Startsymbol S:
S ⇒ aABe ⇒ aAde ⇒ aAbcde ⇒ abbcde
Rechtsableitung RedukLon
abbcde aAbcde aAde aABe S
Rechtsableitung in umgekehrter
Reihenfolge
4
Handle
Informell: Der Handle eines Eingabestring ist ein Substring, der die rechte Seite einer ProdukLon ist. Die RedukLon des Handle zu einem NTS auf der linken
Seite der ProdukLon ist ein SchriI zur umgekehrten Rechtsableitung.
O\ ist es so, dass der am weitesten links stehende Substring b, der die rechte Seite einer ProdukLon A → b ist, kein Handle ist. Das ist dann der Fall, wenn die RedukLon durch die ProdukLon A → b zu einem String führt, der sich nicht zum Startsymbol reduzieren lässt.
DefiniLon: Handle einer Rechtssatzform
Sei G eine kontexereie GrammaLk und sei S ⇒* αAw ⇒ αβw
r r
eine Rechtsableitung in G. Dann heißt β ein Handle der Rechtssatzform αβw.
5
Handle – im Ableitungsbaum
S
A
β w α
Handle A → β im Ableitungsbaum für αβw
6
Arbeitsweise eines BoIom-‐Up-‐Parsers
1. Shi\: Entnimm das nächste Symbol der Eingabefolge und lege es auf den Stack.
2. Reduce: Ein Handle einer ProdukLon A→ β bildet das obere Ende des Stack.
Ersetze β auf dem Stack durch A.
3. Accept: Auf dem Stack liegt nur noch das Startsymbol. Die Eingabefolge ist leer.
AkzepLere die Eingabefolge.
4. Error: Entscheide, dass ein Syntaxfehler vorliegt.
Shift-Reduce-Parser
7
Stack
$
$ a
$ ab
$ aA
$ aAb
$ aAbc
$ aA
$ aAd
$ aAB
$ aABe
$ S
Eingabe abbcde$
bbcde$
bcde$
bcde$
cde$
de$
de$
e$
e$
$
$
Aktion shift shift
reduce: A → b shift
shift
reduce: A → Abc shift
reduce: B → d shift
reduce: S → aABe accept
Shi\-‐Reduce-‐Parser -‐ Beispiel
8
Viable Prefix
DefiniLon: Viable Prefix
Sei G eine kontexereie GrammaLk und sei S ⇒* aAw ⇒ aβw
r
r
eine Rechtsableitung in G. Jedes Anfangsstück der Folge aβw heißt viable prefix von G.
Viable Prefixes einer Rechtssatzform sind die Zeichenfolgen, die auf dem Stack liegen können.
9
Operator-‐Vorrang-‐Analyse (OVA)
o
Ursprünglich für Syntaxanalyse arithmetischer Ausdrücke entwickelt.
o
Nur für recht eingeschränkte Klasse von Grammatiken geeignet.
o
Lässt sich relativ einfach von Hand implementieren.
o
Grundidee:
•
Definiere 3 Relationen, die zwischen aufeinander-folgenden Symbolen (TS) auf dem Stack existieren können: <
.≡
.>
•
<
.und
.> begrenzen einen Handle
•
<
.≡ auf dem Stack à Shift
• .
> auf dem Stack à Reduce
10
Voraussetzungen der GrammaLk für OVA
1.
Auf keiner rechten Seite einer Produktion darf es zwei aufeinanderfolgende NTS geben.
2.
Es darf keine Produktionen mit gleicher rechter Seite geben.
3.
Es darf keine ε -Produktionen geben.
11
Operator-‐Vorrang -‐ Beispiel
+ <. * oder * .> +
E + E * E + E erhält die Relationen E + <. E * E .> + E Grammatik:
E → E + T | T.
T → T * F | F.
F → (E) | id.
E → E + E | E * E | (E) | id.
Eingabe
+ * ( ) id $
Stack + .> <. <. .> <. .>
* .> .> <. .> <. .>
( <. <. <. ≡ <.
) .> .> .> .>
id .> .> .> .>
$ <. <. <. <.
error
accept vereinfachen
12
Syntaxbaum ohne NTS
id + id * id E
E + T
T T * F F F id id id
E
E + E
id E * E id id
+
id *
id id
13
Finden der Handles
1.
Suche von links nach rechts die erste
.> - Relation.
2.
Suche nach links die nächste <
.- Relation.
3.
Handle: alles zwischen den beiden <
. .> - Klammern + umschließende NTS.
o
Beispiel: id + id * id
14
Operator-‐Vorrang-‐Analyse -‐ Beispiel
Stack
$
$ <. id
$ E
$ E <. +
$ E <. + <. id
$ E <. + E
$ E <. + E <. *
$ E <. + E <. * <. id
$ E <. + E <. * E
$ E <. + E
$ E
Eingabe id + id * id$
+ id * id$
+ id * id$
id * id$
* id$
* id$
id$
$
$
$
$
Aktion shift
reduce: E → id shift
shift
reduce: E → id shift
shift
reduce: E → id reduce: E → E * E reduce: E → E + E accept
Relation
<.
.>
<.
<.
.>
<.
<.
.>
.>
.>
15
ImplemenLerung der OVA
loop {
sei a oberstes Stackelement und b nächstes Eingabesymbol if a = $ und b = $ then exit loop
else {
if a <. b oder a ≡ b then push(b);
b := nächstes Eingabesymbol else if a .> b then
repeat pop unLl für a gilt <. – RelaLon else error
}
}
Bei einer Reduktion muss
natürlich eine passende rechte
Seite gefunden werden.
16
Entdeckung von Syntaxfehlern
Es gibt genau 2 Situationen, in den Syntaxfehler entdeckt werden:
1.
Es gibt keine Vorrangregel zwischen dem Terminalsymbol a auf TOP (Top Of Stack) und dem aktuellen Eingabesymbol b.
2.
Ein Handle (<
....
.> ) wird zwar gefunden, aber es gibt keine
Produktion mit dem Handle als rechter Seite (hier braucht
man die NTS!!!).
17
Festlegen der Vorrangregeln
1. Wenn eine Folge Ab auf der rechten Seite einer Produktion erscheint und wenn aus A eine Folge αa ableitbar ist, dann muss gelten a .> b.
2. Wenn eine Folge aA auf der rechten Seite einer Produktion erscheint und wenn aus A eine Folge bα ableitbar ist, dann muss gelten a <. b.
3. Wenn auf der rechten Seite einer Produktion eine Folge aAb erscheint, dann muss gelten a ≡ b.
A b α a
18
Festlegen von PräzedenzrelaLonen für Operatoren 1/2
... für Prioritäten und Assoziativität.
Für alle Operatoren θ :
1.
Falls Operator θ
1höhere Priorität hat als Operator θ
2:
¤
θ
1 .> θ
2und θ
2<
.θ
12.
Falls die Operatoren θ
1und θ
2gleiche Priorität haben:
a)
θ
1 .> θ
2und θ
2 .> θ
1, falls linksassoziativ
b)
θ
1<
.θ
2und θ
2<
.θ
1, falls rechtsassoziativ
¤
3.
Setze für alle Operatoren θ
θ <
.id und id
.> θ
θ <
.( und ( <
.θ
θ
.> ) und )
.> θ
θ
.> $ und $ <
.θ
19
Festlegen von PräzedenzrelaLonen für Operatoren 2/2
4. Setze außerdem:
( ≡ ) $ <
.( $ <
.id ( <
.( id
.> $ )
.> $ ( <
.id id
.> ) )
.> )
20
Unäre Operatoren
Beispiel: Logische NegaLon (!)
Der Operator ist mit nur einem Operanden, der unmiIelbar auf ihn folgt, verknüp\ (Präfix-‐Operator).
Präzedenzen:
¤ ∀ θ: θ <. !
¤ ! .> θ , wenn ! höhere Priorität hat als θ
¤ ! <. θ , wenn θ höhere Priorität hat als !
Beispiel: Poseix-‐Inkrement (++)
Der Operator ist mit nur einem Operanden, der unmiIelbar vor ihm steht, verknüp\ (Poseix-‐Operator).
Präzedenzen:
¤ ∀ θ: ++ .> θ
¤ θ <. ++, wenn ++ höhere Priorität hat als θ
¤ θ .> ++,, wenn θ höhere Priorität hat als ++
21
MehrdeuLge Operatoren
Problem:
o
- und + können unär (Vorzeichen) oder binär (Addition, Subtraktion) sein mit unterschiedlichen Prioritäten!
o
Die Präzedenzrelation wäre mehrdeutig!
Lösung:
o
Der Scanner erzeugt unterschiedliche Darstellungen unter
Berücksichtigung des zuvor erkannten Zeichens.
22
LR(k)-‐Methoden
L Untersuchung der Eingabe von links.
R Konstruktion einer Rechtsableitung (in umgekehrter Reihenfolge)
k Umfang des Lookaheads
Varianten der LR(k)-Methode
Simple LR (SLR)
Lookahead LR (LALR)
Canonical LR (LR)
23
Architektur eines LR-‐Parsers
a
1a
ia
n$
s
mX
ms
m-1X
m-1s
0Action Goto
LR-Parser
Zustand
Grammatik- symbol
bereits
gelesen Nächstes
Token
Ausgabe
Steuer- tabelle
24
Zustände
s
mX
ms
m-1X
m-1s
0beschreibt den Abschnitt
Zustände charakterisieren den Inhalt das Stack
„unter“ ihnen.
Speicherung der Grammatiksymbole ist nicht notwendig!
Die Grammatiksymbole werden der
Übersichtlichkeit halber weiterhin angegeben.
25
AuCau der Steuertabelle
Action Goto
. . . t . . . . . A .
. s
. . .
lex.
Element
Aktion Zustand
NTS
Zustand
26
AkLonen
AcLon (s, t) =
•
accept, Analyse erfolgreich abgeschlossen.
•
error, Analyse ohne Erfolg abbrechen.
•
reduce i, reduziere mit ProdukLon der Nummer i.
•
shi\ z, lege lexikalisches Element t und darüber Zustand z auf den Stack.
27
LR-‐Analyse 1/2
Situationen der Analyse haben folgende Form:
(s
0X
1s
1X
2. . . X
ms
m, a
ia
i+1. . . a
n$)
Stack Eingabe
Fall 1 : Action(sm, ai) = shift z
Neue Situation: (s0X1s1X2 . . . Xmsmaiz, ai+1 . . . an$)
Fall 2 : Action(sm, ai) = reduce i mit Produktion i: A → β mit |β| = r
Zwischensituation: (s0X1s1X2 . . . Xm-rsm-r, ai ai+1 . . . an$) Neue Situation: (s0X1s1X2 . . . Xm-rsm-r As, ai ai+1 . . . an$), wobei s = Goto (sm-r, A)
28
LR-‐Analyse 2/2
Fall 3 : AcLon(s
m, a
i) = accept
Analyse erfolgreich abschließen.
Fall 4 : AcLon(s
m, a
i) = error
Analyse mit Fehlermeldung abbrechen (evtl.
Fehlerbehandlung)
29
Steuertabelle für BeispielgrammaLk
(1) E → E + T.
(2) E → T.
(3) T → T * F.
(4) T → F.
(5) F → (E).
(6) F → id.
id + * ( ) $ E T F
0 s5 s4 1 2 3
1 s6 accept
2 r2 s7 r2 r2
3 r4 r4 r4 r4
4 s5 s4 8 2 3
5 r6 r6 r6 r6
6 s5 s4 9 3
7 s5 s4 10
8 s6 s11
9 r1 s7 r1 r1
10 r3 r3 r3 r3
11 r5 r5 r5 r5
sj shift mit Zustand Nr. j ri reduce mit Prod. i Blank error.
30
Beispiel für LR-‐Analyse
Stack 0
0 id 5 0 F 3 0 T 2 0 E 1 0 E 1 + 6 0 E 1 + 6 id 5 0 E 1 + 6 F 3 0 E 1 + 6 T 9 0 E 1 + 6 T 9 * 7
0 E 1 + 6 T 9 * 7 id 5 0 E 1 + 6 T 9 * 7 F 10 0 E 1 + 6 T 9
0 E 1
Eingabe id + id * id$
+ id * id$
+ id * id$
+ id * id$
+ id * id$
id * id$
* id$
* id$
* id$
id$
$
$
$
$
Action s5
r6: F → id r4: T → F r2: E → T s6
s5
r6: F → id r4: T → F s7
s5
r6: F → id r3: T → T * F r1: E → E + T accept
31
LR-‐Algorithmus
S := AnfangssituaLon repeat
sei t nächstes Token,
s Zustand an der Spitze des Stack (TOP) case AcLon (s, t) of
accept: Erfolg := true;
error: Fehler := true;
shi\ z: lege t auf Stack;
lege z auf Stack;
beschaffe nächstes Token;
reduce j: /* Prod. j: A → β */
eneerne 2 | β | Elemente vom Stack;
/* s‘ sei jetzt TOP */
lege A auf Stack;
lege Goto (s‘, A) auf Stack;
end
unLl Erfolg or error;
32
Eigenscha\en der Steuertabelle
Stack: alternierende Folge von Grammatiksymbolen und Zuständen.
Zustand beschreibt, an welcher Stelle der Analyse sich der Parser befindet.
Ähnlichkeit mit Pfaden in DFA:
Knoten = Zustände
Kanten = Grammatiksymbole oder shift: Zustandsübergang mit TS
reduce: a) gehe zurück bis Zustand, von dem ab Symbole in der rechten Seite der reduzierenden Produktion vorkommen.
b) Zustandsübergang mit NTS.
Weitere Vorgehensweise:
Grammatik (Produktionen) à DFA à Steuertabelle
33
Zustände der LR-‐Analyse als DFA – am Beispiel
0 E 1 + 6 T 9 * nach 7
nach 3 nach 4 nach 5 id
( F
2 * 7 F 10
nach 4 nach 5 id
( T
F 3
4 E 8 ) 11
nach 6 +
( (
nach 2 nach 3 F
T
id 5
id
id + * ( ) $ E T F
0 s5 s4 1 2 3
1 s6 accept
2 r2 s7 r2 r2
3 r4 r4 r4 r4
4 s5 s4 8 2 3
5 r6 r6 r6 r6
6 s5 s4 9 3
7 s5 s4 10
8 s6 s11
9 r1 s7 r1 r1
10 r3 r3 r3 r3
11 r5 r5 r5 r5
34
Wie findet man die Zustände des DFA?
Beobachtung:
• Während der Analyse sind gewisse Teile des noch unbekannten Ableitungsbaums gesehen und reduziert worden.
• Reduktion = Anwendung von Produktionen (in umgekehrter Richtung).
• Jede Anwendung einer Produktion = Fortschritt (der Analyse).
Idee: Markierung des Fortschritts in den Produktionen
E
E + T
T T * F F F id id id
Stackzustand:
0 E 1 + 6 T 9
Reduktionen
35
AnalysefortschriI -‐ Markierung
Mit einem
.wird der FortschriI der Syntaxanalyse markiert.
Im Beispiel:
Die ProdukLonen oben sind teilweise abgearbeitet:
E → E + T E → E +
.T T → T * F T → T
.* F
Die ProdukLonen im linken Ast sind vollständig abgearbeitet:
F → id
.T → F
.E → T
.
Die ProdukLon im rechten Ast ist noch unbearbeitet:
F →
.id
Produktionen mit . markiert:
LR(0)-Items
36
LR(0)-‐Element
Definition: LR(0)-Element / LR(0)-Item
Sei A → α eine Produktion einer kontextfreien Grammatik G. Für jede Zerlegung βγ von α (d.h. α = βγ) ist A → β . γ ein LR(0)-Element von G. Falls α = ε, so ist A → . ein LR(0)-Element von G.
Beispiel:
A → XYZ
Welches sind die LR(0)-Elemente?
A → . XYZ A → X . YZ A → XY . Z A → XYZ .
37
Zustand und ProdukLon
Zusammenhang: Zustand und ProdukLon Feststellung:
a)
Ein Zustand ist immer an den AnalysefortschriI (LR(0)-‐Elemente) geknüp\.
b)
Ein Zustand kann auf mehreren Wegen erreicht werden.
⇒
Ein Zustand umfasst immer mehrere, d.h. eine Menge von LR(0)-‐
Elementen.
Ein Zustandsübergang erfolgt mit einem Symbol und führt zu einer neuen Menge von LR(0)-‐Elementen.
38
Wie kommt man zu den Zuständen?
o
Füge neues Startsymbol S‘ mit ProdukLon S‘ → S ein.
o
Nummeriere die ProdukLonen durch.
o
Beginne mit Startsymbol S‘.
o
Da noch nichts getan ist, entspricht der Startzustand 0 dem LR(0)-‐Item: S‘ →
.S.
o
Verfahre von dort aus analog weiter, indem die rechten Seiten der ProdukLonen von S betrachtet werden und gruppiere dabei die LR(0)-‐Items zu einem Zustand.
39
Zustände finden – am Beispiel
(0) E‘ → E (1) E → E + T (2) E → T (3) T → T * F
(4) T → F (5) F → (E) (6) F → id
Zustand 0:
E‘ → . E E → . E + T
E → . T
T → . T * F
T → . F
F → . ( E ) F → . id
Abschluss / Closure
40
Abschluss (Clousure) eines Zustands
Definition: Abschluss / Closure
Sei M eine Menge von LR(0)-Elementen. Der Abschluss oder Closure von M - closure(M) – wird nach folgenden Regeln gebildet:
(i) Jedes Element in M ist auch in closure(M).
(ii) Wenn A → α . Bβ in closure(M) ist, dann ist für jede Produktion B → γ auch das Element B → . γ in closure(M).
Die Regel (ii) ist solange anzuwenden, bis nichts mehr zur closure hinzu kommt.
s0 := closure ( {E‘ → . E}) =
{ E‘ → . E, E → . E + T,
E → . T, T → . T * F,
T → . F, F → . ( E ), F → . id
}
41
Zustandsübergänge
Weitere Zustände à anwenden von Zustandsübergängen auf die Elemente eines gegebenen Zustands.
Zustandsübergang = Verschieben des Fortschrittpunktes über ein Symbol hinweg.
Nach einem Zustandsübergang ergibt sich eine neue Menge von LR(0)-Items, von welchen der Abschluss gebildet werden muss.
Definition: Zustandsübergangsfunktion goto
Sei M eine Menge von LR(0)-Elementen, X ein Grammatiksymbol. Dann ist goto (M, X) :=
closure ({A → αX . β | A → a . Xβ ∈ M}).
goto (S0, E) =
s1 := closure ( {E‘ → E., E → E . + T}) = {E‘ → E., E → E . + T}
42
Berechnung der Zustände -‐ Beispiel
E‘ → . E E → . E + T E → . T T → . T * F T → . F F → . ( E ) F → . id
s0 E‘ → E .
E → E . + T s1
E → T . T → T . * F
s2
T → F . s3
F → ( . E) E → . E + T E → . T T → . T * F T → . F F → . ( E ) F → . id
s4 E
T
F
(
F → id . s5 id
43
Berechnung aller Zustände -‐ Beispiel
E‘ → . E E → . E + T E → . T T → . T * F T → . F F → . ( E ) F → . id
s0
E‘ → E . E → E . + T
s1
E → T . T → T . * F
s2
T → F . s3
F → ( . E) E → . E + T E → . T T → . T * F T → . F F → . ( E ) F → . id
s4
E
T
F (
F → id . s5
id F
E → E + . T T → . T * F T → . F F → . ( E ) F → . id
s6 +
F (
E → E + T . T → T . * F
s9 T
F → (E . ) E → E . + T
s8 F → (E) .
s11
T → T * . F F → . ( E ) F → . id
s7
T → T * F . s10
* id id
(
)
*
F
+ id (
T
E
44
Algorithmus für die Berechnung der Zustände
procedure items (G‘) {
C : = {closure ( {S‘ →
.S} ) }
repeat
for
jede Menge M (LR(0)-Items) in C und
jedes Grammatiksymbol X mit goto (M, X) ≠ ∅ und noch nicht in C do
füge goto (M, X) zu C hinzu.
until keine weitere Menge kann zu C hinzugefügt werden
}
45
Kanonische LR(0)-‐KollekLon
Die Beispielgrammatik hat 11 Teilmengen mit LR(0)-Elementen.
Jede dieser 11 Teilmengen definiert einen Zustand des DFA.
Gesamtheit der Mengen von LR(0)-Items è kanonische LR(0)-Kollektion für die Grammatik G‘.
Wo stehen wir ?
Grammatik (Produktionen) à DFA à Steuertabelle
46
Algorithmus zur Berechnung der SLR(1)-‐
Analysetabelle
Gegeben: erweiterte kontexereie GrammaLk G‘
Ergebnis: AcLon-‐ und Goto-‐Tabelle für G‘
1. Berechne C = {M
0, . . ., M
n}, die kanonische LR(0)-‐KollekLon für G‘.
2. Berechne die Goto-‐Tabelle: Für jedes Paar (M
i, M
j) in C und NTS A, für die gilt goto(M
i, A) = M
j, setze Goto[i, A] = j.
3. Berechne die AcLon-‐Tabelle:
a) Für jedes Paar (Mi, Mj) in C und TS a, für die gilt goto(Mi, a) = Mj, setze AcLon[i, a] = shi\ j.
b) Für jede Menge Mi in C, die ein LR(0)-‐Item A → α. enthält und für jedes TS a in FOLLOW(A) setze AcLon[i, a] = reduce A → α. Abbruch bei
reduce/reduce und shi\/reduce-‐Konflikten.
c) Für die Menge Mm in C, die das Element S‘ à S . enthält, setze AcLon[m, $] = accept.
d) Setze alle bisher nicht belegten Einträge in der AcLon-‐Tabelle auf error.
47
Probleme bei SLR-‐Parsern
o
LR(0)-‐Item-‐Menge enthält 2 (oder mehr) Elemente A → α
., B → β
.deren FOLLOW-‐Mengen nicht disjunkt sind.
⇒ Problem: reduce/reduce-‐Konflikt: man kann nicht entscheiden, mit welcher ProdukLon reduziert werden soll.
⇒ KonstrukLon der Tabelle schlägt fehl; GrammaLk eignet sich nicht für SLR-‐Analyse
o
Für TS a gibt es einen Eintrag AcLon[i, a] = shi\ in der Tabelle (weil Übergang mit a in DFA) und es ist möglich, dass a in FOLLOW(A) liegt (im Zustand i und A → α
.).
⇒ Problem: shi\/reduce-‐Konflikt: man kann nicht entscheiden, ob reduziert oder „geshi\et“ werden soll.
⇒ KonstrukLon der Tabelle schlägt fehl; GrammaLk eignet sich nicht für SLR-‐Analyse
48
shi\/reduce-‐Konflikt – Beispiel 1/2
(0) S‘ → S (1) S → L = R (2) S → R
(3) L → * R (4) L → id (5) R → L
S‘ → . S S → . L = R S → . R R → . L L → . * R L → . id
s0 S‘ → S .
s1
S → L . = R R → L .
s2 S → R .
s3
L → * . R R → . L L → . id L → . * R
s6
L → id . s5
S → L = . R R → . L L → . * R L → . id
s4 s9
R → L . s8
L → * R . s7 R L
S
id
*
=
*
L
L * R
id id
R
S → L = R .
49
shi\/reduce-‐Konflikt – Beispiel 2/2
S → L . = R R → L .
s2
• Für = gibt es einen Übergang im DFA è Eintrag Action[2, =] = shift 6
• Da = in FOLLOW(R) liegt (im Zustand 2) è Eintrag Action[2, =] = reduce 5
⇒ shift/reduce-Konflikt: man kann nicht entscheiden, ob reduziert oder „geshiftet“
werden soll.
s6
S → L = . R R → . L L → . * R L → . id
=
50
reduce/reduce-‐Konflikt – Beispiel 1/2
(0) S‘ → S (1) S → E = E (2) S → id
(3) E → E + id (4) E → id
S‘ → . S S → . E = E S → . id E → . E + id E → . id
s0 S‘ → S .
s1
S → E . = E E → E . + id
s2
E → E + . id
s4
S → id . E → id .
s3
S → E = . E E → . E + id E → . id s5
s6 E
S
id
=
+
E
S → E = E . E → E . + id +
E → E + id . s7
id
id
51
reduce/reduce-‐Konflikt – Beispiel 2/2
• Da $ in FOLLOW(S) liegt (im Zustand 3) è Eintrag Action[3, $] = reduce 2
• Da $ in FOLLOW(E) liegt (im Zustand 3) è Eintrag Action[3, $] = reduce 4
⇒ reduce/reduce-Konflikt: man kann nicht entscheiden, mit welcher Produktion reduziert werden soll.
S → id . E → id .
s3
52
Problemlösung(en)
o
Kanonische LR-‐Parser – verfeinern die SLR-‐Technik
•
Berechnen bei der Berechnung der Zustände des DFA die jeweils möglichen Folgezustände mit und verwalten diese InformaLon in sog. LR(1)-‐Items.
•
Haben sehr viel mehr Zustände als SLR-‐Parser (bei HPS: SLR-‐Parser mehrere Hundert Zustände, kanonische LR-‐Parser: mehrere
Tausend).
•
Verbesserung: Verschmelzung der Zustände des LR-‐Automaten: è
LALR-‐Parser.
53
AuCau der Parse-‐Tabelle für die BeispielgrammaLk 1/3
0 E 1 + 6 T 9 * nach 7
nach 3 nach 4 nach 5 id
( F
2 * 7 F 10
nach 4 nach 5 id
( T
T 3
4 E 8 ) 11
nach 6 +
( (
nach 2 nach 3 F
T
id 5
id
54
AuCau der Parse-‐Tabelle für die BeispielgrammaLk 2/3
Berechnung der FOLLOW-Mengen für die NTS E‘, E, T und F:
E‘ E
F T
$ ) + $
* ) + $
* ) + $
55
Zustand id + * ( ) $ E T F
0 S5 s4 1 2 3
1 s6 accept
2 r2 s7 r2 r2
3 r4 r4 r4 r4
4 s5 s4 8 2 3
5 r6 r6 r6 r6
6 s5 s4 9 3
7 s5 s4 10
8 s6 s11
9 r1 s7 r1 r1
10 r3 r3 r3 r3
11 r5 r5 r5 r5