|
|
Der User Language Compiler dient dazu, User Language-Quelltext in User Language-Maschinenprogramme bzw. in User Language-Libraries zu übersetzen. User Language-Programme können vom User Language Interpreter ausgeführt werden. User Language-Libraries werden üblicherweise aus häufig benötigten Quelltexten erzeugt. Der Maschinencode von User Language-Libraries kann wahlweise statisch (während der Kompilierung durch den User Language Compiler) oder dynamisch (während der Laufzeit durch den User Language Interpreter) eingebunden werden in anderen Maschinencode (Programme oder Libraries). Der Vorteil des Librarykonzepts besteht darin, dass häufig benötigte Quelltexte nur einmal der zeitaufwändigen Kompilierung unterzogen werden müssen; anschließend kann der entsprechende Maschinencode über die sehr viel schnelleren Linkprozesse referenziert werden. 3.2.1 ArbeitsweiseDer User Language Compiler übersetzt User Language-Quelltext in User Language-Maschinencode (User Language-Programme oder User Language-Libraries). Bei der Kompilierung führt der Compiler eine umfassende Konsistenzprüfung des Quelltextes hinsichtlich Syntax und Semantik durch, befreit das Programm bzw. die Library von Redundanzen und erzeugt schließlich - in sehr kompakter Form - einen zum Quelltext äquivalenten Maschinencode. Nach Bedarf werden durch den im User Language Compiler integrierten Linker statische Linkprozesse durchgeführt bzw. notwendige Informationen für dynamische Linkprozesse generiert. Dies alles geschieht in der nachfolgend beschriebenen Abfolge von Arbeitsschritten. Syntaxanalyse und SemantikprüfungIm ersten Schritt der Kompilierung erfolgt die syntaktische Analyse des Quelltextes. Über einen Parser-Lauf werden dabei die formalen Probleme behandelt, ob also die in der Quelltextdatei enthaltene Sequenz von Worten und Zeichen ein syntaktisch gültiges User Language-Programm (bzw. eine korrekte User Language-Library) darstellt. Bereits während der Syntaxanalyse wird der Teil der Semantikprüfung durchgeführt, der die im Programm enthaltenen Definitionen (für Variablen, Parameter und Funktionen) auf Konsistenz und Eindeutigkeit in Bezug auf deren Geltungsbereiche prüft. Ergebnis dieses ersten Parser-Laufes (Pass 1) ist eine interne Symboltabelle, die für den zweiten Parser-Lauf (Pass 2) zur semantischen Prüfung benötigt wird. Die semantische Prüfung umfasst die kontext-sensitive Analyse des Quelltextes. Ziel dabei ist es, den Missbrauch der im Programm bzw. in der Library definierten Objekte zu unterbinden. Es wird also die Gültigkeit der Verwendung von Namen ebenso geprüft, wie die Zulässigkeit der Operationen auf die im Programm bzw. in der Library definierten Objekte. Generierung des MaschinencodesBereits während der Semantikprüfung, d.h. im zweiten Parser-Durchlauf (Pass 2) wird der zum Quelltext äquivalente Maschinencode konstruiert. Nur wenn die semantische Prüfung vollständig durchgeführt wurde, und dabei keine Fehler auftraten, entspricht der erzeugte Maschinencode auch einem ausführbaren Maschinenprogramm bzw. einer korrekten User Language-Library. LinkerMit dem im User Language Compiler integrierten Linker können optional statische Linkprozesse durchgeführt bzw. notwendige Informationen zur Durchführung dynamischer Linkprozesse generiert werden. Beim statischen Linken (Compiler-Option -lib) bindet der User Language Compiler den Maschinencode der angeforderten User Language-Libraries direkt in den Maschinencode des aktuell übersetzten Quelltextes ein. Dabei werden die angeforderten Libraries sowie die darin referenzierten Objekte (Funktionen, Variablen, etc.) einer Kompatibilitäts- und Konsistenzprüfung unterzogen. Beim dynamischen Linken (Compiler-Option -dll) simuliert der User Language Compiler lediglich die Einbindung des Maschinencodes der angeforderten User Language-Libraries. Resultat dieses Prozesses sind Relokationstabellen mit Informationen zur Auflösung der Bibliotheksreferenzen. Diese Relokationstabellen werden mit dem zu übersetzenden Maschinencode abgespeichert und später vom User Language Interpreter zur Laufzeiteinbindung der angeforderten Dynamic Link Libraries verwendet. Bei Änderungen an User Language-Libraries ist zu beachten, dass alle diejenigen User Language-Programme und User Language-Libraries, die Anforderungen zum dynamischen Linken der geänderten Libraries enthalten, neu kompiliert werden müssen. OptimiererDer Optimierer des User Language Compilers kann mit der Option -O aktiviert werden. Er hat die Aufgabe, den zuvor erzeugten Maschinencode von Redundanzen zu befreien und den Maschinencode durch Änderungen effizienter zu gestalten. Der Optimierer erkennt und eliminiert dabei nicht erreichbare Code-Segmente sowie nicht referenzierte Funktions-, Variablen- und Parameterdefinitionen. Er wandelt soweit möglich Variablenreferenzen in Konstantenzugriffe um (Constant Propagation), und er führt algebraische Optimierungen durch. Durch den Einsatz des Optimierers ergibt sich in aller Regel eine signifikante Reduzierung des Speicherplatzbedarfs und der Laufzeit für den Maschinencode ergibt. Auf einen ausgesprochen nützlichen Nebeneffekt der Optimierung sei ausdrücklich hingewiesen: in einem durch den Optimierer modifizierten Maschinencode lassen sich u.U. Programmierfehler lokalisieren, die der Compiler sonst nicht erkannt hätte. Prüfung des MaschinencodesNachdem der Maschinencode fertig erzeugt ist, wird er nochmals auf schwerwiegende Programmierfehler geprüft. Zu dieser Kategorie von Fehlern zählen die Division durch Null, die Konstruktion von Endlos-Schleifen und endlos-rekursive Funktionsaufrufe, die der Compiler durch die Analyse des Maschinencodes u.U. erkennen kann. Ausgabe einer ListingdateiDer User Language Compiler kann optional zur Ausgabe einer Listingdatei veranlasst werden. Die Angaben in dieser Datei sind u.U. nützlich bei der Lokalisierung von Fehlern, die erst zur Laufzeit, also bei der Programmausführung auftreten. Der vollständige Inhalt der Listingdatei besteht aus allgemeinen Angaben zum Programm bzw. zur Library (Name, Version, Aufruftyp), Verweisen auf die im Maschinencode referenzierten Libraries bzw. Library-Definitionen, der Auflistung der im Maschinencode statisch eingebundenen Libraries und der im Maschinencode definierten Objekte (Funktionen, Variablen, Strukturen, usw.) sowie der Auflistung des Maschinencodes selbst (Liste der Instruktionen mit Angabe der Quelltextzeilennummer und der äquivalenten Zeilennummer(n) im Maschinencode). Die Ausführlichkeit der auszugebenden Information kann über verschiedene Modi der Listing-Option -l des User Language Compilers kontrolliert werden, wodurch z.B. vom Inhalt her eingeschränkte Listingdateien zur Dokumentation von User Language-Libraries (Funktionsreferenzen) erzeugt werden können. Die Option
-ld gestattet die Spezifikation eines alternativen Verzeichnisses für die mit der Option
-l auszugebenden Listindateien. Dies ist insbesondere bei der Verwendung von
Speicherung des MaschinencodesDer letzte Schritt des Compiler-Laufes besteht in der Speicherung des erzeugten Maschinenprogramms bzw. der generierten
User Language-Library. Der
User Language Compiler legt per Default das Maschinenprogramm (bzw. die
User Language-Library) als Datenbankeintrag unter dem beim Compileraufruf spezifizierten Elementnamen (siehe Compiler-Optionen
-Source,
-cp,
-cl) in der Datei
Mit Hilfe spezieller Compiler-Optionen ist auch das Löschen von
User Language-Programmen (Option
-dp) und
User Language-Libraries (Option
-dl) aus der Datei
3.2.2 CompileraufrufDer Compileraufruf startet die Übersetzung von User Language-Programmen bzw. von User Language-Libraries. SynopsisDer Aufruf des User Language Compilers erfolgt auf Betriebssystemebene. Die Aufrufsyntax lautet: ulc [-wcon|-wcoff] [[-S[ource]] srcfile...] [-lib libname...] [-dll libname...] [{-cp|-cl} [dstname...]] [-I[nclude] includepath...] [-D[efine] macroid...] [-O[0|1]] [-e[0|1]] [-w[0|1|2|3|4]] [-t[0|1]] [-l[0|1|2|3|4|5]] [-ld listingdirectory] [-dp prgname...] [-dl libname...] [-ulp prgfilename] [-ull libfilename] [-log logfilename] Bei einem syntaktisch falschen Aufruf des User Language Compiler wird die korrekte Aufrufsyntax des Compilers angezeigt, und der Compiler-Lauf wird abgebrochen. OptionenDie Kommandozeilenoptionen des
User Language Compilers bestehen aus einem Bindestrich
( Wildcard Option [-wcon|-wcoff]
Source File Option [[-S[ource]] srcfile...]
Static Link Option [-lib libname...]
Dynamic Link Option [-dll libname...]
Create Program/Library Option [{-cp|-cl} [dstname...]]
Include Path Option [-I[nclude] includepath...]
Define Option [-D[efine] macroid...]
Optimizer Option [-O[0|1]]
Error Severity Option [-e[0|1]]
Warning Severity Option [-w[0|1|2|3|4]]
Top Level Warnings Only Option [-t[0|1]]
Listing Option [-l[0|1|2|3|4|5]]
Listing Directory Option [-ld listingdirectory]
Delete Program Option [-dp prgname...]
Delete Library Option [-dl libname...]
Program Database File Name Option [-ulp prgfilename]
Library Database File Name Option [-ull libfilename]
Log File Option [-log logfilename]
BeispieleKompilieren des in
ulc ulprog -Ow Kompilieren des in
ulc ulprog -l -cp newprog Löschen der
User Language-Programme mit Namen
ulc -dp ulprog newprog -dl test*lib Erzeugen der
User Language-Library
ulc libbae.ulh -cl libsll -l2O Kompilieren aller im aktuellen Verzeichnis enthaltenen Quelltextdateien mit der Extension
ulc *.ulc -Define USELIB -lib libsll -O Generieren der
User Language-Libraries
ulc -w2 -O -cl libstd stdlib -Source std.ulh Generieren der
User Language-Library
ulc /wO -cl liblay -S \baeulc\lay.ulh -dll libstd -log genlib.rep Generieren der
User Language-Programme
laypcr und
tracerep aus den Quelltextdateien
ulc laypcr.old /dll liblay /cp -O /S tracerep 3.2.3 FehlerbehandlungMit der wichtigste Bestandteil des Compilers ist die Fehlerbehandlung. Dies ist darin begründet, dass der Compiler am weitaus häufigsten Quellcodedateien zu bearbeiten hat, die fehlerbehaftet sind oder Redundanzen aufweisen (ein absolut fehlerfreies Programm wird i.d.R. nur einmal übersetzt). Die durch den Compiler ausgegebenen Fehlermeldungen sollen dem Programmierer helfen, das zu entwickelnde Programm bzw. die zu erzeugende Library möglichst schnell in einen fehlerfreien Zustand zu bringen. Der
User Language Compiler gibt alle Meldungen auf die Standardausgabe und gleichzeitig auf eine Reportdatei aus. Die Ausgabe auf die Reportdatei erfolgt, da die Liste der Meldungen - insbesondere bei der Übersetzung mehrerer Quellcodedateien - sehr umfangreich werden kann. Der Standardname
Im Folgenden ist eine Liste aller im
User Language Compiler definierten Meldungen, Warnungen und Fehler aufgeführt. Beim Auftreten von Fehlern kann kein ablauffähiger Maschinencode erzeugt werden. Warnungen weisen den Programmierer darauf hin, dass zwar ablauffähiger Maschinen-Code erzeugt werden kann, dieser aber u.U. mit unerwünschten Nebeneffekten behaftet ist. Wo immer möglich, wird der Meldung in Klammern die Zeilennummer vorangestellt, in der der Fehler lokalisiert wurde; diese Zeilennummer bezieht sich entweder auf die Quellcode-Datei
( Den unten aufgeführten Warnmeldungen ist jeweils eine Nummer in eckigen Klammern vorangestellt. Diese Angaben sind nicht Bestandteil der tatsächlich ausgegebenen Warnungen, sondern geben vielmehr den Warning Severity Level an, der mit der Option -w mindestens eingestellt sein muss, damit die entsprechende Warnung vom User Language Compiler ausgegeben wird. Warnungen, die dem Severity Level 0 zugeordnet sind, werden unabhängig vom aktuell eingestellten Warning Severity Level grundsätzlich ausgegeben. Allgemeine MeldungenBei einem syntaktisch falschen Aufruf des User Language Compilers korrekten Aufrufsyntax des Compilers angezeigt, und der Compiler-Lauf wird abgebrochen. Die folgenden allgemeinen Compiler-Meldungen geben Aufschluss über die Aktionen des Compilers bzw. werden als resümierende Meldungen über den Compiler-Lauf ausgegeben: Loeschen Programme aus "n"... Programm 'n' geloescht. Loeschen Libraries aus "n"... Library 'n' geloescht. Libraries Laden/Linken... Quellcodedatei "n" wird kompiliert... Programm 'n' erfolgreich generiert. Library 'n' erfolgreich generiert. Quellcodedatei "n" erfolgreich kompiliert. e Fehler, w Warnungen. User Language Compiler-Lauf abgebrochen! User Language Compiler-Lauf erfolgreich beendet. Die folgenden Fehlermeldungen stehen in direktem Zusammenhang und weisen auf fehlende Benutzungsberechtigung zur Ausführung des User Language Compilers, ungültige Datei- bzw. Elementnamensangaben, Dateizugriffsprobleme oder Probleme beim Zugriff auf User Language-Libraries hin: FEHLER : Die Benutzungsberechtigung fehlt! FEHLER : Dateiname "n" ist zu lang! FEHLER : Dateiname "n" enthaelt ungueltige Zeichen! FEHLER : Elementname 'n' ist zu lang! FEHLER : Elementname 'n' enthaelt ungueltige Zeichen! FEHLER : Fehler beim Schreiben auf Listing-Datei "n"! FEHLER : ULC-Log-Datei "n" kann nicht angelegt werden! FEHLER : Zu viele Quellcodedateien spezifiziert! FEHLER : Quellcodedatei "n" nicht gefunden! FEHLER : Library 'n' nicht gefunden"! FEHLER : User Language Library 'n' Version inkompatibel! Die folgenden Warnmeldungen stehen in direktem Zusammenhang mit dem Compileraufruf und weisen auf Probleme beim Lesen von Verzeichnissen bzw. beim Zugriff auf Programme oder Libraries, sowie auf Kompatibilitätsprobleme beim Linken von Libraries hin: [0] WARNUNG : Verzeichnis 'n' nicht gefunden/nicht verfuegbar! [0] WARNUNG : Programm 'n' nicht gefunden! [0] WARNUNG : Library 'n' nicht gefunden! [0] WARNUNG : User Language Library 'n' nicht optimiert! Interne Compiler-FehlerDie folgenden internen Compiler-Fehler können in Zusammenhang mit der Speicherverwaltung stehen oder auf Implementierungs-Lücken im Compiler hinweisen: (Ll) FEHLER : Listen-Ueberlauf! (Ll) FEHLER : Zu wenig Speicherplatz! (Ll) FEHLER : INTERNER FEHLER IN function -- BITTE MELDEN! Parser FehlerDie folgenden Fehler können beim Zugriff auf Quelltextdateien bzw. bei der Syntaxanalyse auftreten: (Ll) FEHLER : Eingabedatei "n" nicht gefunden! (Ll) FEHLER : Eingabedatei "n" kann nicht gelesen werden! (Ll) FEHLER : Eingabedatei Dateielement zu lang ('s')! (Ll) FEHLER : Eingabedatei Ausdruck zu komplex ('s')! (Ll) FEHLER : Syntaxfehler bei 'string' (unerwartetes Symbol)! (Ll) FEHLER : Allgemeiner Analyser-Fehler! Semantische Fehler und WarnungenDie folgenden Fehler können bei der semantischen Prüfung der Quelltextdatei auftreten: (Ll) FEHLER : Identifier 'n' ist zu lang! (Ll) FEHLER : Character 's' ist zu lang / Kein Character! (Ll) FEHLER : String 's' ist zu lang! (Ll) FEHLER : Numerische Angabe 's' ist zu lang! (Ll) FEHLER : Ungueltige numerische Angabe 's'! (Ll) FEHLER : Typ 'n' nicht definiert! (Ll) FEHLER : Typ 'n' mehrfach definiert! (Ll) FEHLER : Funktion 'n' undefiniert! (Ll) FEHLER : Funktion 'n' mehrfach definiert! (Ll) FEHLER : Funktion 'n' ist als System-Funktion definiert! (Ll) FEHLER : Funktions-Parameter 'n' nicht definiert! (Ll) FEHLER : Funktions-Parameter 'n' mehrfach definiert! (Ll) FEHLER : Funktions-Parameter 'n' mehrfach deklariert! (Ll) FEHLER : Variable 'n' nicht definiert! (Ll) FEHLER : Variable 'n' mehrfach definiert! (Ll) FEHLER : Zuweisung an Konstante oder Ergebnis nicht erlaubt! (Ll) FEHLER : Kein Array; Index-Zugriff nicht moeglich! (Ll) FEHLER : Ungueltige Array-Index-Angabe! (Ll) FEHLER : Array-Index nicht im gueltigen Bereich! (Ll) FEHLER : Zugriff auf Element ('n') aus unbekannter Struktur! (Ll) FEHLER : Struktur 'n' unbekannt/ungueltig! (Ll) FEHLER : Struktur 'n' mehrfach definiert! (Ll) FEHLER : Struktur-Element 'n' unbekannt/ungueltig! (Ll) FEHLER : Struktur-Element 'n' mehrfach definiert! (Ll) FEHLER : Index 'n' unbekannt/ungueltig! (Ll) FEHLER : Index-Variable 'n' unbekannt/ungueltig! (Ll) FEHLER : 'n' ist keine Variable vom Typ index! (Ll) FEHLER : 'forall'-Index nicht in 'of'-Index 'n' enthalten! (Ll) FEHLER : 'continue' nicht innerhalb Schleife! (Ll) FEHLER : 'break' nicht innerhalb Schleife oder 'switch'! (Ll) FEHLER : 'void'-Funktion 'n' kann keinen 'return'-Wert liefern! (Ll) FEHLER : Funktion 'n' muss gueltigen 'return'-Wert liefern! (Ll) FEHLER : 'return'-Ausdruck nicht typ-kompatibel zur Funktion 'n'! (Ll) FEHLER : Ausdruck nicht typ-kompatibel zum Parameter 'n'! (Ll) FEHLER : Ausdruck nicht typ-kompatibel zur Variablen 'n'! (Ll) FEHLER : Operand nicht typ-kompatibel zum 'n'-Operator! (Ll) FEHLER : Operanden nicht typ-kompatibel zum 'n'-Operator! (Ll) FEHLER : Zuweisung an aktiven Schleifen-Index unzulaessig! (Ll) FEHLER : Ungueltiger 'n'-Ausdruck! (Ll) FEHLER : Unbekannte/undefinierte Funktion 'n'! (Ll) FEHLER : Funktion 'n' - zu wenig Parameter spezifiziert! (Ll) FEHLER : Funktion 'n' - Parameter nicht kompatibel! (Ll) FEHLER : Funktion 'n' - Parameter nicht im Wertebereich! (Ll) FEHLER : Ungueltige '#if-#else-#endif'-Konstruktion! (Ll) FEHLER : Identifier 'n' ist als Makro definiert! (Ll) FEHLER : Zugriff auf void Makro 'n'! (Ll) FEHLER : BNF kann nicht in UL-Library gespeichert werden! (Ll) FEHLER : BNF mehrfach definiert! (Ll) FEHLER : BNF-Symbol 'n' unbekannt/undefiniert! (Ll) FEHLER : BNF-Produktion 'n' mehrfach definiert! (Ll) FEHLER : BNF-Reduce/Reduce-Konflikt bei Produktion 'n'! (Ll) FEHLER : BNF-Terminalsymbol 'n' ist ungueltig! (Ll) FEHLER : BNF-Kommentarbegrenzer 's' ist ungueltig! (Ll) FEHLER : BNF-Funktion 'n' ist nicht vom Type 'int'! (Ll) FEHLER : Division durch Null! (Ll) FEHLER : Endlos-Schleife! (Ll) FEHLER : Funktion 'n' - rekursiver Aufruf! (Lp) FEHLER : Stack Ueberlauf! FEHLER : Dateiende erreicht; '}' wurde erwartet! FEHLER : Inkompatible Index-/Funktions-Referenz(en)! Die folgenden Warnungen können bei der semantischen Prüfung der Quellcodedatei auftreten: [1] (Ll) WARNUNG : BNF enthaelt keine gueltigen Produktionen! [2] (Ll) WARNUNG : Funktion 'n' - Default-'return'-Wert verwendet! [1] (Ll) WARNUNG : Funktion 'n' - zu viele Parameter spezifiziert! [2] (Ll) WARNUNG : Funktion 'n' - Aenderung n. Parameter wird ignoriert! [2] (Ll) WARNUNG : Funktion 'n' - Aenderung fuer Parameter 'n' wird ignoriert! [2] (Ll) WARNUNG : Konstanter 'n'-Ausdruck! [2] (Ll) WARNUNG : Ausdruck hat keine Seiten-Effekte! [2] (Ll) WARNUNG : Funktion 'n', lokale Variable 'n' verdeckt globale Variable! [2] (Ll) WARNUNG : Funktion 'n', Parameter 'n' verdeckt globale Variable! [4] (Ll) WARNUNG : Variable 'n' wurde nicht initialisiert! [4] (Ll) WARNUNG : Makro 'n' neu definiert! Optimierer-WarnungenDie folgenden Warnungen werden ggf. vom Optimierer erzeugt und weisen auf Redundanzen im Quellcode hin: [1] (Ll) WARNUNG : BNF ist nicht referenziert! [2] (Ll) WARNUNG : Globale Variable 'n' ist nicht referenziert! [2] (Ll) WARNUNG : Funktion 'n' ist nicht referenziert! [2] (Ll) WARNUNG : Statement wird nicht erreicht! [3] (Ll) WARNUNG : Funktion 'n', Lokale Variable 'n' ist nicht referenziert! [3] (Ll) WARNUNG : Funktion 'n', Parameter 'n' ist nicht referenziert! [4] WARNUNG : Library-Funktion 'n' ist nicht referenziert! [4] WARNUNG : Library-Variable 'n' ist nicht referenziert! [4] WARNUNG : Dynamic Link Library 'n' ist nicht referenziert! Datenbank-Zugriffs-FehlerDie folgenden Fehler können beim Speichern des Maschinen-Codes auftreten: FEHLER : Datenbankdatei "n" kann nicht angelegt werden! FEHLER : Schreib-/Lesefehler beim Zugriff auf Datei "n"! FEHLER : Zu viele offene Dateien im System! FEHLER : Datei "n" ist keine Datenbank/DDB-Datei! FEHLER : Die Datenbankstruktur in Datei "n" ist beschaedigt! FEHLER : Der Dateiaufbau ist fehlerhaft in Datei "n"! FEHLER : Funktion fuer altes Format nicht verfuegbar! FEHLER : Datenbank Limit ueberschritten! FEHLER : Datei "n" ist zur Programmversion inkompatibel! FEHLER : Element 'n' nicht gefunden! FEHLER : Element 'n' existiert bereits! FEHLER : Datei "n" nicht gefunden! FEHLER : Record-Ende erreicht! FEHLER : Allgemeiner Datenbankfehler!
Compiler |
|