L'objectif est de créer un préprocesseur pour le langage C, aussi petit que possible en termes de taille de code source en octets , dans votre langue préférée. Son entrée sera un fichier source C et sa sortie sera le code source prétraité.
Les éléments qu'il devra être en mesure de traiter seront: la suppression des commentaires (ligne / bloc), les directives #include (en ouvrant les fichiers aux chemins relatifs et en remplaçant le texte au point requis), #define, #undef, #if, #elif, #else, #endif, #ifdef, #ifndef et defined (). D'autres directives de préprocesseur C comme #pragmas ou #errors peuvent être ignorées.
Il n'est pas nécessaire de calculer des expressions arithmétiques ou des opérateurs de comparaison dans les directives #if, nous supposons que l'expression sera évaluée à true tant qu'elle contient un entier différent de zéro (son utilisation principale sera pour la directive defined ()). Des exemples d'entrées et de sorties possibles suivent (les éventuels espaces blancs supplémentaires dans les fichiers de sortie ont été coupés pour une meilleure apparence, il n'est pas nécessaire que votre code le fasse). Un programme capable de traiter correctement les exemples suivants sera considéré comme suffisant.
----Input file: foo.c (main file being preprocessed)
#include "bar.h" // Line may or may not exist
#ifdef NEEDS_BAZZER
#include "baz.h"
#endif // NEEDS_BAZZER
#ifdef _BAZ_H_
int main(int argc, char ** argv)
{
/* Main function.
In case that bar.h defined NEEDS_BAZ as true,
we call baz.h's macro BAZZER with the length of the
program's argument list. */
return BAZZER(argc);
}
#elif defined(_BAR_H_)
// In case that bar.h was included but didn't define NEEDS_BAZ.
#undef _BAR_H_
#define NEEDS_BARRER
#include "bar.h"
int main(int argc, char ** argv)
{
return BARRER(argc);
}
#else
// In case that bar.h wasn't included at all.
int main()
{return 0;}
#endif // _BAZ_H_
----Input file bar.h (Included header)
#ifndef _BAR_H_
#define _BAR_H_
#ifdef NEEDS_BARRER
int bar(int * i)
{
*i += 4 + *i;
return *i;
}
#define BARRER(i) (bar(&i), i*=2, bar(&i))
#else
#define NEEDS_BAZZER // Line may or may not exist
#endif // NEEDS_BARRER
#endif // _BAR_H_
----Input file baz.h (Included header)
#ifndef _BAZ_H_
#define _BAZ_H_
int baz(int * i)
{
*i = 4 * (*i + 2);
return *i;
}
#define BAZZER(i) (baz(&i), i+=2, baz(&i))
#endif // _BAZ_H_
----Output file foopp.c (no edits)
int baz(int * i)
{
*i = 4 * (*i + 2);
return *i;
}
int main(int argc, char ** argv)
{
return (baz(&argc), argc+=2, baz(&argc));
}
----Output file foopp2.c (with foo.c's first line removed)
int main()
{return 0;}
----Output file foopp3.c (with bar.h's line "#define NEEDS_BAZZER" removed)
int bar(int * i)
{
*i += 4 + *i;
return *i;
}
int main(int argc, char ** argv)
{
return (bar(&argc), argc*=2, bar(&argc));
}
#if
besoins doivent être pris en charge? c'est-à-dire que le préprocesseur doit prendre en charge les expressions avec des opérations arithmétiques, au niveau du bit, etc.?