Метою є створення препроцесора для мови С, якомога менший за розміром вихідного коду в байтах , на бажаній вам мові. Його вхід буде вихідним файлом C, а його вихід буде попередньо обробленим вихідним кодом.
Елементи, які потрібно буде обробити, це: видалення коментарів (рядок / блок), директиви #include (відкриваючи файли на відносних шляхах та замінюючи текст у потрібній точці), #define, #undef, #if, #elif, #else, #endif, #ifdef, #ifndef та визначено (). Інші директиви C препроцесора, такі як #pragmas або #errors, можуть ігноруватися.
Немає необхідності обчислювати арифметичні вирази чи оператори порівняння в директивах #if, ми припускаємо, що вираз буде оцінюватись як істинне, доки воно містить ціле число, відмінне від нуля (його основне використання буде для визначеної () директиви). Наступні приклади можливих вхідних та вихідних даних (можливі додаткові пробіли у вихідних файлах були оброблені для кращого вигляду; для цього немає необхідності у вашому коді). Програма, здатна правильно обробити наступні приклади, буде вважатися достатньою.
----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
потрібно підтримувати? тобто чи повинен препроцесор підтримувати вирази арифметичними, побітовими операціями тощо?