560 likes | 677 Views
Einführung in die Programmierung Prof. Dr. Bertrand Meyer. Lektion 16: Die Syntax beschreiben. Ziele der heutigen Vorlesung. Sprachen, die andere Sprachen beschreiben, kennenlernen Die Syntaxbeschreibung für Eiffel lesen und verstehen können Einfache Syntaxbeschreibungen selbst erstellen.
E N D
Einführung in die ProgrammierungProf. Dr. Bertrand Meyer Lektion 16: Die Syntax beschreiben
Ziele der heutigen Vorlesung Sprachen, die andere Sprachen beschreiben, kennenlernen Die Syntaxbeschreibung für Eiffel lesen und verstehen können Einfache Syntaxbeschreibungen selbst erstellen
Syntax: Konditional Eine Bedingungsinstruktion besteht aus (in dieser Reihenfolge): • Einem „If“-Teil der Form ifBedingung. • Einem „Then“-Teil der Form thenInstruktion. • Null oder mehr „Elseif“-Teile, jeder der FormelseifBedingung thenInstruktion. • Kein oder ein „Else-Teile“ der Form elseInstruktion • Dem Schlüsselwort end. Hierbei ist jede Bedingung ein Boole‘scher Ausdruck, und jede Instruktionist eine Verbunds-Instruktion.
Wieso Syntax formal beschreiben? Wir kennen Syntaxbeschreibungen aus natürlichen Sprachen: • Z.B. Grammatik für Deutsch, Englisch, Französisch,… • Gut genug für den menschlichen Gebrauch • Uneindeutig, wie die natürliche Sprache selbst
Die Macht des menschlichen Gehirns I cdnoult blvelee taht I cluod aulacity uesdnatnrd waht I was rdgnieg. The Paomnnehal Pweor of the Hmuan Mnid Aoccdrnig to a rscheearch at Cmabrigde Uinervtisy, is deosn't mttaer in waht oredr the ltteers in a wrod are, the olny iprmoatnt tihng is taht the frist and lsat ltteer be in the rghit pclae. The rset can be a taotl mses and you can sitll raed it wouthit any porbelm. Tihs is bcuseae the huamn mnid deos not raed ervey lteter by istlef, but the wrod as a wlohe. Ptrety Amzanig Huh?
Compiler brauchen eine strikte formale Definition einer Programmiersprache Wieso Syntax formal beschreiben? Compilerbenutzen Algorithmen, um • Die Gültigkeit des Programmtextes zu überprüfen • Den Programmtext zu analysieren um Elemente für einen abstrakten Syntaxbaum zu extrahieren • Den Programmtext in Maschineninstruktionen zu übersetzen
Formale Beschreibung der Syntax Benutzen Sie eine formale Sprache, um Programmiersprachen zu beschreiben. Sprachen, die andere Sprachen beschreiben, heissen Meta-Sprachen Die Meta-Sprache, die Eiffel beschreibt: BNF-E(Variante der Backus-Naur-Form, BNF)
Geschichte 1954 FORTRAN: Erste weitgehend bekannte Programmiersprache (entwickelt von John Backus et Al.) • 1958 ALGOL 58: Zusammenarbeit von europäischen und amerikanischen Gruppen 1960 ALGOL 60: Die Vorbereitung zeigte den Bedarf einer formalen Beschreibung auf John Backus (ALGOL Team) schlug die Backus-Normal-Form (BNF) vor 1964: Donald Knuth schlug vor, Peter Naur für sein Mitwirken zu ehren Backus-Naur-Form Viele weitere Varianten seither, z.B. die graphische Variante von Niklaus Wirth
Formale Beschreibung einer Sprache Mit BNF kann man syntaktischeEigenschaften einer Sprache beschreiben: • Zulässige Struktur einer Sprache • Ähnlich Grammatiken in normaler Sprache Erinnerung: Die Beschreibung einer Programmiersprache beinhaltet auch lexikalische und semantische Eigenschaften Andere Werkzeuge
(Erinnerung: von Lektion 3) • Semantische Regeln definieren den Effekt eines Programms, das den syntaktischen Regeln genügt • Syntaktische Regeln definieren, wie man Exemplare aus Tokens, die den lexikalischen Regeln genügen, herstellt • Lexikalische Regeln definieren, wie man aus Zeichen Tokens macht Semantische Regeln SyntaktischeRegeln basieren auf StatischeSemantik(Gültigkeitsregel) LexikalischeRegeln
Formale Beschreibung der Syntax Eine Sprache ist eine Menge von Phrasen Eine Phrase ist eine endliche Sequenz von Zeichen (Tokens) eines gewissen „Vokabulars“ Nicht jede mögliche Sequenz ist eine Phrase der Sprache Eine Grammatik spezifiziert, welche Sequenzen Teil der Sprache sind und welche nicht. BNF wird benutzt, um eine Grammatik für eine Programmiersprache zu definieren.
Beispiele von Phrasen class age: INTEGER -- Alter end PERSON feature class PERSON feature age: INTEGER -- Alter end
Grammatik • Definition • Eine Grammatik für eine Sprache ist eine endliche Menge von Regeln zum Erstellen von (Token) Sequenzen, so dass gilt: • Jede Sequenz, die man durch endlich häufiges Anwenden von Regeln der Grammatik erhält, ist eine Phrase der Sprache • Jede Phrase der Sprache kann durch eine endliche Anzahl von Anwendungen der Grammatik-Regeln erzeugt werden
Elemente von Grammatiken: Terminale Terminale • Zeichen der Sprache, die nicht durch eine Produktion der Grammatik definiert sind. Z.B. Schlüsselworte von Eiffel wie if,then,endoder Symbole wie das Semikolon “;” oder die Zuweisung “:=”
Elemente einer Grammatik: Nonterminale Nonterminale Namen von syntaktischen Strukturen oder Unterstrukturen, die benutzt werden, um Phrasen zu erstellen
Elemente einer Grammatik: Produktionen ProduktionenRegeln, die durch eine Kombination von Terminalen und (anderen) Nonterminalen die Nonterminale einer Grammatik definieren
Konditional: else end Eine Beispielsproduktion Instruktion Bedingung Instruktion then if Terminal Nonterminal Produktion
A B BNF Elemente: Verkettung Graphische Repräsentation: BNF: A B Bedeutung:Agefolgt von B
A BNF Elements: Optional Graphische Repräsentation: BNF: [A ] Bedeutung:Aoder nichts
A B BNF Elements: Wahl • Graphische Repräsentation: BNF: A|B Bedeutung: entweder Aoder B
A BNF Elements: Repetition • Graphische Repräsentation: BNF: { A }* Bedeutung: Sequenz von null oder mehrerenA
A BNF Elements: Repetition, einmal oder mehr • Graphische Repräsentation: BNF: { A}+ Bedeutung: Sequenz von einem oder mehreren A
A A A B B A A BNF Elemente: Übersicht Verkettung: AB Optional: [ A ] Wahl: A | B Repetition (0 odermehr): { A }* Repetition (mind. einmal): { A }+
float_zahl: Ziffer: Ein einfaches Beispiel 0 - Ziffer 1 Ziffer . 2 3 Beispielphrasen: .76 -.76 1.56 12.845 -1.34 13.0 ÜbersetzenSiees in die schriftliche Form! 4 5 6 7 8 9
Ziffer Ein einfaches Beispiel In BNF: | | | | | | | | | 0 1 2 3 4 5 6 7 8 9 [ ] { }* { }+ - = = float_zahl Ziffer Ziffer .
Konditional: else end Konditional ] [ Bedingung Instruktion Instruktion then end else if BNF Elemente kombiniert Instruktion = Bedingung Instruktion then if In BNF geschrieben:
[ ] if end Then_teil_liste Else_teil { }* elseif Then_teil Then_teil else Verbund BNF: Konditional mit elseif Konditional = = = = Then_teil_liste then Boolescher_ausdruck Verbund Then_teil Else_teil
Boolescher_ausdruck if Verbund then { }* [ ] Verbund else Elseif_teil Boolescher_ausdruck Then_teil elseif Andere Grammatik für Konditional Konditional If_teil Then_teil Else_liste end If_teil = = = = = Then_teil Else_liste Elseif_teil
Einfaches BNF-Beispiel • SatzI[don’t ] Verb Namen Quant Namen Name {andName}* Name tomatoes|shoes|books|football Verb like|hate Quant a lot| alittle Welche der folgenden Phrasen sind korrekte Sätze? I like tomatoes and football I don’t like tomatoes a little I hate football a lot I like shoes and tomatoes a little I don’t hate tomatoes, football and books a lot Schreiben Sie die BNF um, damit sie auch die inkorrekten Phrasen beinhaltet = = = = =
Einfaches BNF-Beispiel (Lösung) Welche der folgenden Sätze sind korrekt? -I like tomatoes and football I don’t like tomatoes a little I hate football a lot I like shoes and tomatoes a little -I don’t hate tomatoes, football and books a lot • Schreiben Sie die BNF um, damit sie auch die inkorrekten Phrasen beinhaltet Satz I[ don’t ] Verb Namen [Quant] Namen Name [{, Name}* and Name] Nametomatoes|shoes| books|football Verblike|hate Quanta lot|alittle = = = = =
BNF-E Wird in der offiziellen Beschreibung von Eiffel benutzt. Jede Produktion ist eine der folgenden VerkettungABC[D] WahlAB|C|D RepetitionA{Bdelimiter... }* • A{Bdelimiter... }+ = = = = = = Interpretiertals A[ B {delimiterB }* ] Interpretiertals AB{delimiterB }*
BNF-E Regeln • Jedes Nonterminal muss auf der linken Seite von genau einer Produktion auftreten. Diese Produktion ist seine definierende Produktion. • Jede Produktion ist von einer Art:Verkettung, Wahl oder Repetition
[ ] if end Then_teil_liste Else_teil { }* elseif Then_teil Then_teil else Verbund BNF: Konditional mit elseif Konditional = = = = Then_teil_liste then Boolescher_ausdruck Verbund Then_teil Else_teil
BNF-E: Konditional [ ] Konditional if end Then_teil_liste Else_teil { ... }+ = = = = elseif Then_teil_liste Then_teil Boolescher_ausdruck then Verbund Then_teil else Verbund Else_teil
Rekursive Grammatiken Konstrukte können verschachtelt sein In BNF wird dies mit rekursiven Grammatiken ausgedrückt. Rekursion: zirkuläre Abhängigkeiten von Produktionen
Rekursive Grammatiken Konditionale können in anderen Konditionalen verschachtelt sein: else Verbund Else_teil = = = { …}* ; Verbund Instruktion | | ... | Aufruf Konditional Schleife Instruktion
Rekursive Grammatiken Der Produktionsname kann in der eigenen Definition vorkommen Definition von Then_teil_listemit Repetition: Rekursive Definition von Then_teil_liste: = = { …}* elseif Then_teil_liste Then_teil [ ] elseif Then_teil_liste Then_teil Then_teil_liste
if a = b then a := a - 1 b := b + 1 elseif a > b then a := a + 1 else b := b + 1 end Konditional = = = = [ ] Konditional Then_teil_liste Else_teil if end { ... }+ Then_teil_liste Then_teil elseif Boolescher_ausdruck Verbund Then_teil then Verbund Else_teil else
BNF für einfache arithmetische Ausdrücke Nehmen Sie an, Number ist als positiver Integer definiert, und Variablebesteht aus einem Buchstaben Keine eingeklammerte Ausdrücke Beispiele von Ausdrücken: a a + b a - b a * 7 + b Brauchen wir eine rekursive Grammatik? ExprFactor {Operator Factor}* FactorNumber | Variable • Operator + | – |*| / = = = Nein:
BNF für einfache arithmetische Ausdrücke Jetzt erlauben wir Klammern; Beispiele von Ausdrücken: a a + b a - b a * 7 + b 7 / ((a * (b + 12)) – c) 7 / ((a * b + 12) – c) Brauchen wir eine rekursive Grammatik? ExprTerm {Operator Term}* • Term Number | Variable | Nested • Nested(Expr) • Operator + | – |*| / = = = = Ja, z.B.: Ist das eine “gute” Grammatik? • Nein: sie entspricht nicht der Semantik; siehe z.B. den Unterschied zwischen • a * b + 12 • a + b *12
BNF für einfache arithmetische Ausdrücke • Eine bessere rekursive Grammatik: • Expr Term { Add_opTerm }* • Term Factor { Mult_opFactor}* • FactorNumber | Variable | Nested • Nested(Expr) • Add_op+ | – • Mult_op*| / = = = = = = Welche der folgenden Phrasen sind korrekt? aa + b-a + b a * 7 + b7 / (3 * 12) – 7 (3 * 7)(5 + a ( 7 * b)) - -
BNF für einfache arithmetische Ausdrücke Expr {Term Add_op …}+ Term { FactorMult_op …}+ FactorNumber | Variable | Nested Nested(Expr) Add_op+ | – Mult_op* | / Welche der folgenden Phrasen sind korrekt? a a + b -a + b- a * 7 + b 7 / (3 * 12) – 7 (3 * 7) (5 + a ( 7 * b)) - = = = = = =
Richtlinien für Grammatiken Halten Sie Produktionen kurz. Einfacher zu lesen Bessere Bewertung der Sprachengrösse Konditional ifBoolescher_ausdruckthenVerbund { elseifBoolescher_ausdruckthenVerbund }* [ elseVerbund ] end =
Richtlinien für Grammatiken Behandeln Sielexikale Konstrukte wie Terminale Bezeichner Konstante Werte IdentifierLetter {Letter | Digit | "_ ”}* Integer_constant [-]{Digit}+ Floating_point [-]{Digit}*“." {Digit}+ Letter "A" | "B" | ... | "Z" | "a" | ... | "z" • Digit "0" | "1" | ... | "9“ = = = = =
Richtlinien für Grammatiken Benutzen Sie eindeutige Produktionen Eine anwendbare Produktion kann so durch Anschauen von einem lexikalen Element pro Mal gefunden werden KonditionalifThen_teil_liste[ Else_teil ] end Verbund { Instruktion }* InstruktionKonditional| Schleife | Aufruf | ... = = =
Syntaxbeschreibung von Eiffel • Die Syntax von Eiffel ist in BNF-E geschrieben • Eine Produktion pro Nonterminal • Jede Produktion ist entweder eine Verkettung, eine Wahl oder eine Repetition • Spezielle Semantik der Repetition • Rekursion ist erlaubt • Terminale (lexikale) Konstruktebenutzen nicht BNF-E für ihre Beschreibung • Reservierte Wörter(z.B. if, end, class) • manifeste Konstanten (237, -12.93) • Symbole (+, ;) • Bezeichner (LINKED_LIST, put)
Syntaxbeschreibung von Eiffel (lexikale Ebene) • Lexikale Konstrukte werden mit einer BNF-ähnlichen regulären Grammatik beschrieben • Mischen von Produktionstypen erlaubt • Benutzen Sie Klammern für Eindeutigkeit, z.B.Letter (Letter | Digit | Underscore)* • Keine Rekursion • Benutzt Symbole und Zeichenintervalle, z.B. ‘a’..’z’ • Einfache Repetitionsregeln (siehe BNF) • Bei der Verkettungen müssen die Elemente nicht (lexikalisch) getrennt sein
Noch eine Übung • Definieren Sie eine rekursive Grammatik in BNF-E für Boole‘sche Ausdrücke mit der folgenden Beschreibung: • Einfache Ausdrücke, beschränkt auf die Variablenbezeichnerx, y, oder z, die, neben Klammerung, als Operationen das unäre not und die binären and, or, undimpliesbeinhalten können • Gültige Phrasen wären z.B. • notx andnot y • (x or y implies z) • y or(z) • (x)
Lösung • B_exprWith_par | Expr • With_par “(” Expr “)” • ExprNot_term | Bin_term | Variable • Bin_termB_exprBin_opB_expr • Bin_op “implies”| “or” | “and” • Not_term “not” B_expr • Variable “x” | “y” | “z” • Bemerkung: hier brauchen wir “x” um Terminale zu bezeichnen = = = = = = =
Einen Parser schreiben Ein Feature pro Produktion Verkettung:Sequenz von Feature-Aufrufen für Nonterminale, überprüft auf Terminale Wahl:Konditional mit Verbund pro Alternative Repetition:Schleife