Comment puis-je mettre en œuvre quelque chose de similaire à l'@encode Objective-C () directive du compilateur en C ANSI?

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

Question

.

La directive @encode renvoie un const char * qui est un descripteur de type codé des divers éléments du type de données qui a été adoptée dans l'exemple suivant:

struct test
{ int ti ;
  char tc ;
} ;

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

Je pouvais voir à l'aide sizeof () pour déterminer les types primitifs - et si elle était un objet plein, je pouvais utiliser les méthodes de classe pour faire l'introspection

.

Cependant, comment il détermine chaque élément d'une structure opaque?

Était-ce utile?

La solution

@Lothars réponse pourrait être « cynique », mais il est assez proche de la marque, malheureusement. Afin de mettre en œuvre quelque chose comme @encode(), vous avez besoin d'un analyseur complet soufflé afin d'en extraire les informations de type. Eh bien, au moins pour autre chose que des déclarations de @encode() « trivial » (c.-à-@encode(char *)). Les compilateurs modernes ont généralement deux ou trois composantes principales:

  • L'extrémité avant.
  • L'extrémité intermédiaire (pour certains compilateurs).
  • Le back-end.

L'avant doit analyser tout le code source et convertit essentiellement le texte de code source dans une forme interne, « machine utilisable ».

L'extrémité arrière se traduit par l'intérieur, la forme « de la machine utilisable » dans le code exécutable.

Compilateurs qui ont un général « fin intermédiaire » font à cause d'un besoin: ils prennent en charge plusieurs « extrémités avant », peut-être composé de plusieurs langues complètement différentes. Une autre raison est de simplifier l'optimisation: tout l'optimisation passe le travail sur la même représentation intermédiaire. La suite du compilateur gcc est un exemple d'un compilateur « en trois étapes ». llvm pourrait être considérée comme une étape « fin intermédiaire et arrière » compilateur: La « machine virtuelle de bas niveau » est la représentation intermédiaire, et tout l'optimisation se déroule sous cette forme. llvm également en mesure de le maintenir dans cette représentation intermédiaire jusqu'à la dernière deuxième cela permet « l'optimisation des liens de temps ». Le compilateur clang est vraiment une sortie « extrémité avant » que (efficacement) llvm représentation intermédiaire.

Donc, si vous voulez ajouter des fonctionnalités de @encode() à un « existant » compilateur, vous auriez sans doute de le faire comme une « source à la source » 'compilateur / préprocesseur. C'est ainsi que l'Objective-C et les compilateurs C Original étaient written- ils parsés le texte source d'entrée et l'a converti en « plaine C » qui a été ensuite introduit dans le compilateur C standard. Il y a quelques façons de le faire:

Roulez vos propres

  • Utilisez yacc et lex pour mettre en place un analyseur ANSI-C. Vous aurez besoin d'un grammar- grammaire ANSI C (YACC) est un bon début. En fait, pour être clair, quand je dis yacc, je veux dire vraiment bison et flex. Et aussi, vaguement, l'autre divers yacc et lex comme des outils basés sur C: citron , < a href = "http://dparser.sourceforge.net/" rel = "noreferrer"> dparser , etc ...
  • Utilisez perl avec ou Yapp EYapp , qui sont des clones pseudo-yacc en perl. Probablement mieux pour le prototypage rapide d'une idée par rapport à yacc base C et lex- il est perl après tout. Les expressions régulières, tableaux associatifs, pas de gestion de la mémoire, etc
  • Créez votre analyseur avec Antlr . Je n'ai aucune expérience avec cette chaîne d'outils, mais il est un autre outil « compilateur de compilateur » qui (semble) être davantage orientée vers les développeurs Java. Il semble y avoir librement disponibles C et Objective-C grammaires disponible.

Hack un autre outil

Note:. Je n'ai pas d'expérience personnelle en utilisant l'un de ces outils pour faire quoi que ce soit comme l'ajout @encode(), mais je pense qu'ils seraient d'une grande aide

  • CIL - Aucune expérience personnelle avec cet outil, mais conçu pour analyser la morue source Ce puis « faire des choses » avec elle. D'après ce que je peux tirer de la documentation, cet outil devrait vous permettre d'extraire les informations de type que vous auriez besoin.
  • Sparse -. Intéressant de regarder, mais pas sûr
  • clang - N'a pas utilisé à cette fin, mais aurait été l'un des objectifs était de faire « facilement piratable » pour tout ce genre de choses. En particulier (et encore, pas d'expérience personnelle) à faire le « levage de charges lourdes » de toute l'analyse syntaxique, vous permet de vous concentrer sur la partie « intéressante », qui dans ce cas serait extrayait le contexte et la syntaxe des informations de type sensible, puis convertir qu'en à une chaîne C ordinaire.
  • gcc Plugins - Plugins sont gcc 4.5 (qui est le version actuelle alpha / bêta du compilateur) et fonction « pourrait » vous permettre de connecter facilement au compilateur pour extraire les informations de type que vous auriez besoin. Aucune idée si l'architecture de plug-in permet ce genre de chose.

Autres

  • Coccinelle - Bookmarked Récemment à "regarder plus tard". Ce « pourrait » être en mesure de faire ce que vous voulez, et « pourrait » être en mesure de le faire avec beaucoup d'efforts sur.
  • CMETA - Bookmarked celui-ci a récemment aussi. Aucune idée de comment cela serait utile.
  • mygcc - "pourrait" faire ce que vous voulez. Il est une idée intéressante, mais ce n'est pas directement applicable à ce que vous voulez. A partir de la page Web: «Mygcc permet aux programmeurs d'ajouter leurs propres contrôles qui prennent en compte la syntaxe, les flux de contrôle, et des informations de flux de données »

Liens.

Edit # 1, les liens bonus.

@Lothar fait un bon point dans son commentaire. Je l'avais fait l'intention d'inclure lcc, mais il semble que cela a été perdu en chemin.

  • lcc - Le compilateur lcc C. Ceci est un compilateur C qui est particulièrement faible, au moins en termes de taille de code source. Il a également a un livre , que je recommande fortement.
  • tcc - Le compilateur tcc C. Pas tout à fait aussi pédagogique que lcc, mais certainement encore la peine de regarder.
  • poc - Le compilateur Objective-C poc. Ceci est une "source à" compilateur Objective-C. Il analyse le code source Objective-C et émet le code source C, qui passe alors à gcc (bien, habituellement gcc). Formé d'un nombre d'extensions / fonctionnalités Objective-C qui ne sont pas disponibles dans gcc. Certainement la peine de regarder.

Autres conseils

Vous mettre en œuvre ce en mettant en œuvre le compilateur ANSI C puis ajouter quelques pragma spécifiques de mise en œuvre et les fonctions à lui.

Oui, je sais que c'est la réponse cynique et j'accepte les downvotes.

Une façon de le faire serait d'écrire un préprocesseur, qui lit le code source pour les définitions de type et remplace également @encode ... avec la chaîne correspondante littérale.

Une autre approche, si votre programme est compilé avec -g, serait d'écrire une fonction qui lit la définition du type de l'information de débogage de programme au moment de l'exécution, ou utilisez gdb ou un autre programme pour le lire pour vous puis reformater comme voulu. La commande gdb de ptype peut être utilisé pour imprimer la définition d'un type particulier (ou si cela ne suffit pas il y a aussi maint print type, qui ne manquera pas d'imprimer beaucoup plus d'informations que vous pourriez avoir envie).

Si vous utilisez un compilateur qui prend en charge plugins (par exemple, GCC 4.5), il peut également possible d'écrire un plugin compilateur pour cela. Votre lecteur pourrait alors tirer profit des informations de type que le compilateur a déjà analysé. Il est évident que cette approche serait très compilateur spécifique.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top