Remplacement du préprocesseur C

Je suis intéressé à utiliser autre chose que le préprocesseur C pour prétraiter mon code source C et Objective-C. Y a-t-il de bonnes alternatives?

Un exemple serait quelque chose qui permettrait à quelqu’un de s’échapper dans un extrait de python ou de perl au milieu du code C , et où l’extrait de code cracherait C qui serait ensuite compilé normalement.

Vous pouvez utiliser PHP comme préprocesseur C. Les avantages sont:

  • syntaxe très similaire, donc la coloration syntaxique fonctionne.
  • et ?> ne sont pas utilisés dans le standard C (avec C non standard, la seule chose qui se casse est l'ancien opérateur d'extension GCC qui retourne min / max)
  • c'est riche en bibliothèques.
  • c'est turing complet.
  • l'utilisation des macros est très explicite. (comparé aux macros préprocesseurs sneaky C)

Pour un usage sérieux cependant, en faisant en sorte que PHP print, les directives #line soient nécessaires pour le débogage du code prétraité.

  int main() {  } 

L’idée que vous exécutiez du code, dont le résultat est ensuite intégré, est appelée quasiquotation . Le code que vous exécutez est obsolète .

Je sais comment résoudre ce problème en utilisant Lua. J’ai utilisé ssortingng.gsub avec une fonction d’antiquotation que j’ai écrite moi-même . J’ai utilisé la syntaxe shell pour l’antiquotation. Comme dans le shell, le code antiquoted renvoie une chaîne qui est ensuite épissée dans le code.

Au-dessous de prog est le code C avec le texte antiquoted, et antiquote est la fonction d’antiquotation. J’ai utilisé la chaîne spéciale de Lua en citant les doubles crochets à son avantage. En pratique, vous ne feriez pas cela ; vous metsortingez prog dans un fichier séparé.

 names = { 'John', 'Paul', 'George', 'Ringo' } local prog = [===[ #include  main() { $(local out = { } for _, n in ipairs(names) do table.insert(out, ssortingng.format([[ printf("The name is %%s\n", %q);]], n)) end return table.concat(out, '\n ') ) } ]===] local function antiquote(s) local body = s:match '^%$%((.*)%)$' return assert(loadssortingng(body))() end prog = prog:gsub('%$%b()', antiquote) io.stdout:write(prog) 

En cours d’utilisation, le programme ressemble à ceci:

 : nr@curlycoat 1181 ; lua /home/nr/tmp/emit-c.lua #include  main() { printf("The name is %s\n", "John"); printf("The name is %s\n", "Paul"); printf("The name is %s\n", "George"); printf("The name is %s\n", "Ringo"); } 

Cog n’est pas exactement un pré-processeur, mais il est intégré au code et génère des données à la volée.

Vous voudrez peut-être envisager m4.
http://www.gnu.org/software/m4/

Si vous résumez un peu votre problème, vous cherchez en fait un moteur de modélisation pour votre code. Tout comme la plupart des sites Web insèrent du contenu généré dynamicment dans des modèles statiques, vous souhaitez insérer du code généré dynamicment dans votre programme.

J’utilise actuellement Jinja2 (Python) pour la plupart des travaux de modélisation – je l’ai trouvé très configurable à tous les niveaux.

Si vous êtes prêt à mettre la main à la pâte avec du C ++, vous trouverez l’parsingur Wave dans Boost, qui est construit à l’aide de l’parsingur de descente récursif Spirit. C’est un préprocesseur C complet conforme aux dernières spécifications pour C et C ++ (et, par extension, Objective C, AFAICS).

Il est très modulaire, vous pouvez donc changer votre propre pilote pour pouvoir faire les extras que vous souhaitez.

http://www.boost.org/libs/wave/doc/introduction.html

Bien sûr, le préprocesseur C standard est très limité.
J’ai fait un tel outil récemment: https://github.com/d-ash/perlpp

Par exemple ceci

   read_(* v);  

devient cela

 char read_CHAR(char* v); int read_INT(int* v); long read_LONG(long* v); 

La syntaxe est similaire à PHP, mais elle utilise à la place Perl et peut capturer des textes dans des piqûres Perl.

Edit by cxw – Avec l’approbation de @d-ash, je suis également responsable de perlpp. Si vous avez des questions, n’hésitez pas à me laisser un message!

J’ai déjà pensé à ce même problème par le passé. Assurez-vous que vous êtes d’accord avec le fait que toute personne souhaitant comstackr votre code aura également besoin du nouvel outil de pré-traitement. Si vous êtes le seul à y travailler, pas de problème, mais si vous souhaitez rendre le code accessible aux autres, vous pouvez envisager d’append ou non un outil requirejs.

La réponse courte est non.” Le préprocesseur est si intimement lié à la sémantique de C que vous ne pouvez pas vraiment le supprimer, et en fait, dans certains compilateurs, il n’existe même pas de phase distincte, comme dans le cas de l’Objectif C Mac parsing simplement la syntaxe Objective C. Donc, bien que vous puissiez certainement utiliser un autre macro-processeur, comme m4, pour traiter votre texte source avant de le transmettre à C, vous ne supprimerez pas le préprocesseur C, vous appendez une autre étape de prétraitement.

Mais il y a une question plus profonde ici: que voulez-vous gagner en éliminant la phase du RPC?

CPP fait beaucoup de choses importantes pour le code C que vous n’avez probablement pas besoin de ré-implémenter. Ce que vous semblez rechercher à la place peut être un processus de modélisation qui émet du code C.

Cheetah est l’un des nombreux qui vous permettent d’utiliser Python. Il y en a d’autres qui utilisent Python et d’autres encore dans d’autres langages, mais Cheetah est connu pour être indépendant de la production, où certains moteurs de template sont très orientés vers HTML / XML. Faire votre recherche.

Je vois un article de 2001 présentant un pré-processeur ressemblant à un python http://ray.cg.tuwien.ac.at/rft/Papers/PYM/pym.html . Il n’est pas clair que quelqu’un l’utilise ..

Vous pouvez utiliser votre langage de programmation préféré pour créer un script / outil afin de générer des fichiers sources (.c / .cpp ou .h ou autres). Il suffit de les #include ou de les comstackr dans votre projet. Il peut être utile d’avoir des commentaires à proximité de #include pour identifier l’endroit où se trouve l’outil et ce qui est généré.

Cela peut ne pas être aussi pratique (ou propre) que d’utiliser un préprocesseur “réel”, mais cela fonctionnerait. Là encore, cela dépend vraiment de votre cas.

Je serais intéressé de voir ce que les gens proposent. J’ai eu tendance à faire de petites choses personnalisées avec des préprocesseurs écrits en Perl. Il est facile de configurer un Makefile qui appelle le préprocesseur. Par exemple, voici une règle pour appeler un programme nommé «meta» pour générer «fichier.c» à partir de «fichier.c.meta».

 % :: %.meta meta $< > $@ 

Je fais des choses amusantes avec les «méta» comme la génération de structures de données C adaptées. C’est certainement une direction que je suggère d’explorer. Mon espoir est de créer une méta-bibliothèque à peu près parallèle aux modèles C ++.