Wo genau ist die Grenze zwischen einem Prä-Prozessor und einem Compiler?

6 Antworten

8

Das ist eine interessante Frage. Ich weiß keine definitive Antwort, aber würde das sagen, wenn man nach einem drängt:

  

Ein Präprozessor analysiert den Code nicht, sondern sucht stattdessen nach eingebetteten Mustern und erweitert sie um

     

Ein Compiler analysiert den Code tatsächlich, indem er einen AST (abstrakten Syntaxbaum) erstellt und diesen dann in eine andere Sprache umwandelt

    
Daren Thomas 25.08.2011, 07:36
quelle
4

Die Sprache der Ausgabe des Präprozessors ist eine Teilmenge der Sprache der Eingabe.

Die Sprache der Ausgabe des Compilers ist (normalerweise) sehr unterschiedlich (Maschinencode), dann die Sprache der Eingabe.

    
Tomas 25.08.2011 07:36
quelle
2

Aus einer vereinfachten, persönlichen Sichtweise:

Ich betrachte den Präprozessor als eine beliebige Form der Textmanipulation, die keine Konzepte der zugrunde liegenden Sprache (dh Semantik oder Konstrukte) hat und daher nur auf eigenen Regeln beruht, um ihre Aufgaben zu erfüllen.

Der Compiler startet, wenn Regeln und Regeln auf das angewendet werden, was gerade verarbeitet wird (ja, macht 'meinen' Präprozessor zu einem Compiler, aber warum nicht: P), dazu gehören die synantische und lexikalische Überprüfung und die enthaltenen Transformationen von x ( textuell) zu y (binäre / Zwischenform). wie einer meiner Professoren sagen würde: "Es ist ein System mit Inputs, Prozessen und Outputs".

    
Necrolis 25.08.2011 08:15
quelle
2

Der C / C ++ -Compiler kümmert sich um Typkorrektheit , während der Präprozessor Symbole einfach erweitert.

    
Janusz Lenar 25.08.2011 08:20
quelle
0

Ein Compiler besteht aus Serval-Prozessen (Komponenten). Der Präprozessor ist nur einer dieser und relativ einfachsten.

Aus dem Wikipedia-Artikel Aufteilung der Compiler-Prozesse :

  

Alle außer den kleinsten Compilern haben mehr als zwei Phasen. Jedoch,   Diese Phasen werden üblicherweise als Teil des Frontends oder als   das hintere Ende. Der Punkt, an dem sich diese beiden Enden treffen, ist offen für   Debatte.

     

Das Frontend wird allgemein als syntaktisch angesehen   und die semantische Verarbeitung findet statt, zusammen mit der Übersetzung in eine niedrigere   Darstellungsstufe (als Quellcode).

     

Das mittlere Ende ist normalerweise   Entwickelt, um Optimierungen in einem anderen Formular als dem Quellcode durchzuführen   oder Maschinencode. Diese Quellcode / Maschinencode-Unabhängigkeit ist   soll ermöglichen, generische Optimierungen zwischen Versionen zu teilen   des Compilers unterstützt verschiedene Sprachen und Zielprozessoren.

     

Das Backend nimmt den Ausgang von der Mitte. Es kann mehr leisten   Analyse, Transformationen und Optimierungen für eine bestimmte   Computer. Dann erzeugt es Code für einen bestimmten Prozessor und ein bestimmtes Betriebssystem. "

Die Vorverarbeitung ist nur der kleine Teil des Front-End-Jobs.

Der erste C ++ - Compiler, der durch Anfügen eines zusätzlichen Prozesses vor dem vorhandenen C-Compiler-Toolset erstellt wurde, nicht weil es ein gutes Design ist, sondern weil Zeit und Ressourcen begrenzt sind.

Heutzutage glaube ich nicht, dass ein solcher nicht-nativer C ++ - Compiler im kommerziellen Bereich überleben kann.

Ich wage cfront für C++11 ist unmöglich zu machen.

    
9dan 25.08.2011 11:28
quelle
0

Die Antwort ist ziemlich einfach. Ein Präprozessor arbeitet an Text als Eingabe und hat Text als Ausgabe. Beispiele hierfür sind die alten Unix-Befehle m4, cpp (der C-Pre-Prozessor), sowie Unix-Programme wie roff und nroff und troff, die man-Seiten (Unix-Kommando "man") formatieren (oder formatieren) oder formatieren zum Drucken oder Setzen. Präprozessoren sind sehr einfach, sie wissen nichts über die "Sprache des Textes", die sie verarbeiten. Mit anderen Worten, sie verarbeiten normalerweise natürliche Sprachen. Der C-Präprozessor neben seinem Namen, z.B. erkennt nur #define, #include, #ifdef, #ifndef, #else usw. und wenn Sie #define MACRO verwenden, versucht es das Makro überall dort zu "erweitern", wo es es findet. Aber das muss kein C- oder C ++ - Programmtext sein, es kann auch ein Roman auf Italienisch oder Griechisch sein. Compiler, die sich in eine andere Sprache übersetzen, werden normalerweise als Übersetzer bezeichnet. So war der alte cfront "Compiler" für C ++, der C-Code ausgab, ein C ++ - Übersetzer. Präprozessoren und spätere Übersetzer werden historisch verwendet, weil alten Maschinen einfach nicht genügend Speicher zur Verfügung stand, um alles in einem Programm ausführen zu können, sondern stattdessen von spezialisierten Programmen und von Platte zu Platte. Ein typisches C-Programm würde aus verschiedenen Quellen zusammengestellt werden. Und der Build-Prozess würde mit make verwaltet werden. In unseren Tagen wird der C-Präprozessor normalerweise direkt in den C / C ++ - Compiler eingebaut. Ein typischer make-Lauf würde den CPP auf den * .c-Dateien aufrufen und die Ausgabe in ein anderes Verzeichnis schreiben, von dort würde entweder der C-Compiler CC ihn direkt in Maschinencode kompilieren oder allgemeiner Assemblercode als Text ausgeben. Hinweis: Der c-Compiler überprüft nur die Syntax, es kümmert sich nicht wirklich um die Typensicherheit usw. Dann würde der Assembler diesen Assembler-Code nehmen und eine * .o-Datei ausgeben, die später mit anderen * .o-Dateien und * .lib verknüpft werden kann Dateien in ein ausführbares Programm. OTOH Sie hatten wahrscheinlich eine make-Regel, die nicht den C-Compiler aufrufen würde, sondern den lint-Befehl, den C-Sprachanalysator, der nach typischen Fehlern und Fehlern sucht (die vom c-Compiler ignoriert werden). Es ist ziemlich interessant, in Wikipedia nach Flusen, Nroff, Troff, M4 usw. zu suchen (D oder D)     

Angel O'Sphere 03.09.2011 16:21
quelle