8. Technische Integration in Sniff+

Sniff+ Version 1.x ist ausschließlich auf die Bearbeitung von C++ (und C) Programmen ausgelegt. (In der Version 2.0 existiert ein Konzept von verschiedenen Dateitypen, die unter­schiedlich behandelt werden. Dieses Konzept ist zum jetzigen Zeitpunkt jedoch noch nicht vollständig implementiert.)

Um zu verstehen, wie es möglich ist, in Sniff+ die Kenntnis über die Eiffel-Syntax zu integrieren, muß man die Architektur von Sniff+ betrachten.

8.1.   Die Architektur von Sniff+

Sniff+ besteht aus einem Kern, der alle Werkzeuge mit graphischer Benutzerschnittstelle beinhaltet (Editor, Class Browser, etc.). Ebenso enthält dieser Kern eine zentrale Datenbasis (Symboltabelle) mit allen Informationen über die bearbeiteten Quelltexte. Alle im Kern enthaltenen Werkzeuge beziehen ihr C++-spezifisches Wissen aus dieser zentralen Datenbasis (zumindest sollte dies so sein, ich erwähne später noch einige Probleme).

Die Datenbasis von Sniff+ wird gefüllt und aktualisiert von einem sog. Information Extractor (auch als Sniffserver bezeichnet). Dieser läuft in einem externen Prozeß und wird bei Änderungen an Quelltexten oder neu hinzugekommenen Quelldateien aufgefordert, diese zu analysieren und die gewonnenen Informationen in der Datenbasis abzulegen. Der Information Extractor enthält als seinen Hauptbestandteil einen Fuzzy-Parser für C und C++.

Abb. 14: Die Architektur von Sniff+ (aus [TakeFive 93])

Da mir das Kommunikationsprotokoll zwischen dem Sniff+-Kern und dem Information Extractor (aus [Bischofberger 95][9]) bekannt, ist konnte ich einen Information Extractor implementieren (basierend auf meinem Fuzzy-Parser für Eiffel), der die aus den Eiffel-Quelltexten gewonnenen Informationen auf C++-Eigenschaften abbildet und diese in der Datenbasis von Sniff+ ablegt. An Sniff+ habe ich keine Änderungen vorgenommen (und auch mangels Zugang zum Quelltext nicht vornehmen können).

Der Information-Extractor wird von Sniff+ gestartet, sobald die Symbolinformationen in der Datenbasis aktualisiert werden sollen, falls er zu dem Zeitpunkt noch nicht gestartet ist..

Die Kommunikation zwischen Sniff+ und dem Information Extractor findet auf einer TCP/IP-Socketverbindung statt. (Für eine einführende Erklärung in TCP/IP-Socketverbindungen siehe [ComerNarten 89].) Durch dieses Kommunikationsmedium ist bereits die Möglichkeit geschaffen, den Information Extractor auf einer anderen Maschine im Netz laufen zu lassen. Gerade wenn Sniff+ gestartet bzw. ein neues Projekt angelegt wird, müssen eine ganze Reihe von Dateien analysiert werden, so daß ein ganz erheblicher Rechenaufwand nötig ist, der auf eine andere, leistungsfähigere Maschine verlagert werden kann.

Über die Socketverbindung teilt Sniff+ dem Information Extractor mit, welche Quelldatei dieser jeweils analysieren soll. Bei einer verteilten Ausführung müssen die Dateisysteme der beteiligten Maschinen (z.B. durch eine Vernetzung mit dem Network File System, NFS) einen gemeinsamen Zugriff auf die Quelltexte zulassen.

Der Parser im Information Extractor muß keine eigene Symboltabelle führen, sondern teilt dem Sniff+-Kern via eines binären Protokolls mit, wenn er ein Symbol (z.B. Klassen- oder Methodendeklaration) gefunden hat. Zusätzlich zum Namen des Symbols werden der Symboltyp (Klassenname, Methodenname etc.) sowie die Position des Symbols im Quelltext[10] übertragen. Diese Positionsangabe erlaubt es Sniff+, bestimmte Symbole im Editor farbig zu markieren oder z.B. zwischen Deklaration und Implementation einer Methode hin und her zu wechseln. (Zusätzlich werden je nach Symboltyp einige Zusatz­informationen wie z.B. Zugriffsrechte o.ä. übermittelt.)

Für die Kommunikation ist ein einheitliches, genau fest­gelegtes Kommunikationsprotokoll nötig, damit der Client (hier: Sniff+) nicht auf Informationen wartet, die der Server (hier: der Information Extractor) nicht sendet.

Vor der Übertragung der Daten werden diese von dem lokal auf der jeweiligen Maschine verwendeten Datenformat (Binärkodierung) in ein vom TCP/IP-Protokoll festgelegtes Netzwerk-Datenformat gewandelt und vom Empfänger wieder in sein lokales Datenformat zurück gewandelt. So wird sichergestellt, daß die Daten nicht (z.B. durch unterschiedliche Byteanordnung (Big Endian / Little Endian)) vom Empfänger anders interpretiert werden als vom Sender und trotzdem jeder Sender bzw. Empfänger nur ein Paar Konvertierungsroutinen benötigt.

8.2.   Abbilden der Eigenschaften von Eiffel auf C++

Da an Sniff+ keinerlei Änderungen vorgenommen werden (können), müssen die für das Browsen wichtigen Eigenschaften von Eiffel auf Eigenschaften von C++ abgebildet werden. Da beide Sprachen ähnliche Konzepte (trotz unterschiedlicher Terminologie) haben, ist dies größtenteils möglich. Einige spezielle Eigenschaften von Eiffel sind leider nicht auf C++ abbildbar und können deshalb vom Browser nicht unterstützt werden.

 

Bezeichnung in Eiffel

Bezeichnung in C++

Bezeichnung in Sniff+

Klasse

Klasse

classes

Routine

Methode

methods

Attribut

Instanzvariable

instance variable

Elternteil

Basisklasse

base class

Erbe

abgeleitete Klasse

derived class

aufgeschoben

abstrakt

abstract

dynamisches Binden (immer verwendet)

virtuelle Methode

virtual method

Abb. 15: Eigenschaften, die sich direkt abbilden lassen

Die Vererbung ist ohne Probleme abzubilden; Probleme treten aber bei der Redefinition bzw. dem Überladen von Merkmalen auf. Mehr dazu im nächsten Abschnitt.

 

Bezeichnung in Eiffel

Bezeichnung in C++

Bezeichnung in Sniff+

Creation-Routine

Konstruktor

(nicht verwendet)

Zugriffsrechte auf Merkmale

public, protected, private

public, protected, private

Abb. 16: Eigenschaften, die sich teilweise abbilden lassen

In Eiffel ist es möglich, den Namen der Routine (oder mehrerer alternativer Routinen) frei zu wählen, die bei der Initialisierung eines Objektes aufgerufen wird. Dies ist die sog. CREATION-Methode. In C++ ist der Name des Konstruktors auf den Klassennamen festgelegt, kann aber unterschiedliche Ausprägungen mit anderen Parametern haben. Da Konstruktoren von Sniff+ nicht weiter beachtet werden, erübrigt sich der Versuch einer Abbildung.

Die Zugriffsrechte auf Merkmale lassen sich nur indirekt abbilden, da es in Eiffel die Möglichkeit gibt, bestimmte Merkmale nur für eine spezielle Klasse freizugeben.

Die Friend-Methoden in C++ können dies nicht abbilden, da ihnen immer der Zugriff auf alle Merkmale einer Klasse gewährt wird.

Ich habe mir damit geholfen, daß ich das Eiffel-Zugriffsrecht {ANY) auf das C++-PUBLIC und das Eiffel {NONE} auf das C++-PRIVATE und alle differenzierteren Zugriffsrechte auf das C++-PROTECTED abgebildet habe. Dies entspricht nicht exakt der Bedeutung in C++, bietet aber dem Eiffel-Programmierer die bestmögliche Abstufung unter diesen Rahmenbedingungen.

Es gibt aber auch eine ganze Reihe von Eigenschaften von Eiffel, die sich überhaupt nicht in C++ abbilden lassen.

 

Bezeichnung in Eiffel

Indexing

Vor- und Nach-Bedingungen

Invarianten

expandierte (Expanded) Klassen

veraltete (Obsolete) Klassen, Methoden

einmalige (Once) Ausführung von Methoden

Umbenennung (Rename) von geerbten Merkmalen

Aufschieben (Undefine) von geerbten Merkmalen

Abb. 17: Eigenschaften von Eiffel, die kein C++-Gegenstück haben

Bei einigen Eigenschaften (z.B. expandiert, Obsolete, Once) würde eine farbliche Markierung o.ä. wie bei aufgeschobenen Merkmalen ausreichen. Bei anderen, z.B. Indexing, wäre eine umfassendere Unterstützung durch den Browser wünschenswert.

In [EllisStrou 90] findet sich ein Vorschlag für das ANSI-Normungs Komitee, C++ um ein syntaktisches Konstrukt zur Umbenennung geerbter Methoden zu erweitern. Soweit mir bekannt ist, ist dieser Vorschlag bisher jedoch nicht in den Sprachstandard übernommen worden. Von Sniff+ ist hierfür ebenfalls bisher keine Unterstützung vorhanden.

Das Aufschieben von geerbten Merkmalen ist in Eiffel zwar zugelassen, widerspricht aber guter Programmierpraxis, da es die Subtyp-Beziehung der Klassen stört.[11] Von dieser Möglichkeit in Eiffel sollte ein Programmierer daher keinen Gebrauch machen. Trotzdem wäre es sehr wichtig, daß der Browser deutliche Warn-Hinweise gibt, falls geerbte Merkmale aufgeschoben wurden.

8.3.   Probleme bei der Integration

Bei der Integration des neuen Information Extractors sind einige Stellen sichtbar geworden, an denen Sniff+ implizite Annahmen über die zu bearbeitende Sprache (C++) macht. Die Struktur der Datenbasis ist z.T. stark auf C++ zugeschnitten. Daher kann ein neuer Information Extractor nur begrenzt die Eigenschaften einer neuen Sprache einbringen.

Zum einen betrifft dies die Reihenfolge, in der Information Extractor mitteilen darf, welche Informationen er gefunden hat.

Ein Beispiel für implizite Annahmen über die Reihenfolge von Informationen: Da C++ kein direktes Ausdrucksmittel hat, um eine aufgeschobene Klasse zu markieren[12], wird dies in ET++ durch Makros nachgebildet und so auch von Sniff+ unterstützt. Da diese Makros aber nur außerhalb der Klassendefinitionen stehen dürfen, macht Sniff+ die Annahme, daß die Information über eine gefundene aufgeschobene Klasse nur außerhalb einer Klassendefinition gemeldet wird, und hängt sich andernfalls auf.

Zum anderen ist im Class Browser fest verdrahtet, wie das Redefinieren von Methoden (in C++) funktioniert. So werden Methoden mit gleichem Namen und gleichen Parametern von der neuen Definition überladen, und alle anderen werden additiv hinzugefügt. In Eiffel spielen die Parameter dagegen keine Rolle. (Um dieses Problem zu umgehen, meldet mein Information Extractor zu keiner Routine die Parameter.)

Die Möglichkeiten, in Eiffel geerbte Merkmale umzubenennen oder aufzuschieben, lassen sich überhaupt nicht abbilden.


 

 


Last updated: 24. Aug 2005
Page maintained by Jan Willamowius
Imprint/Impressum · Privacy/Datenschutz
 
English: Home | Linux | Perl | Java | Eiffel | Books | Music | Jan Willamowius | Updates | Site Map
Deutsch: Home | Badminton | ISBN-Suche | Musik-Suche | Rezepte | Jan Willamowius