Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Programmierung 1 - Repetitorium

Ähnliche Präsentationen


Präsentation zum Thema: "Programmierung 1 - Repetitorium"—  Präsentation transkript:

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

2 Dienstag, den Kapitel 12 Syntax

3 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 12.2 Lexikalische Syntax Die lexikalische Syntax klassifiziert die Wörter von F in Symbolische Wörter (“+“ , “-“ , “*“ , “<=“ , “(“ , “)“ , “:“ , “->“ , “=>“) Zahlkonstanten (nichtleere Zeichenreihen aus Ziffern) 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 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 : Die Zeichenfolge beginnt mit “~“. In diesem Fall muss eine möglichst lange negative Zahlkonstante überlesen werden. Die Zeichenfolge beginnt mit einer Ziffer. In diesem Fall muss eine möglichst lange einfache Zahlkonstante überlesen werden. 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 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 12.3 Lexer lexN : token list → int → int → char list → token list Akkumulator bereits gelesenes Vorzeichen Zahl der bereits gelesenen Ziffern noch zu lesenden Zeichen Dependenzgraph der Prozedur des Lexers : lex lexA lexN lexA‘

8 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 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 12.4 Kontextfreie Syntax für Typen
atty “bool“ “int“ “(“ “)“ ty = atty | atty “→“ ty Typ atty = “bool“ | “int“ | “(“ ty “)“ atomarer Typ Nonterminal Terminal Eine Grammatik beschreibt eine Menge von Syntaxbäumen. Syntaxbäume sind geordnete Bäume : Jedes Blatt ist mit einem Wort markiert. Die Wurzel und die inneren Knoten sind mit Nonterminalen markiert. Für jeden mit einem Nonterminal markierten Knoten gilt : Wenn N die Marke des Knotens ist und S1, ... , Sn die Marken der Nachfolger des Knotens sind, dann spezifiziert die Grammatik für das Nonterminal N die Alternative S1 , ... , Sn.

11 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. ty atty ty ty atty ty atty ty atty atty “(“ “int“ “→“ “int“ “)“ “→“ “int“ “→“ “int“

12 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 : Satz Syntaxbäume eindeutige kontextfreie Grammatik Phrasen abstrakte Grammatik

13 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 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 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 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 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 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"

Ähnliche Präsentationen


Google-Anzeigen