Compilerbauhome Compilerbau: Prof. Dr. Uwe Schmidt FH Wedel

weiter

weiter

LL-Analyse, Linksrekursion und Faktorisierung

G = (N, T, P, S)
N :{ S, ST, SL, E }
T :{ :=, ;, else, endif, id, if, n, then, $ }
S :S
P :S::=ST $
 ST::=id := E
 ST::=if E then SL endif
 ST::=if E then SL else SL endif
 SL::=ST
 SL::=SL ; ST
 E::=id
 E::=n

Diese Grammatik beschreibt eine Syntax für Anweisungen (ST), Anweisungsfolgen (SL), Zuweisungen und Verzweigungen. Sie ist für die LL-Syntaxanalyse aus zwei Gründen nicht geeignet: Die beiden Verzweigungsregeln beginnen mit den gleichen Symbolfolgen. Hier wird eine Faktorisierung notwendig sein. Die Anweisungsfolgen (SL) sind über eine Linksrekursion definiert, diese muss in eine Rechtsrekursion überführt werden.


Die Iterationen bei der Berechnung der FIRST-Mengen

 SSTSLE
0.{ }{ }{ }{ }
1.{ }{ id, if }{ id, if }{ id, n }
2.{ id, if }{ id, if }{ id, if }{ id, n }
3.{ id, if }{ id, if }{ id, if }{ id, n }

Die nullable Tabelle ist trivial, da keine epsilon-Produktionen vorkommen, daher ist die FOLLOW-Tabelle für den Aufbau der Parsertabelle nicht notwendig.


Die LL-Parser-Tabelle

 :=;elseendifidifnthen$
S----S ::= ST $S ::= ST $---
ST----ST ::= id := EST ::= if E then SL endif
ST ::= if E then SL else SL endif
---
SL----SL ::= ST
SL ::= SL ; ST
SL ::= ST
SL ::= SL ; ST
---
E----E ::= id-E ::= n--

Die Grammatik ist nicht LL(1): 3 Zelle(n) mit Konflikten

Es gibt jeweils zwei Ableitungsmöglichkeiten für ST und den look ahead if, und für SL wegen der Linksrekursion.


Eine gleichwertige Grammatik ohne Linksrekursion und mit Faktorisierung

G = (N, T, P, S)
N :{ S, ST, EP, SL, RL, E }
T :{ :=, ;, else, endif, id, if, n, then, $ }
S :S
P :S::=ST $
 ST::=id := E
 ST::=if E then SL EP endif
 EP::= 
 EP::=else SL
 SL::=ST RL
 RL::= 
 RL::=; ST RL
 E::=id
 E::=n

Es sind zwei neue Nichtterminalsymbole dazugekommen: EP (else part) und RL (rest list) und an zwei Stellen werden epsilon-Produktionen verwendet.


Die nullable-, FIRST- und FOLLOW-Tabellen

nullable

 SSTEPSLRLE
0.  -    -    -    -    -    -  
1.  -    -  true  -  true  -  
2.  -    -  true  -  true  -  

FIRST

 SSTEPSLRLE
0.{ }{ }{ }{ }{ }{ }
1.{ }{ id, if }{ else }{ id, if }{ ; }{ id, n }
2.{ id, if }{ id, if }{ else }{ id, if }{ ; }{ id, n }
3.{ id, if }{ id, if }{ else }{ id, if }{ ; }{ id, n }

FOLLOW

 SSTEPSLRLE
0.{ }{ }{ }{ }{ }{ }
1.{ }{ $, else, endif, ; }{ endif }{ else, endif }{ else, endif }{ $, then }
2.{ }{ $, else, endif, ; }{ endif }{ else, endif }{ else, endif }{ $, then, else, endif, ; }
3.{ }{ $, else, endif, ; }{ endif }{ else, endif }{ else, endif }{ $, then, else, endif, ; }

Die LL-Parser-Tabelle

 :=;elseendifidifnthen$
S----S ::= ST $S ::= ST $---
ST----ST ::= id := EST ::= if E then SL EP endif---
EP--EP ::= else SLEP ::= -----
SL----SL ::= ST RLSL ::= ST RL---
RL-RL ::= ; ST RLRL ::= RL ::= -----
E----E ::= id-E ::= n--

Die Grammatik ist LL(1)

Es gibt keine mehrfachen Einträge in der Tabelle


Eine Linksableitung

Für die Zeichenreihe if n then id := n ; id := id else id := n endif wird eine Linksableitung mit einem LL-Parser und der Tabelle konstruiert.

Aktion Verarbeitet Keller Eingabe
init   S if n then id := n ; id := id else id := n endif $
S ::= ST $   ST $ if n then id := n ; id := id else id := n endif $
ST ::= if E then SL EP endif   if E then SL EP endif $ if n then id := n ; id := id else id := n endif $
shift if E then SL EP endif $ n then id := n ; id := id else id := n endif $
E ::= n if n then SL EP endif $ n then id := n ; id := id else id := n endif $
shift if n then SL EP endif $ then id := n ; id := id else id := n endif $
shift if n then SL EP endif $ id := n ; id := id else id := n endif $
SL ::= ST RL if n then ST RL EP endif $ id := n ; id := id else id := n endif $
ST ::= id := E if n then id := E RL EP endif $ id := n ; id := id else id := n endif $
shift if n then id := E RL EP endif $ := n ; id := id else id := n endif $
shift if n then id := E RL EP endif $ n ; id := id else id := n endif $
E ::= n if n then id := n RL EP endif $ n ; id := id else id := n endif $
shift if n then id := n RL EP endif $ ; id := id else id := n endif $
RL ::= ; ST RL if n then id := n ; ST RL EP endif $ ; id := id else id := n endif $
shift if n then id := n ; ST RL EP endif $ id := id else id := n endif $
ST ::= id := E if n then id := n ; id := E RL EP endif $ id := id else id := n endif $
shift if n then id := n ; id := E RL EP endif $ := id else id := n endif $
shift if n then id := n ; id := E RL EP endif $ id else id := n endif $
E ::= id if n then id := n ; id := id RL EP endif $ id else id := n endif $
shift if n then id := n ; id := id RL EP endif $ else id := n endif $
RL ::=  if n then id := n ; id := id EP endif $ else id := n endif $
EP ::= else SL if n then id := n ; id := id else SL endif $ else id := n endif $
shift if n then id := n ; id := id else SL endif $ id := n endif $
SL ::= ST RL if n then id := n ; id := id else ST RL endif $ id := n endif $
ST ::= id := E if n then id := n ; id := id else id := E RL endif $ id := n endif $
shift if n then id := n ; id := id else id := E RL endif $ := n endif $
shift if n then id := n ; id := id else id := E RL endif $ n endif $
E ::= n if n then id := n ; id := id else id := n RL endif $ n endif $
shift if n then id := n ; id := id else id := n RL endif $ endif $
RL ::=  if n then id := n ; id := id else id := n endif $ endif $
shift if n then id := n ; id := id else id := n endif $ $
shift if n then id := n ; id := id else id := n endif $    
accept if n then id := n ; id := id else id := n endif $    

Letzte Änderung: 14.02.2012
© Prof. Dr. Uwe Schmidt
Prof. Dr. Uwe Schmidt FH Wedel