Top Banner
Von Automaten zu Programmen 1 Tim Furche Compilerbau, Wintersemester 2008/09, Prof. F. Bry Manuelle und automatische Entwicklung von Parsern
75

Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Jul 17, 2015

Download

Education

Tim Furche
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Von Automaten zu Programmen

1

Tim Furche

Compilerbau, Wintersemester 2008/09, Prof. F. Bry

Manuelle und automatische Entwicklung von Parsern

Page 2: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

2

Beispiele aus der Praxis

Formale Sprachen:

Page 3: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

3

Nicht nur in Compilern!

Formale Sprachen:

Page 4: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Browser

4

Page 5: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

5

Page 6: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

6

URIs

HTML

Google Anfrage

CSS

JavaScript

Browser: Formale Sprachen

Page 7: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Spreadsheets: Excel/Numbers/OpenCalc

7

Page 8: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

8

Page 9: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

9

Formeln

Format Felder

Macros

Page 10: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Parser für Reguläre Sprachenz.B.: URIs, Datumsangaben, Gleitpunktzahlen

10

AEndliche

Automaten

Page 11: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Beispiel:Gleitpunktzahlen

11

Page 12: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

12

-666.797E-14

parsen, normalisieren

Page 13: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

13

Parsen und Normalisieren mit Endlichem Automaten

Gleitpunktzahlen

$java‐jarFPParser.jar‐666.797E‐14‐‐step

(Initial,‐666.797E‐14)

|‐(WholeNrDigit,666.797E‐14)

|‐(WholeNrDigit_or_Fraction_or_Exponent,66.797E‐14)

|‐(WholeNrDigit_or_Fraction_or_Exponent,6.797E‐14)

|‐(WholeNrDigit_or_Fraction_or_Exponent,.797E‐14)

|‐(FractionDigit,797E‐14)

|‐(FractionDigit_or_Exponent,97E‐14)

|‐(FractionDigit_or_Exponent,7E‐14)

|‐(FractionDigit_or_Exponent,E‐14)

|‐(Exponent,‐14)

|‐(ExponentDigit,14)

|‐(ExponentDigit_or_End,4)

|‐(ExponentDigit_or_End,)

Success:‐6.66797E‐12

‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐

Page 14: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

14

Page 15: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

15

Wie?

z.B. in Java

Page 16: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

16

Page 17: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

17

Bibliothek:Double.parseDouble()

Page 18: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

17

Bibliothek:Double.parseDouble()

Regulärer Ausdruck über Bibliothek:java.util.regex.Pattern&Matcher

Page 19: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

17

Bibliothek:Double.parseDouble()

Regulärer Ausdruck über Bibliothek:java.util.regex.Pattern&Matcher

Endliche Automaten Bibliothek:dk.brics.automaton

Page 20: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

17

Bibliothek:Double.parseDouble()

Regulärer Ausdruck über Bibliothek:java.util.regex.Pattern&Matcher

Endliche Automaten Bibliothek:dk.brics.automaton

Manuelle Implementierung

Page 21: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

17

Bibliothek:Double.parseDouble()

Regulärer Ausdruck über Bibliothek:java.util.regex.Pattern&Matcher

Endliche Automaten Bibliothek:dk.brics.automaton

Manuelle Implementierung

Page 22: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Ganzzahlen in JavaEndlicher Automat für den Ganzzahlparser in Long.parseLong

18

5

1 public static long parseLong(String s, int radix) throws NumberFormatException{

3 if (s == null) throw new NumberFormatException("null");[...]

5 int max = s.length();[...]

7 // State 1: Treat the signif (s.charAt(0) == ’-’) {

9 negative = true;limit = Long.MIN_VALUE;

11 i++;} else

13 limit = -Long.MAX_VALUE;

15 // State 2: Treat first digitif (i < max) {

17 digit = Character.digit(s.charAt(i++),radix);if (digit < 0) // Not a digit

19 throw NumberFormatException.forInputString(s);else

21 result = -digit;}

23

// State 3: Treat all other digits25 while (i < max) {

digit = Character.digit(s.charAt(i++),radix);27 if (digit < 0) // Not a digit

throw NumberFormatException.forInputString(s);29 result *= radix;

// Check if out-of-bounds [...]31 result -= digit;

}33 if (negative) {

if (i > 1)35 return result;

else /* Only got "-" */37 throw NumberFormatException.forInputString(s);

} else39 return -result;

41 }

Istart F R

‘-’

‘0’–‘9’

‘0’–‘9’

‘0’–‘9’

Page 23: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

19

5

1 public static long parseLong(String s, int radix) throws NumberFormatException{

3 if (s == null) throw new NumberFormatException("null");[...]

5 int max = s.length();[...]

7 // State 1: Treat the signif (s.charAt(0) == ’-’) {

9 negative = true;limit = Long.MIN_VALUE;

11 i++;} else

13 limit = -Long.MAX_VALUE;

15 // State 2: Treat first digitif (i < max) {

17 digit = Character.digit(s.charAt(i++),radix);if (digit < 0) // Not a digit

19 throw NumberFormatException.forInputString(s);else

21 result = -digit;}

23

// State 3: Treat all other digits25 while (i < max) {

digit = Character.digit(s.charAt(i++),radix);27 if (digit < 0) // Not a digit

throw NumberFormatException.forInputString(s);29 result *= radix;

// Check if out-of-bounds [...]31 result -= digit;

}33 if (negative) {

if (i > 1)35 return result;

else /* Only got "-" */37 throw NumberFormatException.forInputString(s);

} else39 return -result;

41 }

2 Von der Spezifikation zum Parser

Kurz gesagt entwickelt man einen Parser für Werte (i.e., Worte) einer regulärenSprache wie folgt:

• Spezifikation der Sprache durch regulären Ausdruck oder Automat.

Page 24: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

20

5

1 public static long parseLong(String s, int radix) throws NumberFormatException{

3 if (s == null) throw new NumberFormatException("null");[...]

5 int max = s.length();[...]

7 // State 1: Treat the signif (s.charAt(0) == ’-’) {

9 negative = true;limit = Long.MIN_VALUE;

11 i++;} else

13 limit = -Long.MAX_VALUE;

15 // State 2: Treat first digitif (i < max) {

17 digit = Character.digit(s.charAt(i++),radix);if (digit < 0) // Not a digit

19 throw NumberFormatException.forInputString(s);else

21 result = -digit;}

23

// State 3: Treat all other digits25 while (i < max) {

digit = Character.digit(s.charAt(i++),radix);27 if (digit < 0) // Not a digit

throw NumberFormatException.forInputString(s);29 result *= radix;

// Check if out-of-bounds [...]31 result -= digit;

}33 if (negative) {

if (i > 1)35 return result;

else /* Only got "-" */37 throw NumberFormatException.forInputString(s);

} else39 return -result;

41 }

Istart F R

‘-’

‘0’–‘9’

‘0’–‘9’

‘0’–‘9’

Page 25: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

21

Page 26: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Gleitpunktzahlen in JavaSpezifikation: Regulärer Ausdruck

22

6

2 Von der Spezifikation zum Parser

Kurz gesagt entwickelt man einen Parser für Werte (i.e., Worte) einer regulärenSprache wie folgt:

• Spezifikation der Sprache durch regulären Ausdruck oder Automat.

• Auswahl einer Implementierungstechnik.

• Anwendung des Musters der Implementierungstechnik.

Solange es nur um das Wortproblem geht, also die Erkennung, ob ein Wert teilder Sprache ist (eine String eine URI sein könnte), geht das rein mechanisch. So-bald jedoch auch Berechnungen auszuführen sind, z.B., das Berechnen der Gleit-punktzahl, ist es nötig den generischen Ansatz an die jeweilige Aufgabe anzupas-sen.

2.1 Regulärer Ausdruck für Gleitpunktzahlen

Für unser Beispiel beginnen wir mit einem regulären Ausdruck für die Art vonGleitpunktzahlen, die unser Parser erkennen soll:

(‘+’|‘-’)? digit+ (‘.’ digit+)? ((‘e’|‘E’) digit+)?

digit := ‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’ | ‘7’ | ‘8’ | ‘9’digit+ := digit digit*

Die Spezifikation ist fast wie in den Übungen behandelt, allerdings erlauben wirdass der Nachkomma-Anteil wegfallen kann (wie der Exponent).

2.2 Endlicher Automat für Gleitpunktzahlen

Die gleiche Sprache können wir durch folgenden Automaten beschreiben:

6

2 Von der Spezifikation zum Parser

Kurz gesagt entwickelt man einen Parser für Werte (i.e., Worte) einer regulärenSprache wie folgt:

• Spezifikation der Sprache durch regulären Ausdruck oder Automat.

• Auswahl einer Implementierungstechnik.

• Anwendung des Musters der Implementierungstechnik.

Solange es nur um das Wortproblem geht, also die Erkennung, ob ein Wert teilder Sprache ist (eine String eine URI sein könnte), geht das rein mechanisch. So-bald jedoch auch Berechnungen auszuführen sind, z.B., das Berechnen der Gleit-punktzahl, ist es nötig den generischen Ansatz an die jeweilige Aufgabe anzupas-sen.

2.1 Regulärer Ausdruck für Gleitpunktzahlen

Für unser Beispiel beginnen wir mit einem regulären Ausdruck für die Art vonGleitpunktzahlen, die unser Parser erkennen soll:

(‘+’|‘-’)? digit+ (‘.’ digit+)? ((‘e’|‘E’) digit+)?

digit := ‘0’ | ‘1’ | ‘2’ | ‘3’ | ‘4’ | ‘5’ | ‘6’ | ‘7’ | ‘8’ | ‘9’digit+ := digit digit*

Die Spezifikation ist fast wie in den Übungen behandelt, allerdings erlauben wirdass der Nachkomma-Anteil wegfallen kann (wie der Exponent).

2.2 Endlicher Automat für Gleitpunktzahlen

Die gleiche Sprache können wir durch folgenden Automaten beschreiben:

Page 27: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

23

7

Ss,dstart Sd

Sd ,p,e Fd Fd ,e

Es,d

Ed Ed ,#

‘+’, ‘-’

‘0’–‘9’‘0’–‘9’

‘0’–‘9’

‘.’

‘e’, ‘E’

‘0’–‘9’

‘0’–‘9’

‘e’, ‘E’

‘0’–‘9’

‘+’, ‘-’

‘0’–‘9’

‘0’–‘9’

Der Automat verwendet die folgenden Zustände, benannt nach denjenigenSymbolen des Alphabets, für die es einen Übergang in einen Nicht-Fehlerzustandgibt. Dabei nennen wir für eine Gleitpunktzahl s. f · 10e : s den significand (oderVorkomma-Anteil der Mantisse), f die fraction (oder Nachkomma-Anteil der Man-tisse), und e den exponent.

state part of number follow characters description

Ss,d significand digit (d ) or sign (s) initial state, recognizes optional sign

Sd –”– digit ensures at least one digit in the non-fraction part of the significand

Sd , f ,e –”– digit, or period (p) or e recognizes any number of digits and tran-sitions to fraction or exponent, final state

Fd fraction digit ensures at least one digit in fraction

Fd ,e –”– digit or e recognizes any number of digits and tran-sitions to exponent, final state

Es,d exponent digit or sign sign or digit as start of exponent

Ed –”– digit ensures at least one digit in exponent

Ed –”– digit recognizes any number of digits, finalstate

Page 28: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

24

7

Ss,dstart Sd

Sd ,p,e Fd Fd ,e

Es,d

Ed Ed ,#

‘+’, ‘-’

‘0’–‘9’‘0’–‘9’

‘0’–‘9’

‘.’

‘e’, ‘E’

‘0’–‘9’

‘0’–‘9’

‘e’, ‘E’

‘0’–‘9’

‘+’, ‘-’

‘0’–‘9’

‘0’–‘9’

Der Automat verwendet die folgenden Zustände, benannt nach denjenigenSymbolen des Alphabets, für die es einen Übergang in einen Nicht-Fehlerzustandgibt. Dabei nennen wir für eine Gleitpunktzahl s. f · 10e : s den significand (oderVorkomma-Anteil der Mantisse), f die fraction (oder Nachkomma-Anteil der Man-tisse), und e den exponent.

Zustand Teil der Zahl Nachfolgerzeichen Beschreibung

Ss,d significand Ziffer (d ) oder Vorzeichen (s) Anfangszustand, erkennt optionales Vor-zeichen

Sd –”– Ziffer stellt sicher, dass zumindest eine Ziffer imsignificand vorkommt

Sd , f ,e –”– Ziffer, Punkt (p) oder e erkennt beliebige Folgen von Ziffern, fährtmit Erkennung von fraction oder expo-nent fort, Endzustand

Fd fraction Ziffer stellt sicher, dass zumindest eine Ziffer infraction vorkommt

Fd ,e –”– Ziffer or e erkennt beliebige Folgen von Ziffern, fährtmit Erkennung von exponent fort, Endzu-stand

Es,d exponent Ziffer oder Vorzeichen Ziffer oder Vorzeichen als Beginn des ex-ponent

Ed –”– digit stellt sicher, dass zumindest eine Ziffer inexponent vorkommt

Ed –”– digit erkennt beliebige Folgen von Ziffern, End-zustand

Page 29: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Implicit state: wie Long.parseLong(); Zustand implizit

Bereich im Programm identifiziert den aktuellen Zustand (PC)

für einfach, im wesentlichen sequentielle Automaten geeignet

Loop-and-switch:

Schleife über Eingabe + goto/switch je nach akt. Zustand und Symbol

effizient nur wenn Sprünge berechnet werden können

typisch für komplexere Automaten mit oft wiederkehrenden Zuständen

Loop-and-lookup: Schleife + Nachschlagen in Tabellenrepr. von δZeilen: Zustände, Spalten: Eingabesymbole, Zelleninhalt: Folgezustand

Zeit-effizient auf Kosten von Speicher, nur bei kleinem Eingabealphabet

z.B. reguläre Ausdrücke über Basispaarsequenzen (nur A, T, G, C).

25

Implementierung Endlicher Automaten

Ansätze …

Page 30: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

FPParser: abstrakte Oberklasse für alle Floating-Point-Parser

Attribute & Methoden zur Verwaltung & Berechnung der FP-Zahl

FPPaser.FPNumberPart: hält ganzzahligen Anteil einer FP-Zahl

significand (Vorkomma-Anteil), fraction (Nachkomma-Antail), exponent

#parse(char): Transition & Berechnung des Automaten

bei Eingabe eines einzelnen Zeichens

#parse(String): Schleife über die Eingabe

für jedes Zeichen wird #parse(char) aufgerufen

26

Implementierung Endlicher Automaten

Umgebung für FP-Parser …

Page 31: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

FPParser: abstrakte Oberklasse für alle Floating-Point-Parser

Attribute & Methoden zur Verwaltung & Berechnung der FP-Zahl

FPPaser.FPNumberPart: hält ganzzahligen Anteil einer FP-Zahl

significand (Vorkomma-Anteil), fraction (Nachkomma-Antail), exponent

#parse(char): Transition & Berechnung des Automaten

bei Eingabe eines einzelnen Zeichens

#parse(String): Schleife über die Eingabe

für jedes Zeichen wird #parse(char) aufgerufen

26

Implementierung Endlicher Automaten

Umgebung für FP-Parser …

FPParser

Page 32: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

27

Implementierung Endlicher Automaten

Loop-and-Switch …

8

3 Diskussion der Implementierungsansätze

Diesen Automaten können wir auf unterschiedliche Weise implementieren. InFPParser.jar finden sich drei gebräuchliche Varianten. Alle varianten haben ge-meinsam, dass sie über alle Zeichen der Eingabe iterieren (daher der loop-Anteilim Nahmen). Für bestimmte Parsing-Probleme (z.B. mit eingeschränkteren Spra-chen wie dem Suchen von Vorkommen eines Strings in einem Text) gibt es Par-ser, die nicht alle Zeichen der Eingabe betrachten müßen. Diese werden hier abernicht weiter betrachtet.

Loop-and-Switch: realisiert in PlainFPParser. Die Idee von loop-and-switch Im-plementierungen ist, in der Schleife über die Eingabezeichen mit Hilfe vonBedingungen oder Switch-Ausdrücken für alle relevanten Kombinationenaus Zustand und Eingabezeichen den Folgezustand (und eventuelle Berech-nungsschritte) zu spezifizieren.

Dies ist illustriert in PlainFPParser#parse(char). Das folgende Programm-frament illustriert beispielsweise die Übergangsfunktion für den ZustandSd , f ,e (im Code expandiert zu STATE_SignifDigit_Fraction_Exponent): beieiner Ziffer bleiben wir im gleichen Zustand und fügen die Ziffer zur aktu-ellen Repräsentation des significand hinzu. Bei einem Punkt gehen wir inden Zustand Fd , also erwarten die erste Ziffer der fraction (würden wir hierin Fd ,e übergehen, wären auch Zahlen der Form 12.E10 erlaubt). Bei eineme oder E gehen wir in Zustand Es,d (STATE_Exponent). In den beiden letztenFällen dienen die Zeichen nur als Trennzeichen und werden nicht zur aktu-ellen Repräsentation hinzugefügt.

1 case STATE_SignifDigit_Fraction_Exponent:if(Character.isDigit(c)) {

3 state = STATE_SignifDigit_Fraction_Exponent;significand.addDigit(c);

5 }else if(c == ’.’) {

7 state = STATE_FractionDigit;}

9 else if(c == ’e’ || c == ’E’) {state = STATE_Exponent;

11 }else state = STATE_Failure;

13 break;

Loop-and-Lookup: realisiert in MatrixFPParser. Die Idee von loop-and-lookup Im-plementierungen ist, in der Schleife über die Eingabezeichen mit Hilfe ei-ner (konstanten) Lookup-Tabelle den Folgezustand (und eventuelle Berech-

Page 33: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

27

Implementierung Endlicher Automaten

Loop-and-Switch …

8

3 Diskussion der Implementierungsansätze

Diesen Automaten können wir auf unterschiedliche Weise implementieren. InFPParser.jar finden sich drei gebräuchliche Varianten. Alle varianten haben ge-meinsam, dass sie über alle Zeichen der Eingabe iterieren (daher der loop-Anteilim Nahmen). Für bestimmte Parsing-Probleme (z.B. mit eingeschränkteren Spra-chen wie dem Suchen von Vorkommen eines Strings in einem Text) gibt es Par-ser, die nicht alle Zeichen der Eingabe betrachten müßen. Diese werden hier abernicht weiter betrachtet.

Loop-and-Switch: realisiert in PlainFPParser. Die Idee von loop-and-switch Im-plementierungen ist, in der Schleife über die Eingabezeichen mit Hilfe vonBedingungen oder Switch-Ausdrücken für alle relevanten Kombinationenaus Zustand und Eingabezeichen den Folgezustand (und eventuelle Berech-nungsschritte) zu spezifizieren.

Dies ist illustriert in PlainFPParser#parse(char). Das folgende Programm-frament illustriert beispielsweise die Übergangsfunktion für den ZustandSd , f ,e (im Code expandiert zu STATE_SignifDigit_Fraction_Exponent): beieiner Ziffer bleiben wir im gleichen Zustand und fügen die Ziffer zur aktu-ellen Repräsentation des significand hinzu. Bei einem Punkt gehen wir inden Zustand Fd , also erwarten die erste Ziffer der fraction (würden wir hierin Fd ,e übergehen, wären auch Zahlen der Form 12.E10 erlaubt). Bei eineme oder E gehen wir in Zustand Es,d (STATE_Exponent). In den beiden letztenFällen dienen die Zeichen nur als Trennzeichen und werden nicht zur aktu-ellen Repräsentation hinzugefügt.

1 case STATE_SignifDigit_Fraction_Exponent:if(Character.isDigit(c)) {

3 state = STATE_SignifDigit_Fraction_Exponent;significand.addDigit(c);

5 }else if(c == ’.’) {

7 state = STATE_FractionDigit;}

9 else if(c == ’e’ || c == ’E’) {state = STATE_Exponent;

11 }else state = STATE_Failure;

13 break;

Loop-and-Lookup: realisiert in MatrixFPParser. Die Idee von loop-and-lookup Im-plementierungen ist, in der Schleife über die Eingabezeichen mit Hilfe ei-ner (konstanten) Lookup-Tabelle den Folgezustand (und eventuelle Berech-

PlainFPParser

Page 34: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

28

Implementierung Endlicher Automaten

Loop-and-Switch …

10

SIGNIF_DIGIT_FRACTION_EXPONENT {2 State transition(char c, FPNumberPart nr){

if(Character.isDigit(c)) {4 nr.addDigit(c);

return SIGNIF_DIGIT_FRACTION_EXPONENT;6 }

else if(c == ’.’) {8 return FRACTION_DIGIT;

}10 else if(c == ’e’ || c == ’E’) {

return EXPONENT;12 }

else return FAILURE;14 }

FPNumberPart select(FPNumberPart s, FPNumberPart f, FPNumberPart!!e){ return s; }

16 boolean isFinal(){ return true; }boolean isFailure(){ return false; }

18 },

3.1 Tests

Um sich zu vergewissern, dass die Implementierungen weitgehend korrekt sind,steht das Kommandozeilen-Interface in FPParserCLI zur Verfügung. Daneben gibtes auch einen JUnit 4 Testcase in FPParserTestCase der gleich eine ganze Rei-he von kanonischen Eingaben testet. Zur Ausführung wird JUnit 4 benötigt, siehehttp://www.junit.org/.

Page 35: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

28

Implementierung Endlicher Automaten

Loop-and-Switch …

10

SIGNIF_DIGIT_FRACTION_EXPONENT {2 State transition(char c, FPNumberPart nr){

if(Character.isDigit(c)) {4 nr.addDigit(c);

return SIGNIF_DIGIT_FRACTION_EXPONENT;6 }

else if(c == ’.’) {8 return FRACTION_DIGIT;

}10 else if(c == ’e’ || c == ’E’) {

return EXPONENT;12 }

else return FAILURE;14 }

FPNumberPart select(FPNumberPart s, FPNumberPart f, FPNumberPart!!e){ return s; }

16 boolean isFinal(){ return true; }boolean isFailure(){ return false; }

18 },

3.1 Tests

Um sich zu vergewissern, dass die Implementierungen weitgehend korrekt sind,steht das Kommandozeilen-Interface in FPParserCLI zur Verfügung. Daneben gibtes auch einen JUnit 4 Testcase in FPParserTestCase der gleich eine ganze Rei-he von kanonischen Eingaben testet. Zur Ausführung wird JUnit 4 benötigt, siehehttp://www.junit.org/.

EnumFPParser

Page 36: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

29

Implementierung Endlicher Automaten

Loop-and-Lookup …

9

nungsschritte) zu spezifizieren. In der Lookup-Tabelle sind den ZuständenZeilen, den Eingabezeichen Spalten zugeordnet.

Die Lookup-Tabelle findet sich in MatrixFPParser#stateMatrix und ist eineziemlich direkte Umsetzung der ! Übergangsfunktion des Automaten. Fürden gleichen Zustand wie oben ergibt sich z.B. folgender Eintrag in der Ma-trix:

1 // STATE_SignifDigit_Fraction_Exponent{ // (STATE_SignifDigit_Fraction_Exponent, SCLASS_Digit)

3 new DigitEffect(STATE_SignifDigit_Fraction_Exponent,!!significand),

// (STATE_SignifDigit_Fraction_Exponent, SCLASS_Sign)5 new Effect(STATE_Failure, significand),

// (STATE_SignifDigit_Fraction_Exponent, SCLASS_Expn)7 new Effect(STATE_Exponent, significand),

// (STATE_Initial, SCLASS_Period)9 new Effect(STATE_FractionDigit, significand),

// (STATE_SignifDigit_Fraction_Exponent, SCLASS_Rest)11 new Effect(STATE_Failure, significand)

},

In jeder Zelle der Lookup-Tabelle findet sich ein Effect Objekt, dassden nächsten Zustand und die auszuführenden Berechnungsschritteenthält. Um die Berechnungsschritte zu paramerterisieren verwendetMatrixFPParser Funktionsobjekte (wo Sprachen wie C++ Funktionspointerverwenden würden), siehe DigitEffect und SignEffect.

Loop-and-Switch mit Zustandsobjekten: realisiert in EnumFPParser. Eine elegantereRealisierung des loop-and-switch Ansatzes, die Zustandsobjekte, eine enumKlasse und anonyme Klassen für die Spezialisierung abstrakter enum Klassenverwendet, um alle Informationen über einen Zustand zu kapseln.

Die Spezifikation eines Zustandes, wie im folgenden gezeigt, enthält hier al-le relevanten Information, so dass man direkt sehen kann, ob es sich z.B. umeinen Endzustand handelt. Auch die Übergangsfunktion ist so klar partitio-niert:

SIGNIF_DIGIT_FRACTION_EXPONENT {2 State transition(char c, FPNumberPart nr){

if(Character.isDigit(c)) {4 nr.addDigit(c);

return SIGNIF_DIGIT_FRACTION_EXPONENT;6 }

else if(c == ’.’) {8 return FRACTION_DIGIT;

}

Page 37: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

29

Implementierung Endlicher Automaten

Loop-and-Lookup …

MatrixFPParser

9

nungsschritte) zu spezifizieren. In der Lookup-Tabelle sind den ZuständenZeilen, den Eingabezeichen Spalten zugeordnet.

Die Lookup-Tabelle findet sich in MatrixFPParser#stateMatrix und ist eineziemlich direkte Umsetzung der ! Übergangsfunktion des Automaten. Fürden gleichen Zustand wie oben ergibt sich z.B. folgender Eintrag in der Ma-trix:

1 // STATE_SignifDigit_Fraction_Exponent{ // (STATE_SignifDigit_Fraction_Exponent, SCLASS_Digit)

3 new DigitEffect(STATE_SignifDigit_Fraction_Exponent,!!significand),

// (STATE_SignifDigit_Fraction_Exponent, SCLASS_Sign)5 new Effect(STATE_Failure, significand),

// (STATE_SignifDigit_Fraction_Exponent, SCLASS_Expn)7 new Effect(STATE_Exponent, significand),

// (STATE_Initial, SCLASS_Period)9 new Effect(STATE_FractionDigit, significand),

// (STATE_SignifDigit_Fraction_Exponent, SCLASS_Rest)11 new Effect(STATE_Failure, significand)

},

In jeder Zelle der Lookup-Tabelle findet sich ein Effect Objekt, dassden nächsten Zustand und die auszuführenden Berechnungsschritteenthält. Um die Berechnungsschritte zu paramerterisieren verwendetMatrixFPParser Funktionsobjekte (wo Sprachen wie C++ Funktionspointerverwenden würden), siehe DigitEffect und SignEffect.

Loop-and-Switch mit Zustandsobjekten: realisiert in EnumFPParser. Eine elegantereRealisierung des loop-and-switch Ansatzes, die Zustandsobjekte, eine enumKlasse und anonyme Klassen für die Spezialisierung abstrakter enum Klassenverwendet, um alle Informationen über einen Zustand zu kapseln.

Die Spezifikation eines Zustandes, wie im folgenden gezeigt, enthält hier al-le relevanten Information, so dass man direkt sehen kann, ob es sich z.B. umeinen Endzustand handelt. Auch die Übergangsfunktion ist so klar partitio-niert:

SIGNIF_DIGIT_FRACTION_EXPONENT {2 State transition(char c, FPNumberPart nr){

if(Character.isDigit(c)) {4 nr.addDigit(c);

return SIGNIF_DIGIT_FRACTION_EXPONENT;6 }

else if(c == ’.’) {8 return FRACTION_DIGIT;

}

Page 38: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

30

Implementierung Endlicher Automaten

Loop-and-Lookup …Ziffer Vorzeichen ‘e’, ‘E’ Punkt

Initial SignifD_F_E SignifD Failure Failure

SignifD SignifD Failure Failure Failure

SignifD_F_E SignifD_F_E Failure Exponent FractionD

FractionD FractionD_E Failure Failure Failure

FractionD_E FractionD_E Failure Exponent Failure

Exponent ExponentD_End ExponentD Failure Failure

ExponentD ExponentD_End Failure Failure Failure

ExponentD_End ExponentD_End Failure Failure Failure

Failure Failure Failure Failure Failure

Page 39: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

31

Parsen und Normalisieren mit Endlichem Automaten

Gleitpunktzahlen

$java‐jarFPParser.jar33E0‐‐step‐‐pEnum

(INITIAL,33E0)

|‐(SIGNIF_DIGIT_FRACTION_EXPONENT,3E0)

|‐(SIGNIF_DIGIT_FRACTION_EXPONENT,E0)

|‐(EXPONENT,0)

|‐(EXPONENT_DIGIT_END,<epsilon>)

Success:33.0

‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐

Page 40: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

32

Page 41: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Parser für kontextfreie Sprachen++z.B. für arithmetische Ausdrücke und Erweiterungen

33

BKeller-

Automaten

Page 42: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

34

Beispiel: Arithmetischer Ausdruck

Page 43: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

35

2 + 4 * 11 - 2 * 3 + 2

parsen, ausrechnen

Page 44: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

36

Parsen und Ausrechnen mit Kellerautomaten

Arithmetische Ausdrücke

$java‐jarParserGenerators.jar‐‐pIntExpr_Eval‐‐fileplain‐intexpr

Expressioninline1:42

2+4*11‐2*3+2

$java‐jarParserGenerators.jar‐‐pIntExpr_AST‐‐fileplain‐intexpr

(+(‐(+2(*411))(*23))2)

$java‐jarParserGenerators.jar‐‐pIntExpr‐‐fileplain‐intexpr

<nooutput>(=noerror)

Page 45: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

37

Page 46: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

38

Parsen und Ausrechnen mit Kellerautomaten

+ Variablen

$java‐jarParserGenerators.jar‐‐pIntExpr_Var‐‐filevar‐intexpr

line3:24ruleatomfailedpredicate:{declaredVariables.contains($ID.text)}?

$java‐jarParserGenerators.jar‐‐pIntExpr_Eval‐‐filevar‐intexpr

line3:24ruleatomfailedpredicate:{undeclaredvariablez}?

Expressioninline3:420

Expressioninline4:6

$java‐jarParserGenerators.jar‐‐pIntExpr‐‐filevar‐intexpr

<nooutput>(=noerror)

x=78

y=2

112+4*x‐2*y+z*2

5+3‐2

Page 47: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

39

Page 48: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Arithmetik & Parsergeneratoren

Grammatik

40

3

1 /*------------------------------------------------------------------

* PARSER RULES3 *------------------------------------------------------------------*/prog: stat+ ;

5

stat: expr NEWLINE7 |ID ’=’ expr NEWLINE

|NEWLINE9 ;

11 expr: multExpr ( (’+’ |’-’) multExpr )*

13 ;

15 multExpr: atom (’*’ atom )*

17 ;

19 atom: INT

21 |ID|’(’ expr ’)’

23 ;

25 /*------------------------------------------------------------------

* LEXER RULES27 *------------------------------------------------------------------*/

29 ID : (’a’..’z’|’A’..’Z’)+ ;INT : ’0’..’9’+ ;

31 NEWLINE:’\r’? ’\n’ ;WS : (’ ’|’\t’)+ {skip();} ;

Beispiel: -666.797E-14

Zum Ausprobieren der Parser einfach folgendem Rezept folgen:

• FPParser.jar herunterladen und mit

$ java -jar FPParser.jar

testen, ob alle Abhängigkeiten vorhanden sind (Java >= 1.5, nur für Testcasesauch JUnit 4).

• Wenn das klappt, einfach Gleitpunktzahl als Parameter übergeben:

Page 49: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Arithmetik & Parsergeneratoren

Lexer-Regeln der Grammatik

41

3

1 /*------------------------------------------------------------------

* PARSER RULES3 *------------------------------------------------------------------*/prog: stat+ ;

5

stat: expr NEWLINE7 |ID ’=’ expr NEWLINE

|NEWLINE9 ;

11 expr: multExpr ( (’+’ |’-’) multExpr )*

13 ;

15 multExpr: atom (’*’ atom )*

17 ;

19 atom: INT

21 |ID|’(’ expr ’)’

23 ;

25 /*------------------------------------------------------------------

* LEXER RULES27 *------------------------------------------------------------------*/

29 ID : (’a’..’z’|’A’..’Z’)+ ;INT : ’0’..’9’+ ;

31 NEWLINE:’\r’? ’\n’ ;WS : (’ ’|’\t’)+ {skip();} ;

Beispiel: -666.797E-14

Zum Ausprobieren der Parser einfach folgendem Rezept folgen:

• FPParser.jar herunterladen und mit

$ java -jar FPParser.jar

testen, ob alle Abhängigkeiten vorhanden sind (Java >= 1.5, nur für Testcasesauch JUnit 4).

• Wenn das klappt, einfach Gleitpunktzahl als Parameter übergeben:

Was ist die Aufgabe eines Lexers?

Page 50: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Struktur eines ANTLR-ParserLexer, Parser, AST, Token vs. Character-Strom

42

Lexer ParserTokenStrom

Abstract Syntax Tree

(auch Scanner, Tokenizer)

CharacterStrom

direkte Ausgaben, Fehler

Page 51: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Von Characters zu TokensAufgabe des Lexers

43

WS

w i d t h = 2 0 0 ; \n

ID

Characters

WS= INT ;

WSTokens

Page 52: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Parser.javaWas hinten herauskommt …

44

void multExpr() { try { atom(); while( <<next input symbol is '*' >> ) { match('*'); atom(); } } [... error handling] } void atom() { try { int alt=3; switch (<< next input symbol >>) { case INT: alt = 1; break; case ID: alt = 2; break; case '(': alt = 3; break; default: [error] } switch(alt){ case 1: match(INT); break; case 2: match(ID); break; case 3: match('('); expr(); match(')'); break; } } [... error handling] }

Page 53: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Arithmetik & Parsergeneratoren

Grammatik

45

3

1 /*------------------------------------------------------------------

* PARSER RULES3 *------------------------------------------------------------------*/prog: stat+ ;

5

stat: expr NEWLINE7 |ID ’=’ expr NEWLINE

|NEWLINE9 ;

11 expr: multExpr ( (’+’ |’-’) multExpr )*

13 ;

15 multExpr: atom (’*’ atom )*

17 ;

19 atom: INT

21 |ID|’(’ expr ’)’

23 ;

25 /*------------------------------------------------------------------

* LEXER RULES27 *------------------------------------------------------------------*/

29 ID : (’a’..’z’|’A’..’Z’)+ ;INT : ’0’..’9’+ ;

31 NEWLINE:’\r’? ’\n’ ;WS : (’ ’|’\t’)+ {skip();} ;

Beispiel: -666.797E-14

Zum Ausprobieren der Parser einfach folgendem Rezept folgen:

• FPParser.jar herunterladen und mit

$ java -jar FPParser.jar

testen, ob alle Abhängigkeiten vorhanden sind (Java >= 1.5, nur für Testcasesauch JUnit 4).

• Wenn das klappt, einfach Gleitpunktzahl als Parameter übergeben:

{ declaredVariables.add($ID.text); }

{ declaredVariables.contains($ID.text) }?

Page 54: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Arithmetik & Parsergeneratoren

Grammatik

45

3

1 /*------------------------------------------------------------------

* PARSER RULES3 *------------------------------------------------------------------*/prog: stat+ ;

5

stat: expr NEWLINE7 |ID ’=’ expr NEWLINE

|NEWLINE9 ;

11 expr: multExpr ( (’+’ |’-’) multExpr )*

13 ;

15 multExpr: atom (’*’ atom )*

17 ;

19 atom: INT

21 |ID|’(’ expr ’)’

23 ;

25 /*------------------------------------------------------------------

* LEXER RULES27 *------------------------------------------------------------------*/

29 ID : (’a’..’z’|’A’..’Z’)+ ;INT : ’0’..’9’+ ;

31 NEWLINE:’\r’? ’\n’ ;WS : (’ ’|’\t’)+ {skip();} ;

Beispiel: -666.797E-14

Zum Ausprobieren der Parser einfach folgendem Rezept folgen:

• FPParser.jar herunterladen und mit

$ java -jar FPParser.jar

testen, ob alle Abhängigkeiten vorhanden sind (Java >= 1.5, nur für Testcasesauch JUnit 4).

• Wenn das klappt, einfach Gleitpunktzahl als Parameter übergeben:

{ declaredVariables.add($ID.text); }

{ declaredVariables.contains($ID.text) }?Test!

Page 55: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

46

grammar IntExpr_Var;

options { language = Java; superClass = RunnableParser; }

@lexer::header{ package de.lmu.ifi.pms.parsergenerators; }

@header{ package de.lmu.ifi.pms.parsergenerators; import java.util.Set; import java.util.HashSet; }

@members {

/** Set for maintaining already declared variables. */ Set declaredVariables = new HashSet();

public static RunnableParser getParserInstance(ANTLRStringStream stream){ [...] }

public void run(ASTProcessor... processors){ try { prog(); } catch (Exception e) [...] }}

Prolog

Page 56: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

47

prog: stat+ ; stat: // Semantic action for printing out the value returned by the evaluation of each expression expr NEWLINE { System.out.println("Expression in line " + input.get(input.index()-1).getLine() + ": " + $expr.value);} // Semantic action for constructing the set of declared variables. | ID '=' expr NEWLINE { varValues.put($ID.text, new Integer($expr.value)); } | NEWLINE ;

// All rules of the grammar get a return value, the computed value of their matching expressionexpr returns [int value] : e=multExpr {$value = $e.value;} // We need to distinguish addition and subtraction ( '+' e=multExpr {$value += $e.value;} | '-' e=multExpr {$value -= $e.value;} )* ;

multExpr returns [int value] : e=atom {$value = $e.value;} ('*' e=atom {$value *= $e.value;})* ;

atom returns [int value] : INT {$value = Integer.parseInt($INT.text);} | ID { Integer v = varValues.get($ID.text); if ( v!=null ) $value = v.intValue(); else throw new FailedPredicateException(input, "atom", "undeclared variable "+$ID.text); } | '(' expr ')' {$value = $expr.value;} ;

Page 57: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

47

prog: stat+ ; stat: // Semantic action for printing out the value returned by the evaluation of each expression expr NEWLINE { System.out.println("Expression in line " + input.get(input.index()-1).getLine() + ": " + $expr.value);} // Semantic action for constructing the set of declared variables. | ID '=' expr NEWLINE { varValues.put($ID.text, new Integer($expr.value)); } | NEWLINE ;

// All rules of the grammar get a return value, the computed value of their matching expressionexpr returns [int value] : e=multExpr {$value = $e.value;} // We need to distinguish addition and subtraction ( '+' e=multExpr {$value += $e.value;} | '-' e=multExpr {$value -= $e.value;} )* ;

multExpr returns [int value] : e=atom {$value = $e.value;} ('*' e=atom {$value *= $e.value;})* ;

atom returns [int value] : INT {$value = Integer.parseInt($INT.text);} | ID { Integer v = varValues.get($ID.text); if ( v!=null ) $value = v.intValue(); else throw new FailedPredicateException(input, "atom", "undeclared variable "+$ID.text); } | '(' expr ')' {$value = $expr.value;} ;

Page 58: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Parser + AktionenWas hinten herauskommt …

48

public int expr() { int value = 0; // return value int e = 0; try { e = multExpr(); value = e; loop3: while(true) { int alt = 3; if (<<next input symbol is '+'>>) alt = 1; else if (<<next input symbol is '-'>>) alt = 2; switch(alt) { case 1: match('+'); e = multExpr(); value += e; break; case 2: [...] } } } [...] }

Page 59: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

49

Page 60: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Trennung syntaktische / semantische Analyse

effiziente, kontext-freie Parser für syntaktische Analyse

Semantische Analyse

volle Programmiersprache mittels Traversierung/Transformation des AST

aber: schwer, oft weitgehend unabhängig von Sprache, ineffizient

Attribute Grammars (Attributgrammatiken), SDDs

Formalismus zur Einbettung der semantischen in die syntaktische Analyse

Anreicherung des ASTs durch “semantische” Attribute

in der Praxis: oft auch Seiteneffekte

50

Jenseits von Syntax

Semantische Analyse

Page 61: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

51

2

Attribute Grammars

Produktion Semantische Aktion

!E" ::= !int" E.val= int.val| !E1" ‘+’ !E2" E.val= E1.val+E2.val| ‘(’ !E1" ‘)’ E.val= E1.val

Beispiele

Page 62: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

51

2

Attribute Grammars

Produktion Semantische Aktion

!E" ::= !int" E.val= int.val| !E1" ‘+’ !E2" E.val= E1.val+E2.val| ‘(’ !E1" ‘)’ E.val= E1.val

Beispiele

3

Prof. Aiken CS 143 Lecture 6 !"

!"#$%&'$()*+$&,(-%../(012+$/3

# $%&'()*+,-.*,/+0110+2,! (&- 3,4,2,5,3,2,6,2,

# 7&),-.*,'-+(&/8,6,49,6,"5

# 7:-*+,;*<(=0;,0&0;>'(',40,;('-,%:,-%?*&'5(&-8 @6A @4@ (&-9 @6A (&-" @5A

# BC+(&/,D0+'(&/,E*,FC(;),0,D0+'*,-+**,G

Prof. Aiken CS 143 Lecture 6 !H

4,&567.(28(9&%#.(-%..

2

2 2

4 2 5

6

2 6

(&-8

(&-9

2

(&-"

# I+0=*',-.*,%D*+0-(%&,%:,-.*,D0+'*+

# B%*',=0D-C+*,-.*,&*'-(&/,'-+C=-C+*

# JC-,-%%,1C=.,(&:%K L0+*&-.*'*'K M(&/;*N'C==*''%+,

&%)*'

Prof. Aiken CS 143 Lecture 6 !8

4,&567.(28(!"#$%&'$()*+$&,(-%..

# 7;'%,=0D-C+*',-.*,&*'-(&/,'-+C=-C+*

# JC-,0F'-+0=-' :+%1,-.*,=%&=+*-*,'>&-0<OP,1%+*,=%1D0=-,0&),*0'(*+,-%,C'*

# 7&,(1D%+-0&-,)0-0,'-+C=-C+*,(&,0,=%1D(;*+

PLUS

PLUS

25 3

Prof. Aiken CS 143 Lecture 6 !Q

).5&+$:'(!'$:2+#

# I.(',(',E.0-,E*A;;,C'*,-%,=%&'-+C=-,7MI'

# 20=.,/+0110+,'>1F%;,10>,.0R*,0--+(FC-*'K S%+,-*+1(&0;,'>1F%;',4;*<(=0;,-%?*&'5,0--+(FC-*',=0&,F*,=0;=C;0-*),F>,-.*,;*<*+

# 20=.,D+%)C=-(%&,10>,.0R*,0&,0=-(%&K T+(--*&,0'U,,,, V,! W! G W& X,0=-(%&,Y

K I.0-,=0&,+*:*+,-%,%+,=%1DC-*,'>1F%;,0--+(FC-*'

Prof. Aiken CS 143 Lecture 6 !Z

).5&+$:'(!'$:2+#;(!+(4,&567.

# $%&'()*+,-.*,/+0110+2,! (&- 3,2,6,2,3,4,2,5

# S%+,*0=.,'>1F%;,V )*:(&*,0&,0--+(FC-*,V[R0;K S%+,-*+1(&0;'\,R0; (',-.*,0''%=(0-*),;*<*1*K S%+,&%&N-*+1(&0;'\,R0; (',-.*,*<D+*''(%&A',R0;C*,40&),(',

=%1DC-*),:+%1,R0;C*',%:,'CF*<D+*''(%&'5

# T*,0&&%-0-*,-.*,/+0110+,E(-.,0=-(%&'U2,! (&- X,2[R0; O,(&-[R0; Y

3,2! 6,29 X,2[R0; O,2![R0;,6,29[R0;,Y3,4,2! 5,,,,,,,,,,,,,,,X,2[R0; O,2![R0;,Y

Prof. Aiken CS 143 Lecture 6 !]

).5&+$:'(!'$:2+#;(!+(4,&567.(012+$/3

L+%)C=-(%&',,,,,,,,,,,,,,,,,2^C0-(%&'2,,! 2! 6,29,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2[R0; O,2![R0;,6,29[R0;

2! ! (&-8 2![R0;,O,(&-8[R0;,,O,8

29 ! 4,2"5,,,,,,,,,,,,,,,,,,,,,,,,29[R0;,O,2"[R0;

2" ! 2H 6,28 2"[R0;,O,2H[R0;,6,28[R0;

2H ! (&-9 2H[R0;,O,(&-9[R0;,O,9

28 ! (&-" 28[R0;,O,(&-"[R0;,,O,"

# M-+(&/U,,,,8,6,49,6,"5

# I%?*&'U,,,(&-8 @6A @4@ (&-9 @6A (&-" @5A

Page 63: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

51

2

Attribute Grammars

Produktion Semantische Aktion

!E" ::= !int" E.val= int.val| !E1" ‘+’ !E2" E.val= E1.val+E2.val| ‘(’ !E1" ‘)’ E.val= E1.val

Beispiele

3

Prof. Aiken CS 143 Lecture 6 !"

!"#$%&'$()*+$&,(-%../(012+$/3

# $%&'()*+,-.*,/+0110+2,! (&- 3,4,2,5,3,2,6,2,

# 7&),-.*,'-+(&/8,6,49,6,"5

# 7:-*+,;*<(=0;,0&0;>'(',40,;('-,%:,-%?*&'5(&-8 @6A @4@ (&-9 @6A (&-" @5A

# BC+(&/,D0+'(&/,E*,FC(;),0,D0+'*,-+**,G

Prof. Aiken CS 143 Lecture 6 !H

4,&567.(28(9&%#.(-%..

2

2 2

4 2 5

6

2 6

(&-8

(&-9

2

(&-"

# I+0=*',-.*,%D*+0-(%&,%:,-.*,D0+'*+

# B%*',=0D-C+*,-.*,&*'-(&/,'-+C=-C+*

# JC-,-%%,1C=.,(&:%K L0+*&-.*'*'K M(&/;*N'C==*''%+,

&%)*'

Prof. Aiken CS 143 Lecture 6 !8

4,&567.(28(!"#$%&'$()*+$&,(-%..

# 7;'%,=0D-C+*',-.*,&*'-(&/,'-+C=-C+*

# JC-,0F'-+0=-' :+%1,-.*,=%&=+*-*,'>&-0<OP,1%+*,=%1D0=-,0&),*0'(*+,-%,C'*

# 7&,(1D%+-0&-,)0-0,'-+C=-C+*,(&,0,=%1D(;*+

PLUS

PLUS

25 3

Prof. Aiken CS 143 Lecture 6 !Q

).5&+$:'(!'$:2+#

# I.(',(',E.0-,E*A;;,C'*,-%,=%&'-+C=-,7MI'

# 20=.,/+0110+,'>1F%;,10>,.0R*,0--+(FC-*'K S%+,-*+1(&0;,'>1F%;',4;*<(=0;,-%?*&'5,0--+(FC-*',=0&,F*,=0;=C;0-*),F>,-.*,;*<*+

# 20=.,D+%)C=-(%&,10>,.0R*,0&,0=-(%&K T+(--*&,0'U,,,, V,! W! G W& X,0=-(%&,Y

K I.0-,=0&,+*:*+,-%,%+,=%1DC-*,'>1F%;,0--+(FC-*'

Prof. Aiken CS 143 Lecture 6 !Z

).5&+$:'(!'$:2+#;(!+(4,&567.

# $%&'()*+,-.*,/+0110+2,! (&- 3,2,6,2,3,4,2,5

# S%+,*0=.,'>1F%;,V )*:(&*,0&,0--+(FC-*,V[R0;K S%+,-*+1(&0;'\,R0; (',-.*,0''%=(0-*),;*<*1*K S%+,&%&N-*+1(&0;'\,R0; (',-.*,*<D+*''(%&A',R0;C*,40&),(',

=%1DC-*),:+%1,R0;C*',%:,'CF*<D+*''(%&'5

# T*,0&&%-0-*,-.*,/+0110+,E(-.,0=-(%&'U2,! (&- X,2[R0; O,(&-[R0; Y

3,2! 6,29 X,2[R0; O,2![R0;,6,29[R0;,Y3,4,2! 5,,,,,,,,,,,,,,,X,2[R0; O,2![R0;,Y

Prof. Aiken CS 143 Lecture 6 !]

).5&+$:'(!'$:2+#;(!+(4,&567.(012+$/3

L+%)C=-(%&',,,,,,,,,,,,,,,,,2^C0-(%&'2,,! 2! 6,29,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2[R0; O,2![R0;,6,29[R0;

2! ! (&-8 2![R0;,O,(&-8[R0;,,O,8

29 ! 4,2"5,,,,,,,,,,,,,,,,,,,,,,,,29[R0;,O,2"[R0;

2" ! 2H 6,28 2"[R0;,O,2H[R0;,6,28[R0;

2H ! (&-9 2H[R0;,O,(&-9[R0;,O,9

28 ! (&-" 28[R0;,O,(&-"[R0;,,O,"

# M-+(&/U,,,,8,6,49,6,"5

# I%?*&'U,,,(&-8 @6A @4@ (&-9 @6A (&-" @5A

3

Prof. Aiken CS 143 Lecture 6 !"

!"#$%&'$()*+$&,(-%../(012+$/3

# $%&'()*+,-.*,/+0110+2,! (&- 3,4,2,5,3,2,6,2,

# 7&),-.*,'-+(&/8,6,49,6,"5

# 7:-*+,;*<(=0;,0&0;>'(',40,;('-,%:,-%?*&'5(&-8 @6A @4@ (&-9 @6A (&-" @5A

# BC+(&/,D0+'(&/,E*,FC(;),0,D0+'*,-+**,G

Prof. Aiken CS 143 Lecture 6 !H

4,&567.(28(9&%#.(-%..

2

2 2

4 2 5

6

2 6

(&-8

(&-9

2

(&-"

# I+0=*',-.*,%D*+0-(%&,%:,-.*,D0+'*+

# B%*',=0D-C+*,-.*,&*'-(&/,'-+C=-C+*

# JC-,-%%,1C=.,(&:%K L0+*&-.*'*'K M(&/;*N'C==*''%+,

&%)*'

Prof. Aiken CS 143 Lecture 6 !8

4,&567.(28(!"#$%&'$()*+$&,(-%..

# 7;'%,=0D-C+*',-.*,&*'-(&/,'-+C=-C+*

# JC-,0F'-+0=-' :+%1,-.*,=%&=+*-*,'>&-0<OP,1%+*,=%1D0=-,0&),*0'(*+,-%,C'*

# 7&,(1D%+-0&-,)0-0,'-+C=-C+*,(&,0,=%1D(;*+

PLUS

PLUS

25 3

Prof. Aiken CS 143 Lecture 6 !Q

).5&+$:'(!'$:2+#

# I.(',(',E.0-,E*A;;,C'*,-%,=%&'-+C=-,7MI'

# 20=.,/+0110+,'>1F%;,10>,.0R*,0--+(FC-*'K S%+,-*+1(&0;,'>1F%;',4;*<(=0;,-%?*&'5,0--+(FC-*',=0&,F*,=0;=C;0-*),F>,-.*,;*<*+

# 20=.,D+%)C=-(%&,10>,.0R*,0&,0=-(%&K T+(--*&,0'U,,,, V,! W! G W& X,0=-(%&,Y

K I.0-,=0&,+*:*+,-%,%+,=%1DC-*,'>1F%;,0--+(FC-*'

Prof. Aiken CS 143 Lecture 6 !Z

).5&+$:'(!'$:2+#;(!+(4,&567.

# $%&'()*+,-.*,/+0110+2,! (&- 3,2,6,2,3,4,2,5

# S%+,*0=.,'>1F%;,V )*:(&*,0&,0--+(FC-*,V[R0;K S%+,-*+1(&0;'\,R0; (',-.*,0''%=(0-*),;*<*1*K S%+,&%&N-*+1(&0;'\,R0; (',-.*,*<D+*''(%&A',R0;C*,40&),(',

=%1DC-*),:+%1,R0;C*',%:,'CF*<D+*''(%&'5

# T*,0&&%-0-*,-.*,/+0110+,E(-.,0=-(%&'U2,! (&- X,2[R0; O,(&-[R0; Y

3,2! 6,29 X,2[R0; O,2![R0;,6,29[R0;,Y3,4,2! 5,,,,,,,,,,,,,,,X,2[R0; O,2![R0;,Y

Prof. Aiken CS 143 Lecture 6 !]

).5&+$:'(!'$:2+#;(!+(4,&567.(012+$/3

L+%)C=-(%&',,,,,,,,,,,,,,,,,2^C0-(%&'2,,! 2! 6,29,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2[R0; O,2![R0;,6,29[R0;

2! ! (&-8 2![R0;,O,(&-8[R0;,,O,8

29 ! 4,2"5,,,,,,,,,,,,,,,,,,,,,,,,29[R0;,O,2"[R0;

2" ! 2H 6,28 2"[R0;,O,2H[R0;,6,28[R0;

2H ! (&-9 2H[R0;,O,(&-9[R0;,O,9

28 ! (&-" 28[R0;,O,(&-"[R0;,,O,"

# M-+(&/U,,,,8,6,49,6,"5

# I%?*&'U,,,(&-8 @6A @4@ (&-9 @6A (&-" @5A

Page 64: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

52

4

Prof. Aiken CS 143 Lecture 6 !"

!"#$%&'()*(&'+%,-).+&",

# $%&'()*+,'+)*-(.,./%+*01,',.1.)%&,-0,%23')*-(.4 567%6,-0,6%.-83)*-(,*.,(-),./%+*0*%7

# 9:'&/8%;9<=>'8,?,9@=>'8,A,9B=>'8

4 C3.),+-&/3)% 9@=>'8 '(7,9B=>'8 D%0-6%,9<=>'84 E%,.'1,)F') 9<=>'8 7%/%(7.,-(,9@=>'8 '(7,9B=>'8

# GF%,/'6.%6,&3.),0*(7,)F%,-67%6,-0,%>'83')*-(

Prof. Aiken CS 143 Lecture 6 HI

/"0"%1"%(2)34$05

9

9! 9H

J 9< K

A

9@A

*()B

*()H

9B

*()<

+

+

2

5

# 9'+F,(-7%,8'D%8%7,9F'.,-(%,.8-),0-6,)F%,>'8'))6*D3)%

# L-)%,)F%,7%/%(7%(+*%.

3

Prof. Aiken CS 143 Lecture 6 H!

67$89$&'%:)*&&4';9&",

# M(,'))6*D3)%,&3.),D%,+-&/3)%7,'0)%6,'88,*).,.3++%..-6.,*(,)F%,7%/%(7%(+1,N6'/F,F'>%,D%%(,+-&/3)%7,4 O(,/6%>*-3.,%:'&/8%,'))6*D3)%.,+'(,D%,+-&/3)%7,D-))-&P3/

# $3+F,'(,-67%6,%:*.).,QF%(,)F%6%,'6%,(-,+1+8%.4 R1+8*+'881,7%0*(%7,'))6*D3)%.,'6%,(-),8%N'8

Prof. Aiken CS 143 Lecture 6 HH

/"0"%1"%(2)34$05

9

9! 9H

J 9< K

A

9@A

*()B

*()H

9B

*()<

10

5

5 5

32

2

5

3

Prof. Aiken CS 143 Lecture 6 H<

!"#$%&'()*(&'+%,-).+&",)<=+%&>?

# $1()F%.*S%7 '))6*D3)%.4 R'8+38')%7,06-&,'))6*D3)%.,-0,7%.+%(7%().,*(,)F%,/'6.%,)6%%

4 9=>'8 *.,',.1()F%.*S%7,'))6*D3)%

4 R'(,'8Q'1.,D%,+'8+38')%7,*(,',D-))-&P3/,-67%6

# T6'&&'6.,Q*)F,-(81,.1()F%.*S%7,'))6*D3)%.,'6%,+'88%7,$P'))6*D3)%7 N6'&&'6.4 C-.),+-&&-(,+'.%

Prof. Aiken CS 143 Lecture 6 H@

@%5"4'&"1)*&&4';9&",

# M(-)F%6,U*(7,-0,'))6*D3)%

# R'8+38')%7,06-&,'))6*D3)%.,-0,/'6%(),'(7V-6,.*D8*(N.,*(,)F%,/'6.%,)6%%

# 9:'&/8%;,',8*(%,+'8+38')-6

Page 65: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

52

4

Prof. Aiken CS 143 Lecture 6 !"

!"#$%&'()*(&'+%,-).+&",

# $%&'()*+,'+)*-(.,./%+*01,',.1.)%&,-0,%23')*-(.4 567%6,-0,6%.-83)*-(,*.,(-),./%+*0*%7

# 9:'&/8%;9<=>'8,?,9@=>'8,A,9B=>'8

4 C3.),+-&/3)% 9@=>'8 '(7,9B=>'8 D%0-6%,9<=>'84 E%,.'1,)F') 9<=>'8 7%/%(7.,-(,9@=>'8 '(7,9B=>'8

# GF%,/'6.%6,&3.),0*(7,)F%,-67%6,-0,%>'83')*-(

Prof. Aiken CS 143 Lecture 6 HI

/"0"%1"%(2)34$05

9

9! 9H

J 9< K

A

9@A

*()B

*()H

9B

*()<

+

+

2

5

# 9'+F,(-7%,8'D%8%7,9F'.,-(%,.8-),0-6,)F%,>'8'))6*D3)%

# L-)%,)F%,7%/%(7%(+*%.

3

Prof. Aiken CS 143 Lecture 6 H!

67$89$&'%:)*&&4';9&",

# M(,'))6*D3)%,&3.),D%,+-&/3)%7,'0)%6,'88,*).,.3++%..-6.,*(,)F%,7%/%(7%(+1,N6'/F,F'>%,D%%(,+-&/3)%7,4 O(,/6%>*-3.,%:'&/8%,'))6*D3)%.,+'(,D%,+-&/3)%7,D-))-&P3/

# $3+F,'(,-67%6,%:*.).,QF%(,)F%6%,'6%,(-,+1+8%.4 R1+8*+'881,7%0*(%7,'))6*D3)%.,'6%,(-),8%N'8

Prof. Aiken CS 143 Lecture 6 HH

/"0"%1"%(2)34$05

9

9! 9H

J 9< K

A

9@A

*()B

*()H

9B

*()<

10

5

5 5

32

2

5

3

Prof. Aiken CS 143 Lecture 6 H<

!"#$%&'()*(&'+%,-).+&",)<=+%&>?

# $1()F%.*S%7 '))6*D3)%.4 R'8+38')%7,06-&,'))6*D3)%.,-0,7%.+%(7%().,*(,)F%,/'6.%,)6%%

4 9=>'8 *.,',.1()F%.*S%7,'))6*D3)%

4 R'(,'8Q'1.,D%,+'8+38')%7,*(,',D-))-&P3/,-67%6

# T6'&&'6.,Q*)F,-(81,.1()F%.*S%7,'))6*D3)%.,'6%,+'88%7,$P'))6*D3)%7 N6'&&'6.4 C-.),+-&&-(,+'.%

Prof. Aiken CS 143 Lecture 6 H@

@%5"4'&"1)*&&4';9&",

# M(-)F%6,U*(7,-0,'))6*D3)%

# R'8+38')%7,06-&,'))6*D3)%.,-0,/'6%(),'(7V-6,.*D8*(N.,*(,)F%,/'6.%,)6%%

# 9:'&/8%;,',8*(%,+'8+38')-6

4

Prof. Aiken CS 143 Lecture 6 !"

!"#$%&'()*(&'+%,-).+&",

# $%&'()*+,'+)*-(.,./%+*01,',.1.)%&,-0,%23')*-(.4 567%6,-0,6%.-83)*-(,*.,(-),./%+*0*%7

# 9:'&/8%;9<=>'8,?,9@=>'8,A,9B=>'8

4 C3.),+-&/3)% 9@=>'8 '(7,9B=>'8 D%0-6%,9<=>'84 E%,.'1,)F') 9<=>'8 7%/%(7.,-(,9@=>'8 '(7,9B=>'8

# GF%,/'6.%6,&3.),0*(7,)F%,-67%6,-0,%>'83')*-(

Prof. Aiken CS 143 Lecture 6 HI

/"0"%1"%(2)34$05

9

9! 9H

J 9< K

A

9@A

*()B

*()H

9B

*()<

+

+

2

5

# 9'+F,(-7%,8'D%8%7,9F'.,-(%,.8-),0-6,)F%,>'8'))6*D3)%

# L-)%,)F%,7%/%(7%(+*%.

3

Prof. Aiken CS 143 Lecture 6 H!

67$89$&'%:)*&&4';9&",

# M(,'))6*D3)%,&3.),D%,+-&/3)%7,'0)%6,'88,*).,.3++%..-6.,*(,)F%,7%/%(7%(+1,N6'/F,F'>%,D%%(,+-&/3)%7,4 O(,/6%>*-3.,%:'&/8%,'))6*D3)%.,+'(,D%,+-&/3)%7,D-))-&P3/

# $3+F,'(,-67%6,%:*.).,QF%(,)F%6%,'6%,(-,+1+8%.4 R1+8*+'881,7%0*(%7,'))6*D3)%.,'6%,(-),8%N'8

Prof. Aiken CS 143 Lecture 6 HH

/"0"%1"%(2)34$05

9

9! 9H

J 9< K

A

9@A

*()B

*()H

9B

*()<

10

5

5 5

32

2

5

3

Prof. Aiken CS 143 Lecture 6 H<

!"#$%&'()*(&'+%,-).+&",)<=+%&>?

# $1()F%.*S%7 '))6*D3)%.4 R'8+38')%7,06-&,'))6*D3)%.,-0,7%.+%(7%().,*(,)F%,/'6.%,)6%%

4 9=>'8 *.,',.1()F%.*S%7,'))6*D3)%

4 R'(,'8Q'1.,D%,+'8+38')%7,*(,',D-))-&P3/,-67%6

# T6'&&'6.,Q*)F,-(81,.1()F%.*S%7,'))6*D3)%.,'6%,+'88%7,$P'))6*D3)%7 N6'&&'6.4 C-.),+-&&-(,+'.%

Prof. Aiken CS 143 Lecture 6 H@

@%5"4'&"1)*&&4';9&",

# M(-)F%6,U*(7,-0,'))6*D3)%

# R'8+38')%7,06-&,'))6*D3)%.,-0,/'6%(),'(7V-6,.*D8*(N.,*(,)F%,/'6.%,)6%%

# 9:'&/8%;,',8*(%,+'8+38')-6

Page 66: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Jenseits von Syntax

Attribute GrammarsAttribute grammar :=

kontextfreie Grammatik mit Attributen und Regeln

Attribute zu Symbolen, Regeln zu Produktionen

S.a bezeichnet das Attribut ‘a’ des Symbols ‘S’

Synthetisiertes Attribut (“Rückgabewerte) a von S

definiert nur unter Verwendung von Attributen von S und Kinder von S

Vererbtes Attribut (“Parameter”) b von S

definiert nur unter Verwendung von Attributen von S, des Vaters von S und der Geschwister von S

53

Page 67: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Jenseits von Syntax

Attribute GrammarsErgebnis: Gleichungssystem

Auswertungsordnung ist nicht fixiert

e.g., E3.val = E4.val + E5.val

E4.val und E5.val nötig um E3.val zu berechnen (dependency)

aber: ob erst E4.val oder E5.val berechnet wird ist offen

Parser muß Auswertungsordnung festlegen

Problem: zyklische Abhängigkeiten

EXPTIME: für eine gegebene Grammatik feststellen, ob Abhängigkeiten für alle Parsebäume zyklenfrei sind.

daher: Einschränkung von Attribute Grammars

54

Page 68: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Jenseits von Syntax

Attribute GrammarsS-attributed attribute grammar

entählt ausschließlich synthetisierte Attribute

L-attributed attribute grammar: alle Attribute entweder

synthetisiert oder

vererbt, aber dann, für Regel A ::= X1 X2 … Xn

Berechnung von Xi.a nur durch

vererbte Attribute von A oder

(synthetisierte oder vererbte) Attribute von Xj fuer j < i oder

(synthetisierte oder vererbte) Attribute von Xi selbst falls nicht abhängig von a

verwendet vor allem in Recursive Descent Parsern wie ANTLR

55

Page 69: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

56

2

Attribute Grammars

Produktion Semantische Aktion

!E" ::= !int" E.val= int.val| !E"1 ‘+’ !E"2 E.val= E1.val+E2.val| ‘(’ !E"1 ‘)’ E.val= E1.val

!bnumeral" ::= !bdigits"1 ‘.’ !bdigits"2

!bnumeral.val= bdigits1.val+ bdigits2.val

2bdigits2 .len

"

!bdigits" ::= !bdigits"1 !bit"#bdigits.val= 2 ·bdigits2.val+bit.val

$#bdigits.len= bdigits2.len+1

$

| !bit"#bdigits.val= bit.val;bdigits.len= 1

$

!bit" ::= ‘0’#bit.val= 0

$

| ‘1’#bit.val= 1

$

Beispiele

Page 70: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

56

2

Attribute Grammars

Produktion Semantische Aktion

!E" ::= !int" E.val= int.val| !E"1 ‘+’ !E"2 E.val= E1.val+E2.val| ‘(’ !E"1 ‘)’ E.val= E1.val

!bnumeral" ::= !bdigits"1 ‘.’ !bdigits"2

!bnumeral.val= bdigits1.val+ bdigits2.val

2bdigits2 .len

"

!bdigits" ::= !bdigits"1 !bit"#bdigits.val= 2 ·bdigits2.val+bit.val

$#bdigits.len= bdigits2.len+1

$

| !bit"#bdigits.val= bit.val;bdigits.len= 1

$

!bit" ::= ‘0’#bit.val= 0

$

| ‘1’#bit.val= 1

$

Beispiele

68 CHAPTER 3 ATTRIBUTE GRAMMARS

<bit> ::=

0Val (<bit>) ! 0

| 1Val (<bit>) ! 1

The derivation tree in Figure 3.7 illustrates the use of attributes that give thesemantics for the binary numeral 1101.01 to be the real number 13.25.

<binary numeral>Val: 13 + 1/22 = 13.25

<binary digits>Val : 13Len : 4

<binary digits>Val : 1 Len : 2

<binary digits>Val : 6 Len : 3

<binary digits>Val : 3 Len : 2

<binary digits>Val : 1 Len : 1

<bit>Val : 1

<binary digits>Val : 0 Len : 1

<bit>Val : 1

<bit>Val : 0

<bit>Val : 1

<bit>Val : 1

<bit>Val : 0

1

1

1 1

0 0

Figure 3.7: Binary Numeral Semantics Using Synthesized Attributes

Page 71: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

57

FazitD

Page 72: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Zusammenfassung Parsergeneratoren

1. Implementierung von Endlichen Automaten

loop-and-switch, loop-and-lookup, Lexer, Automatenbibliotheken

manuelle Implementierung oft in Bibliotheken und bei zeitkritischem Parsing (Basispaarsequenzen) verwendet

Lexer erlauben auch komplexe endliche Automaten

ohne signifikanten Effizienzverlust

Automatenbibliotheken

ineffizienter als Lexer oder manuelle Implementierung

aber: Konstruktion und Manipulation der Automaten zur Laufzeit möglich

58

Page 73: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Zusammenfassung Parsergeneratoren

2. Implementierung von Kellerautomaten

Parsergeneratoren

manuelle Implementierung meist zu aufwendig

Parsergeneratoren erzeugen Lexer und Parser

Mehr als kontextfreie Sprachen dank semantischer Aktionen

kontext-sensitive Eigenschaften “von Hand” programmieren

Recursive-descent oder LL(k)/LL(*) Parser wie ANTLR

einfach zu lesender Code, leichte manuelle Anpassung

Andere verbreitete Ansätze: LR, LALR, Left-Corner, Earley

59

Page 74: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

Zusammenfassung Parsergeneratoren

Beispielprogramme + Dokumentation

im Laufe der Woche auf der Webseite

Mehr Details zu Attributgrammatiken in den Übungen

Kapitel 5, Drachenbuch (“Compilers …”, Aho et al., 2007)

Selber ausprobieren!

60

Page 75: Von Automaten zu Programmen–Parsergeneratoren und Attributgrammatiken

61

FragenE