Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Programmierung 1 - Repetitorium WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage:

Ähnliche Präsentationen


Präsentation zum Thema: "Programmierung 1 - Repetitorium WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage:"—  Präsentation transkript:

1 Programmierung 1 - Repetitorium WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage:

2 Programmierung 1 - Repetitorium Dienstag, den Kapitel 12 Syntax

3 Programmierung 1 - Repetitorium 12.1 Übersicht Die Abstrakte Syntax liefert die Baumdarstellung von Phrasen. Die Konkrete Syntax besteht aus der lexikalischen und der phrasalen Syntax. Die Lexikalische Syntax regelt, welche Wörter für die Darstellung von Phrasen zur Verfügung stehen und wie Wörter durch Zeichenreihen darzustellen sind. Die Phrasale Syntax regelt, wie Phrasen durch Wortfolgen dargestellt werden. Eine konkrete Syntax muss eindeutig und durch einen Parser realisierbar sein, der zu einer vorgelegten Zeichenreihe entscheidet, ob es sich um die Darstellung einer Phrase handelt und gegebenenfalls die Baumdarstellung der Phrase liefert.

4 Programmierung 1 - Repetitorium 12.2 Lexikalische Syntax Die lexikalische Syntax klassifiziert die Wörter von F in 1.Symbolische Wörter (+, -, *,, =>) 2.Zahlkonstanten (nichtleere Zeichenreihen aus Ziffern) 3.Alpha-numerische Wörter (alle Wörter aus Buchstaben und Ziffern, die mit einem Buchstaben beginnen) 4.Leerzeichen (, \t, \n) if x<=2 then 1 else 2+y ist die Wortfolge if,x,<=,2,then,1,else,2,+,y Die Trennungsregel besagt, dass zwei Wörter ohne trennendes Leerzeichen direkt hintereinander geschrieben werden dürfen, wenn es kein Wort gibt, das mit dem Zeichen des ersten Wortes und dem ersten Zeichen des zweiten Wortes beginnt. Kommentare (*... *) dürfen nur balanciert auftreten und sind in der Wortdarstellung nicht sichtbar. Symbolische Wörter sind alle nichtleeren Zeichenreihen von ! % & $ # + - / : \ ~ ^ | * Alpha-numerische Wörter dürfen, _ und. enthalten.

5 Programmierung 1 - Repetitorium 12.3 Lexer Ein Lexer ist eine Prozedur, die zu einer vorgelegten Zeichenfolge entscheidet, ob sie lexikalisch zulässig ist, und gegebenenfalls die dargestellte Wortfolge liefert. Der Lexer liest die vorgelegte Zeichenfolge von links nach rechts. Die leere Zeichenfolge ist zulässig. Leerzeichen werden überlesen. Wenn das erste Zeichen kein Leerzeichen ist, muss ein Wort überlesen werden. Zunächst wird geprüft, ob ein symbolisches Wort überlesen werden kann. Wenn kein symbolisches Wort überlesen werden kann, verbleiben für eine zulässige Zeichenfolge nur 3 Möglichkeiten : 1.Die Zeichenfolge beginnt mit ~. In diesem Fall muss eine möglichst lange negative Zahlkonstante überlesen werden. 2.Die Zeichenfolge beginnt mit einer Ziffer. In diesem Fall muss eine möglichst lange einfache Zahlkonstante überlesen werden. 3.Die Zeichenfolge beginnt mit einem Buchstaben. In diesem Fall muss ein möglichst langes alpha-numerisches Wort überlesen werden. Der Lexer liefert die gelesenen Wörter als Werte des Konstruktortyps token.

6 Programmierung 1 - Repetitorium 12.3 Lexer datatype token = ICON of int | ID of string | ADD | SUB | MUL | LPAR | RPAR | LEQ | FALSE | TRUE | IF | THEN | ELSE | FN | COLON | ARROW | DARROW if ~17 <= xy then bool else 1 + liefert [ IF, ICON ~17, LEQ, ID xy, THEN, ID bool, ELSE, ICON 1, ADD ] lex : token list char list token list (*Error,Overflow*) Akkumulator (reversierte Ordnung) noch zu lesende Zeichenfolge lexA : token list char list char list token list Akkumulator bereits gelesene Zeichen noch zu lesenden Zeichen

7 Programmierung 1 - Repetitorium 12.3 Lexer lexN : token list int int char list token list Akkumulator bereits gelesenes Vorzeichen noch zu lesenden Zeichen Zahl der bereits gelesenen Ziffern Dependenzgraph der Prozedur des Lexers : lex lexA lexN

8 Programmierung 1 - Repetitorium 12.3 Lexer val ord0 = ord #0 fun lex ts nil = rev ts | lex ts (# ::cr) = lex ts cr | lex ts (#\n::cr) = lex ts cr | lex ts (#\t::cr) = lex ts cr | lex ts (#<::#=::cr) = lex (LEQ::ts) cr | lex ts (#-::#>::cr) = lex (ARROW::ts) cr | lex ts (#=::#>::cr) = lex (DARROW::ts) cr | lex ts (#+::cr) = lex (ADD::ts) cr | lex ts (#-::cr) = lex (SUB::ts) cr | lex ts (#*::cr) = lex (MUL::ts) cr | lex ts (#:::cr) = lex (COLON::ts) cr | lex ts (#(::cr) = lex (LPAR::ts) cr | lex ts (#)::cr) = lex (RPAR::ts) cr | lex ts (#~::c::cr) = if Char.isDigit c then lexN ts ~1 0 (c::cr) else raise Error |...

9 Programmierung 1 - Repetitorium 12.3 Lexer...| lex ts (c::cr) = if Char.isDigit c then lexN ts 1 0 (c::cr) else if Char.isAlpha c then lexA ts [c] cr else raise Error and lexN ts s n cs = if not (null cs) andalso Char.isDigit(hd cs) then lexN ts s (10*n + (ord(hd cs) – ord 0)) (tl cs) else lex (ICON(s*n)::ts) cs and lexA ts xs cs = if not (null cs) andalso Char.isAlphanum(hd cs) then lexA ts (hd cs::xs) (tl cs) else lex (lexA (implode (rev xs))::ts) cs and lexA if = IF | lexA then = THEN | lexA else = ELSE | lexA fn = FN | lexA false = FALSE | lexA true = TRUE | lexA x = ID x

10 Programmierung 1 - Repetitorium 12.4 Kontextfreie Syntax für Typen ty attybool int ( ) ty = atty | atty tyTyp atty = bool | int | ( ty )atomarer Typ Nonterminal Terminal Eine Grammatik beschreibt eine Menge von Syntaxbäumen. Syntaxbäume sind geordnete Bäume : 1.Jedes Blatt ist mit einem Wort markiert. 2.Die Wurzel und die inneren Knoten sind mit Nonterminalen markiert. 3.Für jeden mit einem Nonterminal markierten Knoten gilt : Wenn N die Marke des Knotens ist und S 1,..., S n die Marken der Nachfolger des Knotens sind, dann spezifiziert die Grammatik für das Nonterminal N die Alternative S 1,..., S n.

11 Programmierung 1 - Repetitorium 12.4 Kontextfreie Syntax für Typen Jeder Syntaxbaum hat also mindestens zwei Knoten. Die Grenze eines Syntaxbaum bezeichnen wir als den durch den Baum dargestellten Satz. ( int int ) int int atty ty atty ty atty ty

12 Programmierung 1 - Repetitorium 12.4 Kontextfreie Syntax für Typen Für die syntaktische Analyse benötigen wir einen Parser, der prüft, ob eine Wortfolge einen Typ darstellt und diesen im Erfolgsfall liefert. Als algorithmische Technik verwenden wir den rekursiven Abstieg mit Ein-Wort-Vorrausschau. Zusammenhang : SatzSyntaxbäume Phrasen eindeutige kontextfreie Grammatik abstrakte Grammatik

13 Programmierung 1 - Repetitorium 12.4 Kontextfreie Syntax für Typen fun match (a,ts) t = if null ts orelse hd ts <> t then raise Error else ( a, tl ts ) fun combine a ts p f = let val (a,tr) = p ts in ( f(a,a), tr ) end fun ty ts = case atty ts of ( a, ARROW :: tr ) => combine a tr ty Arrow | ats => ats and atty (ID int :: ts) = (Int, ts) | atty (ID bool :: ts) = (Bool, ts) | atty (LPAR :: ts) = match (ty ts) RPAR | atty _ => raise Error fun parse ts = case ty ts of ( a, [] ) => a | _ => raise Error val parse : token list ty

14 Programmierung 1 - Repetitorium 12.5 Kontextfreie Syntax für arithmetische Ausdrücke exp asexp mulexp atexp <= + - * ( ) exp = asexp [ <= asexp ] asexp = [ asexp ( + | - ) ] mulexp mulexp = [ mulexp * ] atexp atexp = constant | identifier | ( exp ) constant identifier Bei der Realisierung des Parsers muss die störende Linksrekursion von asexp und mulexp entfernt werden, da diese sonst zur Divergenz führen.

15 Programmierung 1 - Repetitorium 12.5 Kontextfreie Syntax für arithmetische Ausdrücke Zur Behebung des Problems führen wir Hilfsnonterminale ein, welche Epsilon-Blätter im Syntaxbaum darstellen. exp = asexp [ <= asexp ] asexp = mulexp asexp asexp = [ ( + | - ) mulexp asexp ] mulexp = atexp mulexp mulexp = [ * atexp mulexp ] atexp = constant | identifier | ( exp )

16 Programmierung 1 - Repetitorium 12.5 Kontextfreie Syntax für arithmetische Ausdrücke fun match (a,ts) t = if null ts orelse hd ts <> t then raise Error else (a, tl ts) fun combine a ts p f = let val (a,tr) = p ts in (f(a,a), tr) end fun opa ops (a,a) = Op(a,ops,a) fun exp ts = case asexp ts of (a, LEQ::tr) => combine a tr asexp (opa Leq) | ats => ats and asexp ts = asexp (mulexp ts) and asexp(a, ADD::ts) = asexp(combine a ts mulexp (opa Add)) | asexp(a, SUB::ts) = asexp(combine a ts mulexp (opa Sub)) | asexp ats = ats and mulexp ts = mulexp(atexp ts) and mulexp(a, MUL::ts) = mulexp(combine a ts atexp (opa Mul)) | mulexp ats = ats...

17 Programmierung 1 - Repetitorium 12.5 Kontextfreie Syntax für arithmetische Ausdrücke... and atexp (FALSE ::ts) = (Con False, ts) | atexp (TRUE ::ts) = (Con True, ts) | atexp (ICON n::ts) = (Con(IC n), ts) | atexp (ID s ::ts) = (Id s, ts) | atexp (LPAR ::ts) = match (exp ts) RPAR | atexp _ = raise Error fun parse ts = case exp ts of (a, nil) => a | _ => raise Error val parse : token list exp

18 Programmierung 1 - Repetitorium 12.6 Bemerkungen zur konkreten Syntax von SML Die Rangfolge und die Gruppierung der Infixoperatoren für SML Ausdrücke ist wie folgt: rechtsassoziativ : orelse andalso linksassoziativ : before o := = <> = + - ^ * / div mod Dabei ist zu beachten, dass orelse und andalso semantisch gesehen keine Operationen sind, sondern aus Konditionalen abgeleitete Formen sind.


Herunterladen ppt "Programmierung 1 - Repetitorium WS 2002/2003 Programmierung 1 - Repetitorium Andreas Augustin und Marc Wagner Homepage:"

Ähnliche Präsentationen


Google-Anzeigen