Programmieren in Java

Ähnliche Dokumente
Syntaxanalyse Ausgangspunkt und Ziel

Alphabet, formale Sprache

Einstieg in die Informatik mit Java

1 Polymorphie (Vielgestaltigkeit)

Programmentwicklung ohne BlueJ

Java I Vorlesung 6 Referenz-Datentypen

Äquivalente Grammatiken / attributierte Grammatik

2.5 Listen. Kurzschreibweise: [42; 0; 16] Listen werden mithilfe von [] und :: konstruiert.

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Einführung in die Programmierung

Kapitel 5: Syntax-Analyse

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 14/15. Kapitel 11. Fehler und Ausnahmen 1

Objects First With Java A Practical Introduction Using BlueJ. Mehr über Vererbung. Exploring polymorphism 1.0

368 4 Algorithmen und Datenstrukturen

Einführung in die Informatik Grammars & Parsers

Objektorientierte Programmierung

Übung 1 mit C# 6.0 MATTHIAS RONCORONI

Grammatiken und ANTLR

Exercise (Part II) Anastasia Mochalova, Lehrstuhl für ABWL und Wirtschaftsinformatik, Kath. Universität Eichstätt-Ingolstadt 1

1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen. I.2. I.2. Grundlagen von von Programmiersprachen.

Spec# Einführung. Formale Software-Entwicklung Seminar SS 07 Universität Karlsruhe Hilal Akbaba

Programmierung 2. Übersetzer: Das Frontend. Sebastian Hack. Klaas Boesche. Sommersemester

Allgemeine Informatik 2 im SS 2007 Programmierprojekt

Java für Anfänger Teil 2: Java-Syntax. Programmierkurs Manfred Jackel

public class SternchenRechteckGefuellt {

Definition von domänenspezifischen Sprachen mit Xtext: Einführung. 19. November 2014

Vererbung & Schnittstellen in C#

Objektorientierte Programmierung. Kapitel 3: Syntaxdiagramme und Grammatikregeln

Bäume. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 10: Collections 4. Inhalt. Bäume. Einführung. Bäume.

Objektorientierte Programmierung

Probeklausur: Programmierung WS04/05

Formale Sprachen, reguläre und kontextfreie Grammatiken

1 Syntax von Programmiersprachen

Fachseminar Compilerbau

Kapitel 2. Methoden zur Beschreibung von Syntax

Höhere Programmierkonzepte Testklausur

Algorithmen und Datenstrukturen

Programmieren I + II Regeln der Code-Formatierung

7. Schnittstellen Grundlagen zu Schnittstellen. 7. Schnittstellen

Große Übung Praktische Informatik 1

Informatik II. /* c) Baumstruktur in einen String schreiben und zurueckgeben */ public String tostring() {

Begriffe (Wiederholung)

Programmieren in Java

Javakurs 2013 Objektorientierung

Gebundene Typparameter

6 Kontextfreie Grammatiken

Java: Vererbung. Teil 3: super()

Objektorientierte Programmierung

Programmieren von Webinformationssystemen

Einführung in die Programmierung 1

1. Zeilenendkommentare: // geklammerte Kommentare: /*... */ 3. Dokumentationskommentare: /**... */

Programmiersprache 1 (C++) Prof. Dr. Stefan Enderle NTA Isny

Java für Anfänger Teil 2: Java-Syntax. Programmierkurs Manfred Jackel

3 Objektorientierte Konzepte in Java

Java Einführung Abstrakte Klassen und Interfaces

SWE1 / Übung 2 ( )

Programmierung WS12/13 Lösung - Übung 1 M. Brockschmidt, F. Emmes, C. Otto, T. Ströder

Praktikum Funktionale Programmierung Teil 1: Lexen und Parsen

Einführung in Javadoc

Klassendefinitionen verstehen

JAVA - Methoden - Rekursion

Javakurs zu Informatik I. Henning Heitkötter

Klassen mit Instanzmethoden

3 Objektorientierte Konzepte in Java

Reguläre Ausdrücke. Felix Döring, Felix Wittwer 14. November Python-Kurs

Methoden (fortgeschritten) in C# - 1

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Struktur des MicroJava- Compilers

Problemstellung. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 24: Reflection 1. IDE und automatische Tests.

Einführung in die Informatik

5 Grundlagen der Java-Syntax

Übungsblatt 3: Algorithmen in Java & Grammatiken

Probeklausur: Programmierung WS04/05

9 Türme von Hanoi Bewege Stapel von links nach rechts. In jedem Zug darf genau ein Ring bewegt werden. Es darf nie ein größerer auf einen kleine

Vererbung. Martin Wirsing. Ziele. Vererbung

Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein

Programmieren I. Formale Sprachen. Institut für Angewandte Informatik

Einführung in die Programmierung für Wirtschaftsinformatik

JAVA - Methoden

Effizientes Arbeiten mit dem Emacs. Suchen und Ersetzen.

MB2-ALG, SS15 Seite 1 Hauptklausur, geschrieben am

Inhalt Kapitel 5: Syntax

Hochschule Augsburg, Fakultät für Informatik Name:... Prüfung "Programmieren 1", IN1bac, WS 10/11 Seite 1 von 6

7. Formale Sprachen und Grammatiken

Interfaces und Vererbung

Java Vererbung. Inhalt

Automaten und formale Sprachen. Lösungen zu den Übungsblättern

Algorithmen mit konstantem Platzbedarf: Die Klasse REG

Institut für Programmierung und Reaktive Systeme 25. August Programmier-Labor Übungsblatt. int binarysearch(int[] a, int x),

p^db=`oj===pìééçêíáåñçêã~íáçå=

Kapitel 8. Programmierkurs. Methoden. 8.1 Methoden

Was ist ein Compiler?

Grammatiken in Prolog

Universität Karlsruhe (TH)

Transkript:

Programmieren in Java Vorlesung 07: Parsen Prof. Dr. Peter Thiemann Albert-Ludwigs-Universität Freiburg, Germany SS 2015 Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 1 / 32

Inhalt Vorlesungsüberblick Erinnerung: Ausdrücke Parsen Lexeme und Scanner BNF Eindeutigkeit Recursive Descent Parser Linksrekursion Lookahead Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 2 / 32

Vorlesungsüberblick Vorlesungsüberblick Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 3 / 32

Erinnerung: Ausdrücke Erinnerung Ein arithmetischer Ausdruck hat eine der folgenden Formen: eine Variable Beispiele: x, index eine Konstante (eine ganze Zahl) Beispiele: 0, 51, 42 eine Summe von zwei arithmetischen Ausdrücken Beispiele: 3+4, 17+4, 17+ (2+2) ein Produkt von zwei arithmetischen Ausdrücken Beispiele: 3 4, 2 (17+4), (2 3) 4 Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 4 / 32

Erinnerung: Ausdrücke Erstellen von Ausdrücken Mit Hilfe von Konstruktoren eine Variable Beispiele: new Var( x ), new Var( index ) eine Konstante (eine ganze Zahl) Beispiele: new Const(0), new Const(51), new Const( 42) eine Summe von zwei arithmetischen Ausdrücken Beispiele: new Add(new Const(3), new Const(4)), new Add(new Const(17), new Add(new Const(2), new Const(2)) ein Produkt von zwei arithmetischen Ausdrücken Beispiele: new Product(new Const(3), new Const(4)), new Product(new Product(new Const(2), new Const(3)), new Const(4)) Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 5 / 32

Erinnerung: Ausdrücke Erstellen von Ausdrücken Mit Hilfe von statischen Factory Methoden eine Variable Beispiele: var( x ), var( index ) eine Konstante (eine ganze Zahl) Beispiele: cnst(0), cnst(51), cnst( 42) eine Summe von zwei arithmetischen Ausdrücken Beispiele: add(cnst(3), cnst(4)), add(cnst(17), add(cnst(2), cnst(2)) ein Produkt von zwei arithmetischen Ausdrücken Beispiele: product(cnst(3), cnst(4)), product(product(cnst(2), cnst(3)), cnst(4)) Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 6 / 32

Heute: Erstellen von Ausdrücken durch Parsen D.h. Einlesen von einem String oder aus einer Datei eine Variable Beispiele: parse( x ), parse( index ) eine Konstante (eine ganze Zahl) Beispiele: parse( 0 ), parse( 51 ), cnst( 42) eine Summe von zwei arithmetischen Ausdrücken Beispiele: parse( 3+4 ), parse( 17+(2+2) ) ein Produkt von zwei arithmetischen Ausdrücken Beispiele: parse( 3 4 ), parse( 2 3 4 ) Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 7 / 32

Aufgabenstellung Parsen Gesucht Statische Methode 1 IExpr parse(string input); so dass folgendes gilt: 1. Falls input einen korrekt geformten Ausdruck enthält, so liefert parse (input) ein Objekt von Type IExp, das der Eingabe entspricht. 2. Falls input keinen korrekt geformten Ausdruck enthält, so liefert parse (input) eine Exception als Fehlermeldung. 3. Für alle Objekte e0 ungleich null von Typ IExpr soll gelten, dass e0.equals(parse (e0.tostring())) == true ist. Insbesondere wird keine Exception ausgeloest. Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 8 / 32

Definition von tostring() 1 class Var implements IExpr { 2 public String tostring() { 3 return name; 4 } 5 } 6 class Const implements IExpr { 7 public String tostring() { 8 return value + ; 9 } 10 } 11 class Add implements IExpr { 12 public String tostring() { 13 return ( + left.tostring() + + + right.tostring() + ) ; 14 } 15 } 16 class Product implements IExpr { 17 public String tostring() { 18 return ( + left.tostring() + + right.tostring() + ) ; 19 } 20 } Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 9 / 32

Beispiele für tostring() 1 public void test() { 2 checktostring( x, var( x )); 3 checktostring( 45, cnst(45)); 4 checktostring( (3 + 4), add(cnst(3), cnst(4))); 5 checktostring( (3 4), product(cnst(3), cnst(4))); 6 checktostring( ((2 3) + 4), add(product(cnst(2),cnst(3)), cnst(4))); 7 } 8 9 private void checktostring(string x, IExpr e) { 10 String r = e.tostring(); 11 System.out.println( + r + ); 12 assertequals(x, r); 13 } Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 10 / 32

Beispiele für parse() Umkehrung von tostring() 1 public void testparse() { 2 checkparse( x, var( x )); 3 checkparse( 45, cnst(45)); 4 checkparse( (3 + 4), add(cnst(3), cnst(4))); 5 checkparse( (3 4), product(cnst(3), cnst(4))); 6 checkparse( ((2 3) + 4), add(product(cnst(2),cnst(3)), cnst(4))); 7 } 8 9 private void checkparse(string input, IExpr expected) { 10 IExpr result = parse(input); 11 assertequals(expected, result); 12 } Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 11 / 32

Lexeme und Scanner Lexeme: Bestandteile eines Ausdrucks 1. Variable: String bestehend aus mehr als einem Buchstaben [A Za z]+ 2. Konstante: String bestehend aus mehr als einer Ziffer \\d+ 3. Klammer auf \\( 4. Klammer zu \\) 5. Pluszeichen \\+ 6. Multiplikationszeichen \\ 7. Trennsymbole: Leerzeichen, Tabulatoren, etc (whitespace) Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 12 / 32

Lexeme und Scanner Lexeme: Bestandteile eines Ausdrucks 1. Variable: String bestehend aus mehr als einem Buchstaben [A Za z]+ 2. Konstante: String bestehend aus mehr als einer Ziffer \\d+ 3. Klammer auf 4. Klammer zu 5. Pluszeichen 6. Multiplikationszeichen 7. Trennsymbole: Leerzeichen, Tabulatoren, etc (whitespace) \\( \\) \\+ Lexeme Die Zeichenfolgen nach 1-6 heißen Lexeme. Zwischen zwei Lexemen dürfen beliebig viele Trennsymbole eingefügt werden. Traditionell werden Lexeme durch reguläre Ausdrücke definiert (rechte Spalte). \\ Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 12 / 32

Lexeme und Scanner Scanner: Zerlegen eines Ausdrucks in Lexeme 1 public interface IScanner { 2 / 3 Test if next lexeme in input is matched by regex. 4 @param regex a regular expression 5 @return true if input starts with regex. 6 / 7 boolean lookingat(string regex); 8 / 9 If scanner is looking at regex, return string matched by regex and 10 advance to next lexeme skipping over whitespace. 11 @param regex a regular expression 12 @return matched string if input starts with regex. Otherwise return null. 13 / 14 String getlexeme(string regex); 15 } Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 13 / 32

Lexeme und Scanner StringScanner: Scanner mit Eingabestring Definiere Klasse StringScanner mit Feld String input. 1 public boolean lookingat(string regex) { 2 Matcher m = Pattern.compile(regex).matcher(input); 3 return m.lookingat(); 4 } Pattern java.util.regex.pattern.compile(string regex) Compiles the given regular expression into a pattern. Parameters: regex The expression to be compiled Returns: the given regular expression compiled into a pattern Throws: PatternSyntaxException - If the expression s syntax is invalid Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 14 / 32

Lexeme und Scanner Pattern und Matcher Matcher java.util.regex.pattern.matcher(string input) Creates a matcher that will match the given input against this pattern. Parameters: input The character sequence to be matched Returns: A new matcher for this pattern boolean java.util.regex.matcher.lookingat() Attempts to match the input sequence, starting at the beginning of the region, against the pattern. This method always starts at the beginning of the region. It does not require that the entire region be matched. If the match succeeds then more information can be obtained via the start, end, and group methods. Returns: true if, and only if, a prefix of the input sequence matches this matcher s pattern Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 15 / 32

Lexeme und Scanner StringScanner.getLexeme() 1 public String getlexeme(string regexp) { 2 Matcher m = Pattern.compile(regexp).matcher(input); 3 String r = null; 4 if (m.lookingat()) { 5 r = input.substring(0, m.end()); 6 input = input.substring(m.end()).trim(); 7 } 8 return r; 9 } substring(begin, end) liefert den Substring ab begin bis (exklusive) end end() liefert den Index direkt hinter dem Match trim() entfernt Leerzeichen etc zu Beginn eines Strings Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 16 / 32

Lexeme und Scanner Zwischenstand Scanner Liefert Zerlegung der Eingabe in Folge von Lexemen und entfernt whitespace. Klassifiziert die Lexeme in Token. Beispiele: 42*17+4 42 * 17 + 4 NUM * NUM + NUM (index - 1) * span ( index - 1 ) * span ( VAR - NUM ) * VAR Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 17 / 32

Lexeme und Scanner Zwischenstand Scanner Liefert Zerlegung der Eingabe in Folge von Lexemen und entfernt whitespace. Klassifiziert die Lexeme in Token. Beispiele: 42*17+4 42 * 17 + 4 NUM * NUM + NUM (index - 1) * span ( index - 1 ) * span ( VAR - NUM ) * VAR Parser Rekonstruiert aus einer Tokenfolge einen Ausdruck, falls möglich. Das heisst, der Parser erkennt die Sprache der Ausdrücke. Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 17 / 32

BNF Spezifikation einer Sprache durch BNF Ein arithmetischer Ausdruck hat eine der folgenden Formen: eine Variable eine Konstante (eine ganze Zahl) eine Summe von zwei arithmetischen Ausdrücken ein Produkt von zwei arithmetischen Ausdrücken Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 18 / 32

BNF Spezifikation einer Sprache durch BNF Ein arithmetischer Ausdruck hat eine der folgenden Formen: eine Variable eine Konstante (eine ganze Zahl) eine Summe von zwei arithmetischen Ausdrücken ein Produkt von zwei arithmetischen Ausdrücken Sprachdefinition durch BNF Analog zur Spezifikation von arithmetischen Ausdrücken Expr ::= VAR Variable NUM Konstante Expr + Expr Summe Expr * Expr Produkt ( Expr ) Klammern (neu) Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 18 / 32

BNF BNF (Backus-Normalform) BNF Bestandteile Expr ::= VAR Variable NUM Konstante Expr + Expr Summe Expr * Expr Produkt ( Expr ) Klammern (neu) Variable (Nichtterminalsymbole): Expr, VAR, NUM stehen jeweils für (eine Menge von) Strings VAR und NUM stehen für die entsprechenden Lexeme Terminalsymbole: +, *, (, ) stehen jeweils für sich selbst Metasymbole ::= und definieren Ersetzungsregeln (Produktionen) Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 19 / 32

BNF BNF Ersetzungsregeln Ersetzungsregeln Expr ::= VAR NUM ( Expr ) Expr + Expr Expr * Expr Links von ::= steht eine Variable Rechts von ::= stehen alternative Ersetzungen getrennt durch In jedem Schritt wird eine Variable durch eine ihrer rechten Seiten ersetzt (Ableitungsschritt ) oder durch ein passendes Lexem Beispiele Expr VAR index Expr Expr + Expr VAR + Expr x + Expr x + NUM x + 1 Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 20 / 32

BNF Sprache einer BNF In jeder BNF ist eine Variable das Startsymbol Beispiel Ausdrücke: Expr Zur Sprache einer BNF gehört jeder String, der aus dem Startsymbol abgeleitet werden kann und vollständig aus Terminalsymbolen besteht. Beispiel Ausdrücke: 42, index, x+1, 2*x+1, 2*(x+1) Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 21 / 32

BNF Problemstellung Parsen Gegeben BNF Eingabestring Gesucht Ableitung vom Startsymbol der BNF zum Eingabestring (falls existiert) Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 22 / 32

Eindeutigkeit Darstellung der Ableitung = IExpr-Objekt Expr ::= VAR Variable var(v) NUM Konstante cnst(n) Expr + Expr Summe add(e 1, e 2 ) Expr * Expr Produkt product(e 1, e 2 ) ( Expr ) Klammern (neu) e Jede Produktion entspricht einem IExpr-Konstruktor (Ausnahme: Klammer) Jede vollständige Ableitung entspricht IExpr-Objekt Beispiel: Expr Expr + Expr add(e 1, e 2 ) VAR + Expr add(var(v), e 2 ) x + Expr add(var( x ), e 2 ) x + NUM add(var( x ), cnst(n)) x + 1 add(var( x ), cnst(1)) Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 23 / 32

Eindeutigkeit Problem: Ausdrucks-BNF ist nicht eindeutig Betrachte 1+2*3 Expr Expr + Expr NUM + Expr 1 + Expr 1 + Expr Expr 1 + NUM Expr 1 + 2 Expr 1 + 2 NUM 1 + 2 3 1 + (2 * 3) add(cnst(1), prd(cnst(2), cnst(3))) Expr Expr Expr Expr + Expr Expr NUM + Expr Expr 1 + Expr Expr 1 + NUM Expr 1 + 2 Expr 1 + 2 NUM 1 + 2 3 (1 + 2) * 3 prd(add(cnst(1), cnst(2)), cnst(3)) Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 24 / 32

Eindeutigkeit Lösung: Eindeutige BNF für Ausdrücke Expr ::= Expr + Term Term Term ::= Term Factor Factor Factor ::= VAR NUM ( Expr ) Für diese BNF gibt es zu jedem String höchstens eine Ableitung Punktrechnung vor Strichrechnung ist eingebaut Die Ableitung Expr 1 + 2 3 entspricht 1 + (2 * 3) Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 25 / 32

Recursive Descent Parser BNF Recursive Descent Parser Idee des Parsers Jede Variable N wird durch eine Methode parsen repräsentiert. Die Methode zu Variable N liest aus der Eingabe einen String, der aus N abgeleitet werden kann. Die Definition der Methode ergibt sich aus den Produktionen für N. Anhand des vorliegenden Lexems (Tokens) wird eine Alternative der Produktion ausgewählt. Für die Symbole auf der rechten Seite wird von rechts nach links Code generiert. Für eine Variable N wird parsen aufgerufen. Für ein Terminalsymbol t wird getlexeme(t) aufgerufen. Bemerkung: die Methoden rufen sich gegenseitig rekursiv auf! Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 26 / 32

Recursive Descent Parser Beispiel: Methode für Factor Factor ::= VAR NUM ( Expr ) 1 public IExpr parsefactor() { 2 // <Factor> ::= <VAR> 3 String lexeme = getlexeme(regexp VAR); 4 if (lexeme) { return var(lexeme); } 5 // <Factor> ::= <NUM> 6 lexeme = getlexeme(regexp NUM); 7 if (lexeme) { return cnst(integer.parseint(lexeme)); } 8 // <Factor> ::= ( <Expr> ) 9 lexeme = getlexeme(regexp OPEN PAREN); 10 if (lexeme) { 11 IExpr e = parseexpr(); 12 if (e!= null) { 13 lexeme = getlexeme(regexp CLOSE PAREN); 14 if (lexeme!= null) { 15 return e; 16 } } } 17 throw new IllegalArgumentException( Cannot parse input ); 18 } Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 27 / 32

Recursive Descent Parser Linksrekursion Beispiel (Problem): Methode für Expr Verfahren funktioniert gut für Factor, weil jede Alternative mit einem anderen Lexem beginnt. Bei den anderen Variablen ist das nicht der Fall. Betrachte das Beispiel Expr Expr ::= Expr + Term Term 1 public IExpr parseexpr() { 2 // <Expr> ::= <Expr> + <Term> 3 // not clear how to check for the other production 4 // unfortunately, this production is left recursive: 5 IExpr left = parseexpr(); 6 // oops, this recursive call does not terminate! 7 //... 8 } Um dieses Problem zu vermeiden, muss die BNF ein letztes Mal umstrukturiert werden. Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 28 / 32

Recursive Descent Parser Linksrekursion Elimination von Linksrekursion Die Produktionen für Expr und Term sind linksrekursiv, d.h., die gleiche Variable taucht direkt am Anfang der rechten Seite einer Regel auf. Expr ::= Expr + Term Term Term ::= Term Factor Factor Diese Produktionen können umgeformt werden, so dass sie nicht mehr linksrekursiv sind, aber dass die gleiche Sprache erkannt wird. Dabei steht ε für eine leere rechte Regelseite. Expr ::= Term Expr 1 Expr1 ::= ε + Term Expr1 Term ::= Factor Term1 Term1 ::= ε Factor Term1 Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 29 / 32

Recursive Descent Parser Lookahead Unterscheiden der Alternativen durch Lookahead Expr ::= Term Expr 1 Expr1 ::= ε + Term Expr1 Term ::= Factor Term1 Term1 ::= ε Factor Term1 Factor ::= VAR NUM ( Expr ) Erkennen der Regel-Alternativen durch Lookahead Factor : ok Expr, Term : nur eine Alternative Expr 1 : durch Testen des folgenden Lexems (Lookahead) falls + in der Eingabe, dann zweite Regel falls * oder ) in der Eingabe, dann erste (leere) Regel Term1 : durch Testen des folgenden Lexems (Lookahead) falls * in der Eingabe, dann zweite Regel falls ) in der Eingabe, dann erste (leere) Regel Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 30 / 32

Recursive Descent Parser Lookahead Beispiel: Methode für Term1 1 public IExpr parseterm1(iexpr left) { 2 String lexeme = getlexeme (REGEXP STAR); 3 if (lexeme!= null) { 4 IExpr right = parsefactor(); 5 if (right!= null) { 6 return parseterm1 (product (left, right)); 7 } 8 throw new IllegalArgumentException ( cannot parse Term1 ); 9 } 10 // should test lookahead for nice error message 11 return left; 12 } parseterm1 erhält beim Aufruf den linken Faktor als Argument Dadurch wird * links-assoziativ parseexpr1 wird analog implementiert. Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 31 / 32

Recursive Descent Parser Lookahead Alles zusammen... 1 public class Parser { 2 private IScanner scan; 3 public Parser(IScanner scan) { this.scan = scan; } 4 5 // delegate to scanner 6 private String getlexeme(string re) { return scan.getlexeme(re); } 7 private boolean lookingat(string re) { return scan.lookingat(re); } 8 9 public IExpr parseexpr() { 10 IExpr left = parseterm(); 11 if (left!= null) { return parseexpr1(left); } 12 throw new IllegalArgumentException ( cannot parse expression ); 13 } 14 // further parsen methods... 15 } Peter Thiemann (Univ. Freiburg) Programmieren in Java JAVA 32 / 32