• Keine Ergebnisse gefunden

SYNTAXANALYSE  –   TOP-­‐DOWN-­‐ANALYSE

N/A
N/A
Protected

Academic year: 2021

Aktie "SYNTAXANALYSE  –   TOP-­‐DOWN-­‐ANALYSE"

Copied!
76
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Compilerbau   Prof.  Dr.  Wolfgang  Schramm  

SYNTAXANALYSE  –   TOP-­‐DOWN-­‐ANALYSE    

3.  Kapitel  (Teil  1)  

(2)

1  

Syntak'sche  Analyse  (Parser)  1/2  

Aufgaben  des  Parsers  

(1) Überprüfung  des  Programms  hinsichtlich  seines  strukturellen  AuAaus  und   Erzeugung  eines  Strukturbaums.  

(2)  Bearbeitung  (Neueinträge/Ergänzungen)  der  Symboltabelle.  

(3)  Fehlererkennung  /  Fehlerbesei'gung.  

(4) Unterstützung  der  seman'schen  Analyse.  

(3)

2  

Syntak'sche  Analyse  (Parser)  2/2  

Symboltabelle

Scanner Parser

Quell- pro- gramm

Struktur- baum

Eintragen/

Nachschlagen Eintragen

Symbol Attribut Token

Anfor- derung

(4)

3  

Parser  –  Beispiele  zu  den  Aufgaben  1/2  

(1)  if (a <= 10) max = a;

stmt cond_stmt

if ( boolexpr ) stmt ;

numexpr cop numexpr assignment

id const id = expr numexpr

id

(5)

4  

Parser  –  Beispiele  zu  den  Aufgaben  2/2  

(2) int a, b, c;

In der Deklaration erkennt der Scanner die lexikalischen Elemente int (Token:

keyword), a, b und c (Token jeweils: id). Er erkennt aber nicht den Zusammenhang:

int ist der Typ von a, b und c.

(3) if a <= 10 max = a;

Der Parser erkennt einen Fehler und korrigiert ihn zu:

if (a <= 10) max = a;

(4) if (a <= 10) max = a;

Der Parser weiß, dass der Ausdruck a <= 10 vom Typ boolean sein muss.

(6)

5  

Beschreibung  der  Syntax  von  Programmiersprachen  

Parser

Eingabe Ausgabe

Syntaxbeschreibung

à Kontextfreie Grammatik (in BNF)

Grammatik ist Basis für den Parser

... um festzustellen (= analysieren), ob ein gegebenes Wort (= Programm) zur Sprache gehört.

(7)

6  

Gramma'k  (kontexPrei)  1/2  

Eine  Gramma'k  zur  Beschreibung  von  Syntax  ist  ein  4-­‐Tupel:  

G  =  (T,  N,  P,  S),  mit  

T:  Menge  von  Token,  sog.  Terminalsymbole  (TS).  

N:  Menge  von  Nonterminalsymbolen  (NTS).  

P:  Menge  von  Produk'onen  (oder  Produk'onsregeln),  wobei  jede  Produk'on   aus  einem  Nonterminalsymbol  (linke  Seite  der  Produk'on)  einem  Pfeil  (→)   und  einer  Folge  von  Terminalsymbolen  und/oder  Nonterminalsymbolen     (rechte  Seite  der  Produk'on)  besteht.  

S:  Ein  ausgezeichnetes  Nonterminalsymbol  -­‐  das  Startsymbol.  

(8)

7  

Gramma'k  

(kontexPrei)  2/2   Die  Sprache  L(G)  einer  GrammaMk  besteht  aus  allen  aus  dem  Startsymbol  S  abgeleiteten   Zeichenke[en  (Wörtern),  die  nur  Terminalsymbole  enthalten.  Ein  Wort  ist  eine  Folge  von   Terminalsymbolen,  die  durch  wiederholtes  Anwenden  von  Regeln  (  =  Subs'tu'on  „rechte   Seite  einer  Produk'on  ersetzt  linke  Seite“)  erzeugt  werden  kann,  wobei  das  Startsymbol  S   der  Ausgangspunkt  der  Erzeugung  ist.  

Es  gibt  verschiedene  Formalismen  zur  Beschreibung  von  kontexPreien  Gramma'ken:  

¤  Backus  Naur  Form  (BNF).  

¤  Erweiterte  Backus  Naur  Form  (EBNF).  

¤  Syntaxdiagramme.  

(9)

8  

Defini'on  Ableitung  

Produk'onen  sind  Ersetzungsregeln.  

A  → α besagt,  dass  man  ein  Aubreten  des  NTS  A  innerhalb  eines   Wortes  ϕ durch  die  Folge  von  Symbolen  α ersetzen  darf.  Damit   verwandelt  sich  das  Ausgangswort ϕ in  ein  Wort ψ.

Sei  G  =  (T,  N,  P,  S)  eine  kontexPreie  Gramma'k. ψ ist  aus  ϕ direkt   ableitbar  (Nota'on:  ϕ ⇒ ψ),  wenn  es  Worte  σ, τ gibt  und  eine   Produk'on  A → α ,  so  dass  gilt:  ϕ = σΑτ und  ψ = σατ. Man  sagt ψ ist  aus  ϕ ableitbar  (ϕ produziert ψ;  Nota'on:  ϕ ⇒* ψ),  wenn  es   eine  Folge  von  Worten  ϕ1, ϕ2, ..., ϕn (n ≥ 1)  gibt,  so  dass  gilt ϕ = ϕ1, ψ = ϕn und  ϕi ⇒ ϕi+1,  für  1  ≤ i< n.  

Die  Folge  von  Worten,  für  die  ja  gilt  ϕ1 ⇒ ϕ2 ⇒ . . . ⇒ ϕn heißt  eine   Ableitung  von  ψ aus  ϕ in  G.  

 

Beispiel folgt!

(10)

9  

Backus-­‐Naur-­‐Form  (BNF)  

o Einfacher  Formalismus  für  die  Syntaxbeschreibung  von  Kunstsprachen     (=  Programmiersprachen).  

o Dieser  Formalismus  hat  selbst  wiederum  eine  Syntax  –  man  spricht  deshalb  von  der   Metasyntax  der  BNF:  

¤  Ersetzungsregeln  in  der  Form:  linke  Seite  ::=  rechte  Seite  

¤  .    Markiert  das  Regelende  

¤  |    Alterna've  

¤  (  )    Klammerung  zusammengehöriger  Symbole  

¤  <  >  schließen  Nonterminalsymbole  ein  

¤  Terminalsymbole  werden  (wegen  der  besseren  Kenntlichkeit)  ob  in  “  “   eingeschlossen  oder  fe_  gedruckt  

(11)

10  

Backus-­‐Naur-­‐Form  (BNF)  -­‐  Beispiel  

o  Bezeichner  einer  Programmiersprache  müssen  mit  einem  

Buchstaben  beginnen,  dürfen  nach  dem  ersten  Buchstaben  aber   auch  Ziffern  enthalten:  

 <Ziffer>  ::=  1|2|3|4|5|6|7|8|9|0.  

 <Buchstabe>  ::=  a|b|c|  ...  |z.  

 <Zeichenke[e>  ::=  <Buchstabe>  |  <Ziffer>  |  

   <Buchstabe>  <Zeichenke[e>  |  

   <Ziffer>  <Zeichenke[e>.  

 <Bezeichner>  ::=  <Buchstabe>  |  <Buchstabe>  <Zeichenke[e>.  

Rekursion

Das lässt sich einfacher mit

regulären Ausdrücken beschreiben.

(12)

11  

Erweiterte  Backus-­‐Naur-­‐Form  (EBNF)  

o  Erweitert  die  BNF  um  einige  Metasymbole,  um  die  Syntax  bequemer  bzw.  leichter   verständlich  zu  beschreiben.  

o  Es  gibt  viele  verschiedene  EBNFs  –  ob  gibt  es  für  die  Beschreibung  der  Syntax  einer   Programmiersprache  eine  eigene  EBNF  

o  Bekannteste  Erweiterung  der  Metasyntax  der  EBNF:  

¤  Ersetzungsregeln  in  der  Form:  linke  Seite    rechte  Seite  

¤  [  ]  op'onale  Klammerung  

¤  {  }  Wiederholungsklammerung  (0  -­‐  n  mal)  

¤  {  }+  Wiederholungsklammerung  (1  -­‐  n  mal)  

-­‐  .    Markiert  das  Regelende  

-­‐  |  Alterna've  

-­‐  (  )  Klammerung  zusammengehöriger  Symbole  

-­‐  <  >  schließen  Nonterminalsymbole  ein  

-­‐  Terminalsymbole  werden  (der  besseren  Kenntlichkeit)  ob  in  

“  “  eingeschlossen  oder  fe[  gedruckt  

(13)

12  

Erweiterte  Backus-­‐Naur-­‐Form  (EBNF)  –  Beispiel  

o  Bezeichner  einer  Programmiersprache  müssen  mit  einem  

Buchstaben  beginnen,  dürfen  nach  dem  ersten  Buchstaben  aber   auch  Ziffern  enthalten:  

 <Ziffer>  ::=  1|2|3|4|5|6|7|8|9|0.  

 <Buchstabe>  ::=  a|b|c|  ...  |z.  

 <Bezeichner>  ::=  <Buchstabe>  {<Buchstabe>|  <Ziffer>  }.  

(14)

13  

Erweiterte  Backus-­‐Naur-­‐Form  (EBNF)  –  komplizierteres   Beispiel  1/3  

expr    →  term  |  expr  add_op  term.  

term  →  factor  |  term  mul_op  factor.  

factor  →  number  |  id  |  "("  expr  ")".  

add_op  →  "+"  |  "-­‐".  

mul_op  →  "*"  |  "/".  

 

number  und  id  seien  Terminalsymbole  

Einfache arithmetische Ausdrücke:

Start- symbol

expr ⇒ expr add_op term ⇒ term add_op term ⇒ factor add_op term ⇒ id add_op term ⇒ id + term ⇒ id + term mul_op factor ⇒

id + factor mul_op factor ⇒ id + id mul_op factor ⇒ id + id * factor ⇒ id + id * id.

(15)

14  

Erweiterte  Backus-­‐Naur-­‐Form  (EBNF)  –  komplizierteres   Beispiel:  Erweiterung  2/3  

expr    →  term  |  expr  add_op  term.  

term  →  factor  |  term  mul_op  factor.  

factor  →  [sign]  (  number  |  id  |  "("  expr  ")"  ).  

sign    →  "+"  |  "-­‐".  

add_op  →  "+"  |  "-­‐".  

mul_op  →  "*"  |  "/".  

Einfache arithmetische Ausdrücke (erweitert um Vorzeichen):

(16)

15  

Erweiterte  Backus-­‐Naur-­‐Form  (EBNF)  –  komplizierteres   Beispiel:  Umformung  3/3  

expr  →  term  {add_op  term}.  

term  →  factor  {mul_op  factor}.  

factor  →  [sign]  (  number  |  id  |  "("  expr  ")"  ).  

sign    →  "+"  |  "-­‐".  

add_op  →  "+"  |  "-­‐".  

mul_op  →  "*"  |  "/".  

Einfache arithmetische Ausdrücke (umgeformt):

(17)

16  

Erweiterte  Backus-­‐Naur-­‐Form  (EBNF)  –größere   Erweiterung  

expr    →  s_expr  |  s_expr  rel_op  s_expr  .   s_expr    →  term  |  s_expr  add_op  term.  

term  →  factor  |  term  mul_op  factor.  

factor  →  [sign]  (  number  |  id  |  "("  expr  ")"  )  |        "not"  (  id  |  "("  expr  ")"  )  .  

sign    →  "+"  |  "-­‐".  

add_op  →  "+"  |  "-­‐"  |  "or".  

mul_op  →  "*"  |  "/"  |  "and".  

rel_op  →  "<"  |  "<="  |  "="  |  "!="  |  ">="  |  ">".  

Einfache arithmetische Ausdrücke - erweitert um relationale Operatoren und boolesche Operatoren:

(18)

17  

Ableitung  aus  dem  Startsymbol  

expr

expr add_op term

term + term mul_op factor factor factor * id

id id Ableitungsbaum

expr ⇒ expr add_op term ⇒ term add_op term ⇒ factor add_op term ⇒ id add_op term ⇒ id + term ⇒ id + term mul_op factor ⇒

id + factor mul_op factor ⇒ id + id mul_op factor ⇒ id + id * factor ⇒ id + id * id.

(19)

18  

Defini'on  Ableitungsbaum  

Sei  G  =  (T,  N,  P,  S)  eine  kontexPreie  Gramma'k.  Sei  B  ein  Baum,  

dessen  innere  Knoten  mit  NTS  und  dessen  Blä[er  mit  TS  von  G  oder   mit  dem  leeren  Wort  ε markiert  sind.  B  heißt  Ableitungsbaum  (oder   Syntaxbaum)  für  das  Wort  w  ∈ T*  und  für  X  ∈ N,  falls  gilt:  

1.  Für  jeden  inneren  Knoten  p,  der  mit  Y  ∈ N  markiert  ist  und  dessen  Söhne   (von  links  nach  rechts)  q1  .  .  .  qn  mit  Q1  .  .  .  Qn  ∈ (N ∪ T)  markiert  sind,  gibt  es   eine  Produk'on  Y  → Q1  .  .  .  Qn  in  P.  Falls  p  einen  einzigen  Sohn  hat,  der  mit  ε markiert  ist,  so  exis'ert  eine  Produk'on  Y  → ε.

2.  Die  Wurzel  des  Baumes  ist  mit  X  markiert,  und  die  Konkatena'on  der  Blä[er   ergibt  w.  

 

(20)

19  

Defini'on:  Links-­‐  und  Rechtsableitung  

Sei ϕ1, . . ., ϕn eine  Ableitung  mit  S  =  ϕ1 , ϕ= ϕn . ϕ1, . . ., ϕn heißt  

Linksableitung  von  ϕ, falls  in  jedem  Schri[  von  ϕι nach ϕι+1 in ϕι jeweils  das   am  weitesten  links  stehende  NTS  ersetzt  wird,  also  gilt  ϕι = wAσ und ϕι+1 = wασ.

Analog  heißt  ϕ1, . . ., ϕn Rechtsableitung  von  ϕ, falls  in  jedem  Schri[  von  ϕι nach ϕι+1 in ϕι jeweils  das  am  weitesten  rechts  stehende  NTS  ersetzt  wird,  das   heißt ϕι = σAw und ϕι+1 = σαw.

Eine  Satzform  (das  ist  jeder  Zwischenzustand  eines  Ableitungsbaums)  innerhalb   einer  Linksableitung  (Rechtsableitung)  heißt  Linkssatzform  (Rechtssatzform).  

 

(21)

20  

Mehrdeu'ge  Gramma'ken  1/4  

Führen  verschiedene  Ableitungen  zum  selben  Syntaxbaum,    dann   spielt  das  wegen  derselben  Struktur  des  Wortes  w  keine  Rolle.  

Ist  es  aber  möglich  zu  einem  Wort  w  verschiedene  Ableitungsbäume   anzugeben,  dann  nennt  man  die  zugrunde  liegende  Gramma'k  

mehrdeuMg.  

 

Mehrdeu'ge  Gramma'k  è  seman'schen  Mehrdeu'gkeiten    

(22)

21  

Mehrdeu'ge  Gramma'ken  2/4  

Beispiel:  

stmt à if expr then stmt |

if expr then stmt else stmt.

if . . . then . . . if . . . then . . . else . . .

stmt

if expr then stmt

if expr then stmt else stmt

(23)

22  

Mehrdeu'ge  Gramma'ken  3/4  

stmt

if expr then stmt

if expr then stmt else stmt

Beispiel:

stmt à if expr then stmt |

if expr then stmt else stmt.

if . . . then . . . if . . . then . . . else . . .

(24)

23  

Mehrdeu'ge  Gramma'ken  4/4  

Auflösung  der  Mehrdeu'gkeit  

 è  Änderung  der  Sprache      è  Änderung  der  Gramma'k  

stmt à matched_stmt | unmatched_stmt.

matched_stmt à if expr then matched_stmt else matched_stmt.

unmatched_stmt à if expr then matched_stmt else unmatched_stmt | if expr then stmt.

Grammatik

Sprache stmt à if expr then stmt endif |

if expr then stmt else stmt endif.

(25)

24  

Top-­‐Down-­‐Analyse  –  Allgemeine  Strategie  1/2  

Startsymbol  

bereits fertig

fehlt noch

bereits verarbeitete Eingabe

noch nicht verarbeitete Eingabe

A

neu

Am weitesten links vorkommendes NTS

Ziel: Finde eine Linksableitung

(26)

25  

Top-­‐Down-­‐Analyse  –  Allgemeine  Strategie  2/2  

Man  baut  den  Ableitungsbaum  von  der  Wurzel  aus  auf.  

Dabei  wird  der  AuAau  des  Baums  (irgendwie)  durch  Betrachtung  der   Eingabefolge  kontrolliert.  

Strategie:  

¤  Vergleiche  die  Bla•olge  des  bisher  erzeugten  Ableitungsbaums  mit  der   Eingabesymbolfolge,  d.h.  beide  Symbolfolgen  werden  von  links  nach  rechts   gelesen.  

¤  Solange  beide  Symbolfolgen  Terminalsymbole  enthalten,  wird  weiter   gelesen.  

¤  Enthält  die  Eingabefolge  ein  TS  und  das  entsprechende  Bla[  des  Baums  ein   NTS,  wird  eine  Produk'on  der  Gramma'k  ausgewählt,  die  auf  dieses  NTS   anwendbar  ist,  die  Bla•olge  des  Baums  wird  dadurch  lokal  verändert.  

¤  Werden  2  nicht  übereins'mmende  TS  angetroffen,  dann  

n  war  eine  vorher  ausgewählte  Produk'on  falsch  und  muss  rückgängig  gemacht   werden.  

n  oder  die  Eingabefolge  ist  syntak'sch  falsch.  

(27)

26  

Kategorien  von  Top-­‐Down-­‐Parsern  

determinis'sch   nicht-deterministisch

mit Rücksetzungen ohne Rücksetzungen

rekursiver Abstieg Tabellenmethode

(28)

27  

Beispielgramma'k  

stmt    → assignment  |  cond  |  loop.  (1)  

assignment    → id  :=  expr.  (2)  

cond    → if  boolexpr  then  stmt  fi  |  (3)  

   if  boolexpr  then  stmt  else  stmt  fi.  

loop    → while  boolexpr  do  stmt  od.  (4)  

expr    → boolexpr  |  numexpr.  (5)  

boolexpr    → numexpr cop  numexpr .  (6)   numexpr    → id    |  const .    (7)  

numexpr numexpr + term | term . (7)

term term * factor | factor. (8)

factor → id | const | (numexpr) . (9)

(29)

28  

Top-­‐Down-­‐Analyse  mit  Backtracking  –  Beispiel  1/3  

Startsymbol

Eingabefolge (von Scanner)

if id cop const then id := const fi stmt

assignment

if id cop const then id := const fi stmt

assignment id := expr stmt

if id cop const then id := const fi

BACKTRACKING

(30)

29  

Top-­‐Down-­‐Analyse  mit  Backtracking  –  Beispiel  2/3  

if id cop const then id := const fi stmt

cond

if boolexpr then stmt fi

if id cop const then id := const fi stmt

cond

if boolexpr then stmt fi numexpr cop numexpr

id

if id cop const then id := const fi assignment stmt

cond

if boolexpr then stmt fi numexpr cop numexpr

id const id := expr

(31)

30  

Top-­‐Down-­‐Analyse  mit  Backtracking  –  Beispiel  3/3  

if id cop const then id := const fi assignment stmt

cond

if boolexpr then stmt fi numexpr cop numexpr

id const id := expr

numexpr cop numexpr const

boolexpr

BACKTRACKING

(32)

31  

•  Verlaufen in Sackgassen.

Ineffizienz

•  Linksrekursive Produktionen (Regeln (7) und (8)).

Analyse ist nicht möglich!

Grammatiken so konstruieren bzw. modifizieren, dass beide Probleme nicht auftreten.

Top-­‐Down-­‐Analyse  -­‐  Probleme  

(33)

32  

Linksrekursion    

•  Direkte Linksrekursion: A → Aα

Indirekte Linksrekursion: A ⇒* Aα Beispiel: A → Aα | β.

A

A α

A α

A α

β

A β A‘

α A‘

α A‘

ε α A‘

linksrekursive Produktionen rechtsrekursive Produktionen A → βA‘.

A‘ → αA‘ | ε.

Eliminierung direkte Linksrekursion

(34)

33  

Algorithmus  zur  Besei'gung  der  Linksrekursion  

o  Eingabe:  Gramma'k  G  –  ohne  Zyklen  und  ε-­‐Produk'onen.  

o  Ausgabe:  Äquivalente  Gramma'k  ohne  Linksrekursion.  

 

1. Ordne  die  NTS  in  der  Reihenfolge  A1,  A2,  .  .  .,  An  an.  

2.  for  i  :=  1  to  n  do  

   for  j  :=  1  to  i-­‐1  do  {  

 Ersetze  jede  Produk'on  der  Form  Ai  → Ajγ durch  die  Produk'onen  

Ai  → δ1γ | δ2γ | . . . | δkγ, wobei  Aj → δ1 | δ2| . . . | δk alle  aktuellen  Aj-­‐

Produk'onen  sind.  

   }  

Eliminiere  die  direkten  Linksrekursionen  unter  den  Ai-­‐Produk'onen.  

 

(35)

34  

Beispielgramma'k  (geändert)  

stmt assignment | cond | loop. (1)

assignment id := expr. (2)

cond if boolexpr then stmt fi| (3)

if boolexpr then stmt else stmt fi.

loop while boolexpr do stmt od. (4)

expr boolexpr| numexpr. (5)

boolexpr numexpr cop numexpr . (6)

numexpr term numexpr‘. (7a)

numexpr‘ + term numexpr‘ | ε . (7b)

term factor term‘. (8a)

term‘ * factor term‘ | ε. (8b)

factor id | const | (numexpr) . (9)

(36)

35  

Predic've  Parsing  –  vorausschauende  Syntaxanalyse  

Ziel:    Vermeiden  von  Sackgassen  und  damit  von  Backtracking.  

 

Idee:    Durch  gemeinsames  Betrachten  des  aktuell  zu  expandierenden   Baumknoten  und  des  aktuellen  Zeichens  der  Eingabefolge,  

kann  man  eindeu'g  entscheiden  welche  Alterna've  bei   mehreren  möglichen  Produk'onen  auszuwählen  ist.  

 

Voraussetzung:  Die  Gramma'k  muss  vom  Typ  LL(1)  sein.  Wenn  sie   das  nicht  ist,  muss  sie  in  LL(1)-­‐Form  gebracht  werden.  

 

(37)

36  

LL(k)-­‐Gramma'ken  

Bei dieser Klasse von Grammatiken kann immer eine eindeutige Entscheidung durch Ansehen der nächsten k Terminalsymbole der Eingabefolge getroffen werden.

Definition: Worte, Anfangsstücke von Worten einer Sprache Sei L T* eine beliebige Sprache und sei k > 0. Dann ist

startk(L) := {w| (w L und |w| < k) oder (es existiert wu L und |w| = k)}.

Für ein Wort v T* sei

v falls |v| < k startk(v) :=

u falls u, t existieren mit |u| = k, ut = v

(38)

37  

LL(k)-­‐Gramma'ken  -­‐  Defini'on  

Definition: LL(k)-Grammatik

Eine kontextfreie Grammatik G = (N, T, P, S) heißt LL(k)-Grammatik, wenn gilt: Aus S * wAσ ⇒ wασ ⇒* wx,

S ⇒* wAσ ⇒ wβσ ⇒* wy, und startk(x) = startk(y) folgt α = β.

A S

w

α σ

x startk(x)

Lesen der Eingabe von links nach rechts und berechnen einer Linksableitung unter

Vorausschau auf die nächsten k-Zeichen.

(39)

38  

Starke  LL(k)-­‐Gramma'ken  -­‐  Defini'on  

Defini'on:  Starke  LL(k)-­‐Gramma'k  

Eine  kontexPreie  Gramma'k  G  =  (N,  T,  P,  S)  heißt  starke  LL(k)-­‐

Gramma'k,  wenn  gilt:  Aus  

S  ⇒* w11 ⇒ w1ασ1 ⇒*  w1x,   S  ⇒* w22 ⇒ w2βσ2 ⇒*  w2y,   und  startk(x)  =  startk(y)    

folgt  α = β.

Hier  spielt  der  Kontext  des  zu  expandierenden  NTS  A  keine  Rolle.  

 

(40)

39  

FIRST-­‐  Menge  

Die  FIRST-­‐Menge  einer  Zeichenfolge  α  (α ∈ (N ∪ T)*  )  besteht  aus   allen  TS,  mit  denen  Zeichenke[en  beginnen  können,  welche  von  α abgeleitet werden.

Defini'on:  FIRST-­‐Menge  

Sei  G  =  (N,  T,  P,  S)  eine  kontexPreie  Gramma'k, α ∈ (N  ∪ T)*  und  k  >  

0,  dann  ist    FIRSTk(α)  :=  startk  ({w  |  α ⇒*  w}).  

Die  Menge  FIRSTk(α)  beschreibt  also  gerade  die  Anfangsstücke  bis  zur   Länge  k  von  aus α ableitbaren  Terminalworten.  

 

(41)

40  

FOLLOW-­‐  Menge  

Die  FOLLOW-­‐Menge  eines  NTS  A  enthält  alle  TS,  die  in  einer  (Links-­‐)   Satzform  direkt  rechts  von  A  stehen  können.  

 

Defini'on:  FOLLOW-­‐Menge  

Sei  G  =  (N,  T,  P,  S)  eine  kontexPreie  Gramma'k,  A ∈ N  und  k  >  0,   dann  ist  

FOLLOWk(A)  :=  {w  |  S  ⇒*  uAv  und  w  =  FIRSTk(v)  }.  

 

Die  Menge  FOLLOWk(A)  beschreibt  also  Terminalzeichenfolgen  bis  zur   Länge  k,  die  innerhalb  von  Ableitungen  in  G  auf  das  NTS  A  folgen  

können.  

(42)

41  

Steuermenge  

Falls αi die  rich'ge  Entscheidung  ist,  dann  muss  die  Folge  der  nächsten  k   Zeichen,  auf  die  wir  vorausschauen,  in  der  Konkatena'on  der  Mengen   FIRSTki)  und  FOLLOWk(A)  liegen.  

 

Defini'on:  Steuermenge  

Sei  G  =  (N,  T,  P,  S)  eine  kontexPreie  Gramma'k,  A    N,  k  >  0,  und   A→ α1 | α2 | . . . | αn die  Menge  der  A-­‐Produk'onen,  dann  ist  für   1 ≤ i ≤ n  die  Steuermenge  Dk(A→ αi)  definiert  als  

Dk(A→ αi)  :=    startk  (FIRSTki)    .    FOLLOWk(A))  .  

 

Die  Entscheidung  unter  den αi kann  eindeu'g  getroffen  werden,  wenn  die   Mengen  Dk(A→ α1),  ...,  Dk(A→ αn)  alle  paarweise  disjunkt  sind.  

 

(43)

42  

LL(1)-­‐Gramma'k  

Eine  Gramma'k  ist  genau  dann  eine  LL(1)-­‐GrammaMk,  wenn  für  jedes   NTS  A  mit  A-­‐Produk'onen  A→ α1 | α2 | . . . | αn gilt:  

Die  Mengen  FIRST11),  .  .  .,  FIRST1n)  sind  paarweise  disjunkt.  

Genau  eine  der  Mengen  FIRST11),  .  .  .,  FIRST1n)  darf  das  leere   Wort  ε enthalten.  Wenn  ε ∈ FIRST1i),  dann  gilt:  FOLLOW1(A)  ist   disjunkt  von  allen  anderen  Mengen  FIRST1j),  i ≠ j.  

 

Für  k  =  1  reduziert  sich  die  Defini'on  der  Steuermengen  zu:    

     FIRST1i),  falls  ε ∉FIRST1i)      D1(A→ αi)  :=    

     FIRST1i)  –  {ε }  ∪ FOLLOW1(A)    sonst    

(44)

43  

Linksfaktorisierung  

cond if boolexpr then stmt fi| (3)

if boolexpr then stmt else stmt fi.

Mit k = 1, d.h. durch Ansehen des ersten Symbols if, ist die richtige Alternative nicht eindeutig zu bestimmen à Verletzung der LL(1)-Eigenschaft.

è  Grammatik so umschreiben, dass LL(1)-Eigenschaft erfüllt wird.

Verschiedene Alternativen einer Produktion haben ein gemeinsames Präfix: A → αβ1 | αβ2 è  Linksfaktorisierung

A → α A‘

A‘ → β1 | β2

cond if boolexpr then stmt cond-rest. (3a)

cond-rest fi | else stmt fi. (3b)

(45)

44  

Berechnung  der  FIRST-­‐Mengen  

Berechnung  von  FIRST(A)  für  alle  Gramma'ksymbole  A  ∈ NTS  ∪ TS.    

Ini'alisiere  FIRST(A)  :=  ∅.

Anwendung  der  folgenden  Regeln,  solange,  bis  keine  weiteren  TS  oder  ε der  Menge   hinzugefügt  werden  können.  

Wenn  A  ∈ TS:  FIRST  (A)  :=  {  A  }.  

Wenn  A  ∈ NTS  und  A  → ε ∈ P:  FIRST  (A)  :=  FIRST  (A)  ∪ ε.

Wenn  A ∈ NTS  und  A  → X1  X2  .  .  .  Xk  ∈  P:  

FIRST  (A)  :=  FIRST  (A) ∪ FIRST  (X1)  \  { ε }.

∀ i,  2  ≤ i ≤ k, mit ε ⊆ FIRST(X1),  ...,  ε ⊆ FIRST(Xi-­‐1):  

FIRST  (A)  :=  FIRST  (A) ∪ FIRST  (Xi)  \  { ε }.    

Wenn ε ⊆ FIRST(Xj)  für  j  =  1,2,  .  .  .,  k:  FIRST  (A)  :=  FIRST  (A)  ∪ ε

Diese  Berechnung  erfolgt  für  jede  Alterna've  in  A  → α12| ...| αn.

 

(46)

45  

FIRST-­‐Mengen  Berechnungsreihenfolge  

In  welcher  Reihenfolge  berechnet  man  denn  die  FIRST-­‐Mengen?  

1. Bes'mme  Menge  Nε von  NTS,  aus  denen  ε abgeleitet  werden   kann:  

Nε :=  {X  ∈  N  |  X  ⇒*  ε}.  

2. Zeichne  Graph,  dessen  Knoten  NTS  sind.  Für  jede  Produk'on    A  → X1  .  .  .  Xm    

i.  Füge  für  NTS  X1  eine  gerichtete  Kante  (A  → X1)  ein.  

ii.  Falls  X1  ∈ Nε und  X2 ∈  N,  füge  eine  gerichtete  Kante  (A  → X2)  ein.  

iii.  Weiter  so,  wenn  aufeinander  folgende  Xi ∈ Nε.

Kante  A → B  bedeutet:  berechne  FIRST(B)  vor  FIRST(A).  

 

(47)

46  

FIRST-­‐Mengen  für  Beispielgramma'k  1/3  

Nε = { term‘, numexpr‘ }

stmt

assignment cond loop

expr

boolexpr numexpr term

factor

cond-rest term‘

numexpr‘

(48)

47  

FIRST-­‐Mengen  für  Beispielgramma'k  2/3  

assignment id := expr.

cond if boolexpr then stmt cond-rest.

loop while boolexpr do stmt od.

stmt assignment | cond | loop.

factor id | const | (numexpr) . term factor term‘.

numexpr term numexpr‘.

boolexpr numexpr cop numexpr . expr boolexpr | numexpr.

cond-rest fi | else stmt fi . term‘ * factor term‘ | ε.

numexpr‘ + term numexpr‘ | ε.

FIRST-Mengen { id } { if } { while } { id, if, while } { id, const, ( } { id, const, ( } { id, const, ( } { id, const, ( } { id, const, ( } { fi, else } { *, ε } { +, ε }

(49)

48  

FIRST-­‐Mengen  für  Beispielgramma'k  3/3  

Beobachtung: Die FIRST-Mengen für die Alternativen boolexpr und numexpr sind nicht disjunkt – LL(1)-Konflikt !!!

Bei Produktion expr boolexpr | numexpr kann nicht eindeutig bestimmt werden, welche Alternative ausgewählt werden soll.

Ursache: Ein Ausdruck beginnt stets mit einem numerischen Ausdruck, ob er ein boolescher Ausdruck ist, kann erst beim Antreffen eines cop-Symbols entschieden werden.

Lösung: Linksfaktorisierung

expr numexpr bool-rest. { id, const, ( } (5a) bool-rest cop numexpr | ε . { cop, e } (5b)

expr boolexpr | numexpr. (5)

(50)

49  

Beispielgramma'k  (geändert)  

stmt assignment | cond | loop. (1)

assignment id := expr. (2)

cond if boolexpr then stmt cond-rest. (3a) cond-rest → fi | else stmt fi. (3b) loop while boolexpr do stmt od. (4) expr numexpr bool-rest. (5a) bool-rest cop numexpr | ε. (5b) boolexpr numexpr cop numexpr . (6)

numexpr term numexpr‘. (7a)

numexpr‘ + term numexpr‘ | ε . (7b)

term factor term‘. (8a)

term‘ * factor term‘ | ε. (8b)

factor id | const | (numexpr) . (9)

(51)

50  

Berechnung  der  FOLLOW-­‐Mengen  

Berechnung  der  FOLLOW-­‐Mengen  FOLLOW  (A)  ∀ A ∈  NTS.    

1.  FOLLOW(S)  :=  {  $  },  S  =  Startsymbol,  $  =  Endemarkierung  der  Eingabe.  

Anwendung  der  folgenden  Regeln,  solange,  bis  keine  weiteren  TS  der   Menge  hinzugefügt  werden  können:  

2.  Für  A αBβ ∈ P  mit  B  ∈ NTS  und  α, β ∈  NTS ∪ TS  mit β ≠ ε : FOLLOW  (B)  :=  FOLLOW  (B) ∪ FIRST  (β) \  { ε }, β ≠ ε.

3.  Für  A  αBβ oder  A  αB,  wobei  gilt  ε ∈ FIRST(β):  

FOLLOW  (B)  :=  FOLLOW  (B)    ∪    FOLLOW  (A  ).    

 

(52)

51  

FOLLOW-­‐Mengen  Berechnungsreihenfolge  

In  welcher  Reihenfolge  berechnet  man  denn  die  FOLLOW-­‐Mengen?  

1.  Zeichne  Graph:  jedes  NTS  =  ein  Knoten.  Die  Knoten  werden  markiert   (mit  TS  und  $).  Markiere  Startsymbol  S  mit  $.  

2.  Betrachte  alle  Produk'onen  aus  P.  Für  jede  Produk'on  betrachte  die   NTS  auf  deren  rechter  Seite.  

i.  A → αBβ ∈ P,  B    NTS, β ≠ ε :

-­‐  markiere  Knoten  B  mit  allen  Symbolen  aus  FIRST  (β)  außer  ε

-  ε ∈ FIRST  (β):  füge  Kante  A  →  B  ein  (falls  noch  nicht  drin  in  Graphen).  

ii.  A → αB ∈  P,  B  ∈ NTS,  füge  Kante  A  →  B  ein  (analog  ε ∈ FIRST  (β))  

3.  Berechne  alle  starken  Komponenten  des  Graphen  und  behandle  jede   Komponente  wie  einen  einzigen  Knoten  K;  

Markierung  (K)  := ∪ Markierungen  all  seiner  Knoten.  

4.  FOLLOW  (B)  :=  Markierung(B)  Markierungen  seiner  Vorgänger.  

 

(53)

52  

stmt

assignment cond loop

expr

boolexpr term

factor

cond-rest

term‘

numexpr‘

bool-rest

numexpr cop, do, then, ),

od, fi, else, $

cop, do, then, ), od, fi, else, +, $ +

* then, do

cop, )

od, fi, else, $

Abhängigkeiten nach 2i Abhängigkeiten nach 2ii

Direkte Markierungen (2i) Propagierte Markierungen (4)

FOLLOW-­‐Mengen  für  Beispielgramma'k  1/2  

Hinweis: Es sind nicht alle FOLLOW- Mengen vollständig angegeben.

(54)

53  

bool-rest → cop numexpr | ε .

term‘ * factor term‘ | ε.

numexpr‘ + term numexpr‘ | ε.

FIRST- und FOLLOW-Mengen { cop } { od, fi, else, $ } { * } { cop, do, then, ), od, fi, else, +, $ } { + } { cop, do, then, ), od, fi, else, $ }

FIRST- und FOLLOW-Mengen bzw. die Steuermengen für die Alternativen sind disjunkt à Grammatik hat LL(1)-Eigenschaft.

Steuermengen

FOLLOW-­‐Mengen  für  Beispielgramma'k  2/2  

(55)

54  

Zusammenfassendes  Beispiel  

Gegeben  ist  folgende  Gramma'k  für  arithme'sche  Ausdrücke:  

E E  +  T  |  T.  

T   T    *  F  |  F.  

F   (  E  )  |  id.  

Sorgen  Sie  dafür,  dass  die  Gramma'k  LL(1)-­‐Eigenschab  hat  und   berechnen  Sie  die  FIRST-­‐  und  FOLLOW-­‐Mengen.  

 

(56)

55  

id := id + const $

X Y Z

$

Predictive Parser

Analysetabelle (M)

Ausgabe: Folge von Produktionen, die eine Linksableitung darstellen

Top-­‐Down-­‐Parser  mit  Analysetabelle  

(57)

56  

Parser-­‐Konfigura'on  

Aktueller Zustand der Analyse:

($αX, xw$)

Stackinhalt Eingabe(rest)

Top of Stack Aktuelles Eingabesymbol

Startkonfiguration des Parsers: ($S, p$)

Arbeitsschritte des Parsers: Übergang von Konfiguration K nach K‘: KK‘ oder Ki K‘ (wenn Übergang mit Produktion i).

Endkonfiguration des Parsers: ($, $) – im Erfolgsfall oder ($αX, xw$) – im Fehlerfall

Startsymbol Programm

(58)

57  

Arbeitsweise  des  Parsers  

1.  ($αX, xw$) mit X ∈T und X = x → ($α, w$)

2.  ($αX, xw$) mit X ∈T und X ≠ x → error

3. ($αX, xw$) mit X ∈ N und M(X, x) = i, Pi = X → X1 ... Xmi ($α Xm ... X1, xw$)

4. ($αX, xw$) mit X ∈ N und M(X, x) = error → Abbruch mit Fehlermeldung

5.  ($, $) Stack und Eingabe sind abgearbeitet → Ende mit Erfolgsmeldung „accept“

 

(59)

58  

Konstruk'on  der  Analysetabelle  

Ausgangspunkt: Produktionen

Für jedes NTS A sei die Menge der A-Produktionen

i1 A α1 | D1

i2 A α2 | D2

. . .

in-1 A αn-1 | Dn-1

in A αn Dn

ij falls ∃ j ∈ {1, ..., n}: b ∈ Dj M[A, b] =

error sonst für alle A ∈ N und b ∈ (T ∪ $)

(60)

59  

Beispielgramma'k  –  Nummerierung  der  Produk'onen   und  Steuermengen    

(1)  stmt assignment | {id}

(2)  cond | {if}

(3)  loop. {while}

(4)  assignment id := expr. {id}

(5)  cond if boolexpr then stmt cond-rest. {if}

(6)  cond-rest fi | {fi}

(7)  else stmt fi. {else}

(8)  loop while boolexpr do stmt od. {while}

(9)  expr numexpr bool-rest. {id, const, ( }

(10)  bool-rest cop numexpr | {cop}

(11)  ε. {od, fi, else, $}

(12)  boolexpr numexpr cop numexpr . {id, const, ( }

(13)  numexpr termnumexpr‘. {id, const, ( }

(14)  numexpr‘ + term numexpr‘ | { + }

(15)  ε . {cop, do, then, ), od, fi, else, $}

(16)  term factor term‘. {id, const , ( }

(17)  term‘ * factor term‘ | { * }

(18)  ε. {cop, do, then, ), od, fi, else, +, $}

(19)  factor id | {id}

(20)  const | {const}

(21)  (numexpr) . { ( }

(61)

60  

Analysetabelle  für  Beispielgramma'k  

id := if then else fi while do od cop + * const ( ) $

stmt 1 2 3

assignment 4

cond 5

cond-rest 7 6

loop 8

expr 9 9 9

bool-rest 11 11 11 10 11

boolexpr 12 12 12

numexpr 13 13 13

numexpr' 15 15 15 15 15 15 14 15 15

term 16 16 16

term' 18 18 18 18 18 18 18 17 18 18

factor 19 20 21

Kein Eintrag è error

(62)

61  

Beispiel  für  Ablauf  Top-­‐Down-­‐Analyse  1/2  

Stack

$ stmt

$ assignment

$ expr := id

$ expr :=

$ expr

$ bool-rest numexpr

$ bool-rest numexpr‘ term

$ bool-rest numexpr‘ term‘ factor

$ bool-rest numexpr‘ term‘ c

$ bool-rest numexpr‘ term‘

$ bool-rest numexpr‘ term‘ factor *

$ bool-rest numexpr‘ term‘ factor

$ bool-rest numexpr‘ term‘ c

$ bool-rest numexpr‘ term‘

Eingabe id:=c*c+c$

id:=c*c+c$

id:=c*c+c$

:=c*c+c$

c*c+c$

c*c+c$

c*c+c$

c*c+c$

c*c+c$

*c+c$

*c+c$

c+c$

c+c$

+c$

Ausgabe 1 4

9 13 16 20 17 20 18

(63)

62  

Stack

$ bool-rest numexpr‘

$ bool-rest numexpr‘ term +

$ bool-rest numexpr‘ term

$ bool-rest numexpr‘ term‘ factor

$ bool-rest numexpr‘ term‘ c

$ bool-rest numexpr‘ term‘

$ bool-rest numexpr‘

$ bool-rest

$

Eingabe +c$

+c$

c$

c$

c$

$

$

$

$

Ausgabe 14 16 20 18 15 11 accept

Top-­‐Down-­‐Parser  mit  Analysetabelle  

(64)

63  

Prinzip  des  rekursiven  Abs'egs  (recursive  descent)  

Für jedes NTS N gibt es eine Prozedur, welche testet, ob die nächsten lexikalischen Elemente ein aus N ableitbares Wort bilden.

Ausgangspunkt: Menge der A-Produktionen

i1 A α1 | D1

i2 A α2 | D2

. . .

in-1 A αn-1 | Dn-1

in A αn Dn

procedure A {

if symbol ∈ D1 then output(i1); bearbeite(α1);

elsif symbol ∈ D2 then output(i2); bearbeite(α2);

. . .

if symbol ∈ Dn then output(in); bearbeite(αn);

else error;

fi;

}

(65)

64  

Rekursiver  Abs'eg  am  Beispiel  

Scanner-Aufruf procedure stmt {

if symbol = id then output(1); assignment;

elsif symbol = if then output(2); cond;

elsif symbol = while then output(3); loop;

else error;

fi;

}

procedure assignment { if symbol = id then

output(4); match(id); match(:=); expr;

else error;

fi;

}

procedure match (symboltype t) {

if symbol = t then nextsymbol; else error; fi;

}

Baum der wechselseitigen

Prozeduraufrufe spiegelt die Struktur des Ableitungsbaums wider.

Referenzen

ÄHNLICHE DOKUMENTE

Gehälter der Ärzte und Chemiker, die sich ausschließlich mit der Entwicklung dieses Produkts beschäftigen: DM 1.150.000,--, Materialeinzelkosten DM 380.000,--, sonstige

Rechtsform in der ein Unternehmen geführt wird, immer Bestandteile des handelsrechtlichen Jahresabschlusses. 3) Der nach HGB vorgeschriebene Anlagenspiegel muß von allen Kaufleuten,

es sich um einen Aktivtausch. 2) Das Konto Lieferantenbonus wird über ‘SBK’ abgeschlossen. 3) Als Anlagevermögen sind nur die Gegenstände auszuweisen, die bestimmt sind,

Die OHG erzielte 1999 einen Gewinn i.H.v. Wassermann, der nicht nur persönlich haftender Gesellschafter ist, sondern auch die Ge- schäftsführung der Firma übernommen hat, bekommt

ausgewiesen werden. 3) Maßgeblichkeitsprinzip bedeutet, daß die Steuerbilanz maßgeblich für die Handelsbilanz ist. 4) Der Anlagenspiegel muß bei Kapitalgesellschaften in der

Aktivum) ist Aufwand im alten Jahr, Ausgabe im neuen Jahr. 2) Durch das System der doppelten Buchführung ist es unmöglich, daß der Gewinn, der sich aus der GuV-Rechnung

schaft gehört die Bilanz, die Gewinn- und Verlustrechnung sowie der Anhang. 2) Beschließt die Hauptversammlung, daß mehr Gewinne ausgeschüttet werden sollen als bisher

lage als auch als Bareinlage erfolgen. 2) Die im HGB verankerten Vorschriften für die OHG werden auch als sogenanntes unabdingbares Recht bezeichnet. 3) In der Bilanz