Compiler programmieren in BB oder BMax?
Übersicht

![]() |
Arrangemonk |
![]() Antworten mit Zitat ![]() |
---|---|---|
wer kompiler bauen will mus lernen wie das geht, ob jetzt hier (ziemlich am ende) ein fiktiver assembler oder ein real existierender verwendet wird is eigentlich irrelevant | ||
ingeneur |
BBPro2 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
so war das auch nicht gemeint, selbstverständlich ist es egal ob man in einen erfundenen assembler oder einen real existierenden übersetzt.
mit in assembler übersetzen ist die sache aber noch nicht getan wenn man einen compiler baut und maschinensprache erzeugen will. wenn man assembler erzeugen will ja - wenn man maschinensprache erzeugen will fehlt noch ein weiterer schwerer schritt, nämlich die übersetzung von assembler in selbige. wie dem auch sei meine hauptkritik galt ohnehin dem tip bezüglich yacc etc |
||
![]() |
Arrangemonk |
![]() Antworten mit Zitat ![]() |
---|---|---|
von assembler zu maschinensprache isses kein weiter weg mehr,
aber wie man genau umcodiert und linkt etc bää. das kotzt an wenn ich nen compiler bauen wollte würde ich in eine sprache die ich kompilieren kann "cross compilen" und das resultat dann anständig mit zugehörigem (edit) COMPILER kompillieren. und so hat man ne neue sprache mit wenig aufwand aber meh... ich bin eh c# besessen^^ |
||
ingeneur |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi,
schreibe gerade eine Studienarbeit zum Thema Compilerbau. Meine Grundlage ist dazu "Compilerbau Teil 1" von Aho, Sethi und Ullmann. Zudem nutze ich "Algorithmen in Java" von Lang für ein paar prägnante, formale Definitionen und Implementierungen von Automaten in Java. Nochmals Kompilieren erfolgt in den vier Schritten (manche Machen mehr Schritte, manche weniger): 1. Lexikalische Analyse: Zerlegen des Programmcodes in eine Folge von Tokens bzw. Symbole auch Tokenstream genannt. Folgende Tokens sind typisch für Programmiersprachen: "Bezeichner", "If", "Then", "Integer-Literal", "Zuweisungsoperator", "RundeKlammerAuf". Kommentare werden überlesen und Whitespaces (zum Einrücken) zum Trennen genutzt. Wobei für BASIC-Sprachen Newlines nicht überlesen werden dürfen, weil hier ein Newline einen Abschluss einer Anweisung markiert wie eine Semikolon in Jaca oder C#. Hier werden Fehler (= lexikalische Fehler) wie ein fehlendes " am Ende eines Strings erkannt. Die lexikalische Analyse erfolgt von einem Lexer bzw. Scanner. 2. Syntaxanalyse/Parsing: Die Tokens aus dem Tokenstream werden zu grammatikalischen Sätzen zusammengefasst. Daraus entsteht ein Parsebaum bzw. Ableitungsbaum. Beispiel könnte ein Tokenstream mit "count" (Bezeichner) "=" "count" (Bezeichner) "+" "1" (Integer-Literal) als Zuweisungsanweisung zusammengefasts werden. Der Baum ergibt sich daraus, dass der Zuweisungsoperator "=" in der Wurzel steht, und die Operanden "count" das linke Kind und der Ausdruck "count + 1" auf der Rechten seite. Da ein Ausdruck wiederum eine grammatische Regel ist, muss dieser ebenfalls geparst werden. Die Syntaxanalyse ist Aufgabe des Parsers. 3. Semantische Analyse: Natürlich kann dein Compiler nicht die Aufgabe deines Quellcodes herausfinden. Deswegen spricht man hier oft von statischer Semantik. Hier wird bspw. auf Typverträglichkeit geprüft. Die Zuweisungsanweisung mit einer Stringvariablen auf der linken Seite und einem Integer-Ausdruck auf der rechten Seite ist in vielen Programmiersprachen (in Blitz nicht) ein Fehler (da explizit gecastet werden muss). Weiterhin wird geprüft, ob eine Variable, die genutzt wird, auch vorher schon deklairert wurde (auch das ist in Blitz nicht der Fall) oder ob eine Funktion mit der richtigen Anzahl von Argumenten aufgerufen wurde (das wird in Blitz geprüft). 4. Codesynthese: Aus dem Parsebaum bzw. aus einem abstrahierten Parsebaum (AST Abstract Syntax Tree) kann dann die in die Zielsprache übersetzt werden. Dass muss nicht zwangsweise Maschinensprache sein, sondern kann jede beliebige Sprache sein (ein Compiler übersetzt ja Worte einer Sprache in Worte einer anderen Sprache). Bei der Zuweisung könnte man bspw. erstmal den Ausdruck auf der rechten Seite auswerten lassen, ihn in das EAX-Register schreiben und dann per MOV in die Speicherzelle der Variablen kopieren. Die Trennung zwischen lexikalischer und syntaktischer Analyse ist nicht ganz klar. In den Büchern steht oft, dass die Beschreibung der Tokens mit regulären Sprachen (die nicht rekursiv sind) erfolgt, hingegen die grammatischen Sätze mit einer BNF (die rekursionen zulässt) beschreiben werden. Kurz zur Definition einer Sprache: Eine Sprache L ist eine Teilmenge von A*, mit A als Alphabet. A* sind alle Wörter (inkl. dem leeren Wort) die aus Kombinationen der Zeichen des Alphabets A gebildet werden können. In einer Programmiersprache sind die Quelltexte die Wörter (unabhängig ob da Leerzeichen enthalten sind) und bspw. ASCII das Alphabet. Da aber nun die Quelltexte unendlich groß sind, lässt sich die Sprache nicht mehr durch Auflisten aller Wörter angeben, sondern man muss mit endlichen Regeln - den Syntaxregeln, die Wörter beschreiben. Mit regulären Ausdrücken (= Syntaxregeln) können dann solche regulären Sprachen beschrieben werden - formal als L(r) ausgedrückt, mit r als regulären Ausdruck. Ein Beispiel für einen regulären Ausdruck, der die Sprache für Bezeichner beschreibt: L(r) mit r = [A..Z]|[a..z]|_ ([A..Z]|[a..z]|[0..9]_)* was heißt, dass Bezeichner nur mit Buchstaben oder Unterstrich beginnen dürfen, gefolgt von beliebig vielen Buchstaben, Ziffern oder Unterstrichen. Solche regulären Sprachen können von endlischen Automaten ausgewertet werden. So ein Automat ist i.d.R nur ein Akzeptor der ja oder nein zurück gibt, ob der gelesen Bezeichner zur Sprache gehört oder nicht. Für lexikalische Analyse muss man diese Automaten noch so erweitern, dass sie beim erreichen eines Endzustands dann das erkannte Token in den Tokenstream einträgt. Für Programmiersprachen hat man oft mehrere reguläre Ausdrücke für Bezeichner, Stringliterale, Integerliterale etc. Hier ist es für das Entwerfen eines Automaten auf einen nicht deterministischen endlichen Automaten (NEA) mit Epsilon-Überggängen zurückzugriefen. Man erstellt ein Startzustand und man zu den aus den einzelnen regulären Ausdrücken entworfenen Automaten dann jeweils ein Epsilon-Übergang. Problem hier ist das Simulieren eines solchen NEA. Auch bei Lexx oder ANTLR erfolgt die Beschreibung der Tokens mit regulären Ausdrücken, sie nehmen Dir aber die Arbeit ab, solche Automaten daraus zu erstellen und zu simulieren. Zudem ANTLR ein hervorangendes Error-Recovering hat (es wird nicht beim ersten Fehler die Analyse abgebrochen, sondern wird versucht weitere Fehler zu erkennen im Gegensatz zum Blitz-Compiler). Für die Syntaxanalyse nutzt man wie gesagt oft die BNF bzw. EBNF zur Beschreibung der grammtikalischen Sätze. Beispiel: Assignment ::= Identifier '=' Expression. Diese Sätze lassen sich mit LR-Parsern meiner Meinung nach am einfachsten prüfen. Du erstellst für jede Produktion eine Prozedur/Methode. Kommt ein Terminal vor wie hier '=', wird geprüft, ob es vorhanden ist, kommt eine weitere Produktion vor wie hier Expression, muss die Prozedur für diese Produktionsregel rekursiv aufgerufen werden. Für den Bereich der Codesynthese finde ich statt Assembler eher die Virtuellen Maschinen von Java (JVM) bzw. von .Net (CLI) viel interessanter. Ganz einfach, weil man hier schon auf ein riesen Framework zurückgreifen. In Assembler würde man sich vermutlich aufwändig dann irgendwelche eigenen Bibliotheken schreiben für so Sachen wie Print oder WriteFile bei JVM und CLI bekommt man dass ja alles schon geschenkt. Und was man noch dazu geschenkt bekommt sind die Garbage Collection und event. Codeoptimizer auf Byte-Code ebene. Für die JVM hieße dass für deinen Compiler, dass du während der Codesynthese Byte-Code erzeugst (das ist wie Assembler, allerdings etwas einfacher zu verstehen). Heraus kommt dann eine .class Datei die Du dann vllt. noch als ausführbare .jar Datei zusammen packst. Achja, und noch einen Vorteil: Das läuft dann auch auf allen Plattformen - selbst auf einem Android. So, Du wirst jetzt sicherlich nicht alles verstanden haben aber Du hast jetzt zumindest ein paar Stichwörter, wonach Du suchen kannst. Ich finde, ein Buch kann hier das Thema sehr viel besser erläutern als das Internet. Ciao Olli |
||
vertex.dreamfall.at | GitHub |
BBPro2 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
war mir alles bewusst;
dass er in maschinensprache übersetzen möchte habe ich implizit angenommen, da es in seinem post so klang. Zitat: von assembler zu maschinensprache isses kein weiter weg mehr das sehe ich absolut anders. du musst dich für alle möglichen zielrechnerarchitekturen in die manuals reinarbeiten und entsprechend übersetzen. meiner meinung nach ist das mehr arbeit als der gesamte compiler davor ^^ wenn du einen compiler publizieren möchtest, welcher in der lage ist maschinensprache zu erzeugen - in welche sprache würdest du dann zwischenübersetzen ? mir fällt gerade keine ein, die sich von deinem programm aufrufen lassen würde um ne exe zu erstellen und zudem eine absolut freie lizenz hat. die frage ist mir sehr wichtig, da ich nämlich die letzten tage genau auf der suche nach so einem compiler war und immer noch bin ich habe nichtmal einen assembler gefunden, der sich extern aufrufen lässt und ne freie lizenz hat ![]() |
||
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
BBPro2 hat Folgendes geschrieben: wenn du einen compiler publizieren möchtest, welcher in der lage ist maschinensprache zu erzeugen - in welche sprache würdest du dann zwischenübersetzen ? mir fällt gerade keine ein, die sich von deinem programm aufrufen lassen würde um ne exe zu erstellen und zudem eine absolut freie lizenz hat.
Was ist mit Assembler oder C? Auf jeden Fall eine Assemblersprache oder eine Hochsprache mit stark optimierendem Compiler. Zitat: die frage ist mir sehr wichtig, da ich nämlich die letzten tage genau auf der suche nach so einem compiler war und immer noch bin
ich habe nichtmal einen assembler gefunden, der sich extern aufrufen lässt und ne freie lizenz hat ![]() oO gas, fasm, nasm, yasm, wasm ... kommt natürlich drauf an, was du mit freier Lizenz meinst. Hoffe, ich habe die Fragestellung richtig verstanden ![]() mfg Thunder |
||
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit |
BBPro2 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
eher nich^^
ich will nen compiler bauen welcher nen knopf hat "exe erstellen" hierzu müsste ich in eine sprache übersetzen und diese dann weiter in maschinencode übersetzen dazu müsste ich die entsprechende sprache mitliefern. das ist normalerweise nicht erlaubt. mit welcher sprache ist es erlaubt und lässt sich die übersetzung auch extern ansteuern, also per kommandozeile ? a.exe -data.bla -data.blu -c oder was auch immer |
||
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
BBPro2 hat Folgendes geschrieben: dazu müsste ich die entsprechende sprache mitliefern
Du willst eine Sprache mitliefern? *kratz* Wenn du den Compiler meinst, dann nimm doch C und den GCC. Oder mache es wie einige heutige Sprachpakete, die mehrere C Compiler unterstützen und einfach den nehmen, der vor Ort installiert ist (oder einen Link zu den Downloadseiten unterstützter Compiler anbieten, falls keiner vorhanden ist). |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ähm. Normalerweise lässt sich JEDER Compiler extern ansteuern. Sei es der gcc:
Zitat: gcc program.c -o program.exe
Der fasm: Zitat: fasm program.asm
Der FreeBasic-Compiler: Zitat: fbc program.bas
Du musst nur in die Sprache eines Compilers bzw. Assemblers kompilieren und diesen dann übersetzen lassen. mfg Thunder |
||
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit |
BBPro2 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
das größere problem ist auch eher die lizenz thunder, nicht das ansteuern
@noobody ja den compiler natürlich, nicht die sprache, haarspalterei ! ![]() den der vor ort installiert ist will ich nicht, ich kann und will nicht davon ausgehen, dass die zielperson einen c compiler installiert hat auch links finde ich alles andere als benutzerfreundlich wenn der gcc so "frei" ist würde er sich natürlich anbieten, muss ich mir mal überlegen und mich schlau machen also nochmal im klartext: ich würde den gcc dann mit meinem compiler mitliefern und ihn verwenden um meinem compiler das "exe erstellen" beizubringen das ist legal? |
||
![]() |
Thunder |
![]() Antworten mit Zitat ![]() |
---|---|---|
gcc = GNU C Compiler ... daher unter GPL lizenziert das ist eine FLOSS-Lizenz - also, wenn man es so sieht, freie Software
Du kannst aber in der Readme schreiben, dass der Benutzer den gcc installieren muss. Das mit der Lizenz ist auch bei fasm relativ einfach, weil ihn auch BlitzMax mitliefert. Und zu deiner Frage: Es ist in nicht-kommerziellen Programmen legal. Möglicherweise muss dein Programm auch unter GPL stehen, da bin ich mir jetzt nicht sicher. Das musst du in der Lizenz nachlesen. [klugscheiß] @Noobody: GCC = GNU Compiler Collection gcc = GNU C Compiler [/klugscheiß] |
||
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit |
EisbaerBetreff: Compiler Design |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das "Dragon Book" ist so ziemlich die Referenz auf dem Gebiet.
http://www.amazon.com/Compiler...0201100886 Aber zu meiner Empfehlung: Zur Übung könntest du das Script-Engine Beispiel von EPS nach BlitzBasic übersetzen. http://www.east-power-soft.de/...uts_script |
||
Eigene Webseite:
http://www.eisbaer-studios.de |
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Studienarbeit ist nun fertig geworden: http://vertex.dreamfall.at/compilerbau.pdf u. a. werden ein paar imperative Sprachkonstrukte, wie eine For-Schleife oder eine bedingte Anweisung wird für Java-Byte-Code, gezeigt.
Cao Olli |
||
vertex.dreamfall.at | GitHub |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group