Wie würde ich etwas ähnliches wie das Objective-C @encode () Compiler-Direktive in ANSI C implementieren?

StackOverflow https://stackoverflow.com/questions/2255637

Frage

Die @encode Richtlinie gibt eine const char *, die ein codiertes Typdeskriptor der verschiedenen Elemente des Datentyps ist, die übergeben wurde Beispiel folgt.

struct test
{ int ti ;
  char tc ;
} ;

printf( "%s", @encode(struct test) ) ;
// returns "{test=ic}"

Ich konnte mit sizeof () sehen primitive Typen zu bestimmen, -. Und wenn es sich um eine vollständige Aufgabe war, konnte ich die Klassenmethoden verwenden Innerlichkeit zu tun

Allerdings Wie funktioniert es jedes Element aus einer undurchsichtigen Struktur bestimmen?

War es hilfreich?

Lösung

@Lothars Antwort könnte „zynisch“ sein, aber es ist ziemlich nah an der Markierung, leider. Um so etwas wie @encode() zu implementieren, benötigen Sie einen Blas- Parser, um die die Typinformationen zu extrahieren. Nun, zumindest für etwas anderes als „trivial“ @encode() Aussagen (das heißt, @encode(char *)). Moderne Compiler im Allgemeinen entweder zwei oder drei Hauptkomponenten haben:

  • Das vordere Ende.
  • Das Zwischen Ende (für einige Compiler).
  • Das hintere Ende.

Das vordere Ende müssen alle den Quellcode analysiert und im Grunde wandelt den Text in Quellcode auf eine interne, „Maschine nutzbare“ Form.

Das hintere Ende übersetzt das interne „Maschine verwendbar“ Formular in ausführbarem Code.

Compiler, der eine „Zwischenende“ haben in der Regel tun dies, weil einige Notwendigkeit: sie mehrere „Frontends“, möglicherweise aus völlig verschiedenen Sprachen unterstützen. Ein weiterer Grund ist die Vereinfachung Optimierung: alle Optimierungs geht die Arbeit an der gleichen Zwischendarstellung. Die gcc Compiler Suite ist ein Beispiel für einen „dreistufigen“ Compiler. llvm könnte ein „Zwischen-und Back-End“ -Stufe Compiler berücksichtigt werden: Die „Low Level Virtual Machine“ ist die Zwischendarstellung, und alle die Optimierung erfolgt in dieser Form. llvm auch in der Lage es in dieser Zwischendarstellung zu halten bis, bis der letzten zweit- dies für „Link Zeitoptimierung“ ermöglicht. Der clang Compiler ist wirklich ein "Front-End", dass (effektiv) Ausgänge llvm Zwischendarstellung.

Wenn Sie also @encode() Funktionalität auf eine ‚bestehende‘ Compiler hinzufügen möchten, würden Sie wahrscheinlich, es zu tun haben, als „Quelle zu Quelle“ ‚Compiler / Präprozessor‘. Dies war, wie die ursprüngliche Objective-C und C ++ Compiler waren written- sie die Eingangsquelle Text analysiert und konvertiert es zu „plain C“, die dann in dem Standard-C-Compiler zugeführt wurde. Es gibt ein paar Möglichkeiten, dies zu tun:

Bewegen Sie Ihre eigenen

  • Verwenden Sie yacc und lex zu setzen, um einen ANSI-C-Parser zusammen. Sie benötigen eine Grammatik- ANSI-C-Grammatik (Yacc) ist ein guter Anfang. Eigentlich klar zu sein, wenn ich yacc sage, dann meine ich wirklich Bison und flex. Und auch, lose, die anderen yacc und lex wie C-basierte Tools: Zitrone , < a href = "http://dparser.sourceforge.net/" rel = "noreferrer"> dparser , etc ...
  • Verwenden Sie perl mit Yapp oder EYapp , die pseudo-yacc Klone in perl. Wahrscheinlich besser für schnell eine Idee Prototyping im Vergleich zu C-basierten yacc und es ist lex nach allen perl-. Reguläre Ausdrücke, assoziative Arrays, kein Memory-Management, usw.
  • Erstellen Sie Ihre Parser mit Antlr . Ich habe keine Erfahrung mit dieser Tool-Kette, aber es ist ein anderer „Compiler Compiler“ -Tool, dass (scheint), um mehr zu Java-Entwickler ausgerichtet zu sein. Es scheint frei verfügbar C und Objective-C-Grammatiken zur Verfügung zu stehen.

Hack ein weiteres Werkzeug

. Hinweis: Ich habe keine persönliche Erfahrung jedes dieser Werkzeuge mit etwas zu tun, wie @encode() Zugabe, aber ich vermute, sie wäre eine große Hilfe sein

  • CIL - Keine persönliche Erfahrung mit diesem Tool, aber für das Parsen von C-Quelle cod entworfene und „doing stuff“ mit ihm dann. Von dem, was ich aus der Dokumentation nachlesen kann, sollte dieses Tool ermöglicht es Ihnen, die Typinformationen zu extrahieren, die Sie benötigen würden.
  • Sparse -. Einen Blick wert, aber nicht sicher
  • Klirren - habe es nicht für diesen Zweck, aber angeblich eines der Ziele war, um es „leicht hackable“ für genau diese Art von Sachen. Insbesondere (und wieder, keine persönliche Erfahrung), um das „schwere Heben“ aller Parsing dabei, so dass Sie auf dem „interessanten“ Teil konzentrieren, die in diesem Fall würden Kontext und sprachsensitiver Typinformationen werden Extrahieren und wandelt dann, dass in zu einem einfachen C-String.
  • gcc Plugins - Plugins sind ein gcc 4.5 (das ist die aktuelle alpha / beta-Version des Compilers) -Funktion und „könnte“ können Sie leicht in den Compiler einzuhaken die Typinformationen extrahieren Sie bräuchten. Keine Ahnung, ob die Plugin-Architektur für diese Art der Sache erlaubt.

Andere

  • Coccinelle - Markiert das kürzlich auf "Blick auf später". Dieses „könnte“ in der Lage sein zu tun, was Sie wollen, und „vielleicht“ in der Lage sein, es mit sich viel Mühe zu tun.
  • METAC - diese eine Markiert zu vor kurzem. Keine Ahnung, wie nützlich diese sein würde.
  • mygcc - "Könnte" tun, was Sie wollen. Es ist eine interessante Idee, aber es ist nicht direkt anwendbar auf das, was Sie wollen. Von der Web-Seite: „Mygcc ermöglicht es Programmierern, ihre eigenen Kontrollen hinzuzufügen, die berücksichtigt Syntax nehmen, Ablaufsteuerung und Dateninformationsfluss.“

Links.

Edit # 1, die Bonus-Links.

@Lothar macht einen guten Punkt in seinem Kommentar. Ich hatte tatsächlich enthalten lcc gedacht, aber es sieht aus wie es auf dem Weg verloren gegangen ist.

  • lcc - Die lcc C-Compiler. Dies ist ein C-Compiler, der besonders gering ist, zumindest in Bezug auf die Quellencodegröße. Es ist auch ein Buch hat, die ich sehr empfehlen kann.
  • tcc - Die tcc C-Compiler. Nicht ganz so pädagogischen wie lcc, aber auf jeden Fall noch einen Blick wert.
  • poc - Die poc Objective-C-Compiler. Dies ist eine „Quelle zu Quelle“ Objective-C-Compiler. Es analysiert die Objective-C-Quellcode und aussendet C-Quellcode, die sie dann an gcc geht (gut, in der Regel gcc). Hat eine Reihe von Objective-C-Erweiterungen / Funktionen, die nicht in gcc sind. Auf jeden Fall einen Blick wert.

Andere Tipps

Sie würden dies implementieren, indem die ANSI-C-Compiler erste Implementierung und dann einige Implementierung spezifische Pragmas und Funktionen hinzufügen.

Ja, ich weiß, das ist zynisch Antwort und ich die downvotes akzeptieren.

Eine Möglichkeit, dies zu tun wäre, einen Prä-Prozessor zu schreiben, die den Quellcode für die Typdefinitionen lesen und ersetzt auch @encode ... mit dem entsprechenden Stringliteral.

Ein weiterer Ansatz, wenn Ihr Programm mit -g kompiliert wird, wäre eine Funktion zu schreiben, die die Typdefinition aus dem Programm der Debug-Informationen zur Laufzeit liest, oder die Verwendung gdb oder ein anderes Programm, um es für Sie zu lesen und umformatieren es dann wie gewünscht. Der gdb ptype Befehl verwendet werden kann, die Definition eines bestimmten Typs zu drucken (oder wenn das nicht ausreicht, gibt es auch maint print type, die weit mehr Informationen drucken sicher ist, als man sich nur wünschen könnte).

Wenn Sie einen Compiler verwenden, dass Unterstützungen Plugins (zB GCC 4.5), kann es auch möglich sein, eine Compiler-Plugin für diese zu schreiben. Ihre Plugin könnte dann nutzen Sie die Typ-Informationen, dass der Compiler bereits analysiert hat. Offensichtlich dieser Ansatz wäre sehr Compiler-spezifisch ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top