Ziel ist es, einen Präprozessor für die C-Sprache zu erstellen, der hinsichtlich der Quellcodegröße in Byte so klein wie möglich ist und in der von Ihnen bevorzugten Sprache vorliegt . Seine Eingabe ist eine C-Quelldatei, und seine Ausgabe ist der vorverarbeitete Quellcode.
Folgende Elemente müssen verarbeitet werden können: Entfernen von Kommentaren (Zeile / Block), # include-Anweisungen (durch Öffnen von Dateien in relativen Pfaden und Ersetzen von Text an der erforderlichen Stelle), #define, #undef, #if, #elif, #else, #endif, #ifdef, #ifndef und defined (). Andere C-Präprozessor-Direktiven wie #pragmas oder #errors werden möglicherweise ignoriert.
Es ist nicht erforderlich, arithmetische Ausdrücke oder Vergleichsoperatoren in # if-Direktiven zu berechnen. Wir gehen davon aus, dass der Ausdruck als wahr ausgewertet wird, solange er eine Ganzzahl ungleich Null enthält (seine Hauptverwendung liegt bei der defined () -Direktive). Es folgen Beispiele für mögliche Ein- und Ausgaben (mögliche zusätzliche Leerzeichen in Ausgabedateien wurden für eine bessere Darstellung gekürzt, Ihr Code muss dies nicht tun). Ein Programm, das die folgenden Beispiele ordnungsgemäß verarbeiten kann, wird als ausreichend angesehen.
----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
muss unterstützt werden? dh muss der Präprozessor Ausdrücke mit arithmetischen, bitweisen Operationen usw. unterstützen?