Info B VL 1: Einführung
Objektorientiere Programmierung in Java 2003
Ute Schmid (Vorlesung) Elmar Ludwig ( ¨ Ubung)
FB Mathematik/Informatik, Universit¨at Osnabr¨uck
Info B VL 1: Einf¨uhrung – p.1
Programmier-Paradigmen (1)
Imperativ/Prozedural
Wertezuweisung an Variablen, Zustandstransformation
Nah am Modell des von-Neumann Rechners Fortran, Modula, Pascal, C
Logisch
Programm als Menge von logischen Klauseln Beweis der Anfrage (SLD-Resolution)
Prolog
Programmier-Paradigmen (2)
Funktional
Programm als Menge von (typisierten) Funktionen nur call by value, Seiteneffekt-Freiheit!
Lisp, ML, Haskell Objektorientiert
jüngstes Paradigma (80er Jahre)
Programm als Menge von Objekten, die miteinander interagieren
Smalltalk, C++, Java
Info B VL 1: Einf¨uhrung – p.3
Entwicklung von Hochsprachen
Erste Generation: Maschinensprachen Zweite Generation: Assemblersprachen Hochsprache
Dritte Generation: Imperative Sprachen Lesbarkeit, Modularisierung (Dijkstra) Compiler bzw. Interpreter
Vierte Generation: Anwendungsspezifische Sprachen
SQL, Mathematica
Fünfte Generation: Deklarative Sprachen
logische/funktionale
Entwicklungsbaum
Fortran
Algol−58
Algol−60 Cobol
Simula I
Simula−67 Algol−68
C
Modula−2 Fortran−77
Ada−83
Modula−3
Ada−95 Java
Eiffel
Objective C C++
CLOS
Haskell Standard−ML Common Lisp
ML Scheme
Lisp
Fortran−90
Smalltalk
Prolog 1957
1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995
Pascal
IMPERATIV OBJEKTORIENTIERT FUNKTIONAL LOGISCH
Info B VL 1: Einf¨uhrung – p.5
Natürliche und Formale Sprachen
Organisation in Sprachfamilien
Indogermanisch (englisch, deutsch, ...) vs.
romanisch (italienisch, französisch) vs. slawisch ...
Sprache und Vorstellung von der Welt sind eng verzahnt (Zeitpfeil vs. Zyklus)
Sprachen innerhalb eines Programmierparadigmas basieren auf ähnlichen Grundstrukturen
Sprache besteht aus
Syntax (Grammatik): Erzeugung von wohlgeformten Sätzen
Semantik: Bedeutung der Konstrukte (“Baum”,
“do-while”)
Pragmatik: Verwendung
Kenntnis von mehr als einem Paradigma
Größeres Repertoire an Ausdrucksmöglichkeiten Hintergrund für geeignete Sprachwahl
Bessere Voraussetzung um neue Sprachen zu lernen Verständnis von Implementationsdetails
Voraussetzung für Sprachentwicklung
Allgemeine Entwicklung von Programmiersprachen
Die Grenzen meiner Sprache sind die Grenzen meiner Welt.
L. Wittgenstein
Info B VL 1: Einf¨uhrung – p.7
Prozeduren
Strukturierung von Programmen:
Objekt-orientiert: Klassen als kleinste autonome Bausteine
Imperativ:
Deklarationsblock Prozeduren
Hauptprogramm
Prozedur (vgl. Java Methode)
Kopf: Namen {Parameter} [ Rückgabetyp]
Rumpf: Anweisungen lokale Variablen
Programmbeispiel: ggt.m2
Parameterübergabe-Methoden
Kopf einer Prozedur/Methode: formale Parameter Rumpf: selbe Parameter als Platzhalter für konkrete Werte
Übergabe-Methoden
Call-by-value: erst auswerten, dann Wert einsetzen Call-by-reference: Referenz (Adresse) wird
übergeben
Seiteneffekt kann (gewollt/ungewollt) auftreten!
Speicherplatz-Ersparnis (Kopieren von Arrays) Call-by-name: Argumentausdrücke werden
unausgewertet übergeben, Auswertung “by need”
In Modula, C, C++: call-by-value und call-by-reference In funktionalen Sprachen: call-by-value oder call-by
name Info B VL 1: Einf¨uhrung – p.9
Call-by-Value in Java
Programmbeispiel: PassByValue.java
Button Object b
y
Button Object b
Button Object Another y
Java: nur call-by-value (auch für Referenztypen!)
Sprachimplementierung
Programm (Code, Quellcode) Programmausführung:
Start, Eingabe
Berechnung (Transformation der Eingabe) Ausgabe
Laufzeit (Aufwandsklasse des dem Programm zugrundeliegenden Algorithmus, Rechnerleistung) Übersetzung von Quellcode durch Compiler (C) Direkte Ausführung von Programmcode durch Interpreter (Prolog)
Hybrid: Erst Compilierung in Zwischencode, dann Interpretation
In Java: Zwischencode ist maschinenunabhängiger Bytecode, Java Virtual Machine führt Bytecode (rechnerspezifisch) aus
Info B VL 1: Einf¨uhrung – p.11
Implementationssysteme
Ausgabe Interpreter Eingabe
Quellprogramm Quellprogramm
Lexikalische Analyse
Syntaxanalyse
Zwischencode−Erzeugung
Eingabe Zwischencode
Interpreter Ausgabe Quellprogramm
Ausgabe
Lexikalische Analyse
Codeerzeugung Symbol−
tabelle Semantische Analyse Zwischencode−Erzeugung
Syntaxanalyse
(Optimierung) Compiler
ÜBERSETZZEIT LAUFZEIT
Maschinencode
Maschine
Eingabe
Syntax
Die Syntax einer Sprache legt fest, wie einzelne Symbole zu größeren Strukturen zusammengesetzt werden dürfen.
Syntax wird durch Grammatik beschrieben:
mit
als Menge der Nonterminal-Symbole
als Menge der Terminalsymbole (Alphabet)
als Menge der Grammatikregeln (Produktionen)
als Startsymbol.
Beispiele (Englisch, 01-Worte)
Bei formalen Sprachen, spricht man von erzeugten Worten über einem Alphabet
Produktivität: endliche Grammatik erlaubt die Erzeugung von unendlich vielen Worten
Info B VL 1: Einf¨uhrung – p.13
Reguläre und Kontextfreie Sprachen
(Chomsky Hierarchie)
Reguläre Sprachen: Regeln der Form
bzw.
Kontextfreie Sprachen: rechts beliebige Kombinationen aus Terminalen und Nonterminalen erlaubt
beschreibt die Sprache
Programmiersprachen sind im wesentlichen kontextfrei (mit kontext-sensitiven Anteilen, z.B. “Variablennamen müssen deklariert werden vor sie benutzt werden” )
Statt üblicher Grammatik-Schreibweise werden BNF (Backus-Naur Form) oder EBNF (erweiterte BNF) zur Darstellung der Syntax einer Programmiersprache
verwendet.
BNF und EBNF sind äquivalent zu kontextfreien
Backus-Naur Form
Produktionsregeln haben die Form Kopf ::= Körper.
Nichtterminale werden in spitzen Klammern
dargestellt, dadurch können auch ganze Wörter statt nur einzelne Symbole als Nonterminale verwendet werden.
Alternative rechte Seiten werden durch einen senkrechten Strich getrennt dargestellt.
Runde Klammern regeln Zusammenfassung und
Vorrang. Alternativen haben den geringsten Vorrang.
Anschaulich stellt man BNF durch Syntaxdiagramme dar.
Info B VL 1: Einf¨uhrung – p.15
EBNF
EBNF, zusätzliche Abkürzungen:
eckige Klammern ([ ]) umschließen Symbolfolgen, die null oder einmal auftreten dürfen
geschweifte Klammern ({ }) umschließen
Symbolfolgen, die beliebig oft (auch null-mal) vorkommen dürfen.
Java in EBNF findet sich unter:
http://cui.unige.ch/db-research/Enseignement/analyseinfo/JAVA/
Java Syntax in EBNF
class_declaration ::=
{ modifier } "class" identifier [ "extends" class_name ]
[ "implements" interface_name { "," interface_name } ]
"{" { field_declaration } "}"
(hier Terminale in Anführungszeichen, Nonterminale ohne Klammern)
Info B VL 1: Einf¨uhrung – p.17
Parser
Die eindeutige und vollständige Beschreibung der Syntax einer Programmiersprache ist wichtig für den Programmierer, um syntaktisch korrekte Programme zu schreiben, und Grundlage für den Parser.
Ein Parser ist ein Akzeptor für einen Programmtext.
Ein syntaktisch korrektes Programm wird ein einen Syntaxbaum überführt.
Ein guter Parser gibt informative Fehlermeldungen, falls das Programm nicht der Grammatik der
Programmiersprache genügt.
Programmiersprachen sollten syntaktisch eindeutig sein. Das heisst, jede Folge von Symbolen entspricht genau einem Parse-Baum.
Wenn Uneindeutigkeiten existieren, werden sie durch
Dangling Else Ambiguity
S
:: = if E
then S
[else S
] entspricht den Alternativen:
S
::= if E
then S
S
::= if E
then S
else S
Zu welchem if gehört das else?
if E1 then if E2 then S1 else S2
Typische Auflösung: Matche else mit dem am nächsten stehenden noch ungematchten if.