Programowanie

Preprocesor

Preprocesor

Preprocesor to program interpretujący, którego zadaniem jest przetworzenie tekstu wejściowego w sposób określony za pomocą poleceń preprocesora przez programistę na tekst wyjściowy. Dopiero tak przetworzony tekst poddawany jest analizie składniowej i kompilacji. Wynikiem działania preprocesora jest więc tekst wyjściowy po przetworzeniu podlegający następnie kompilacji.

Preprocesor jest najczęściej zintegrowany z kompilatorem języka programowania.

Spis treści

[edytuj] Preprocesor języków C i C++

Wikibooks
Zobacz podręcznik na Wikibooks: C - Preprocesor

Najbardziej znane języki, które wyposażone są w preprocesor „wbudowany w język”, to C i C++. Dyrektywy preprocesora mogą występować w ogólności w dowolnym miejscu programu, a rozróżnienie ich od tekstu kodu źródłowego w językach C i C++ dokonywane jest poprzez poprzedzenie dyrektywy znakiem hash ‘#’. Do najważniejszych dyrektyw należą:

Dyrektywy preprocesora C/C++ wykorzystuje się często do zabezpieczenia plików nagłówkowych przed wielokrotnym dołączaniem do tego samego projektu. Jeżeli treść pliku nagłówkowego nazwa.hpp obejmie się instrukcjami:

#ifndef _NAZWA_HPP_  // (1)
#define _NAZWA_HPP_  // (2)

//  ...  treść właściwa ...

#endif               // (3) 

to przy pierwszej próbie dołączenia pliku, kompilator najpierw sprawdzi, czy zdefiniowano stałą _NAZWA_HPP_ (może ona mieć dowolną nazwę, ten sposób jest jednak dobrym zwyczajem promowanym przez programistów) (1) - jeżeli nie, zostanie ona zdefiniowana (2) i do programu zostanie dołączona treść między (2) i (3), oznaczający koniec części dodawanej tylko przy spełnieniu warunku (1).

Uwaga! Niektórzy programiści preferują instrukcję:

zapobiegającą ponownemu załączeniu treści całego pliku, w którym się owa instrukcja znajduje, jest to jednak sposób niezgodny z ISO C++ i nieobsługiwany przez część kompilatorów (kompilator nie zwróci błędu kodu - po prostu zignoruje tę instrukcję i przy próbie dołączenia pliku po raz drugi zwróci błąd wielokrotnej deklaracji/definicji tej samej zmiennej/stałej/typu/funkcji).

[edytuj] Preprocesor języka Clipper

W wersji 5.x języka Clipper został zaimplementowany preprocesor wzorowany na preprocesorze języka C. Znalazły się więc w nim takie dyrektywy jak: #define, #ifdef, ifndef, #include, #undef. Ale preprocesor ten zawiera również dwie dodatkowe dyrektywy: #command i #translate. Ich składania jest następująca: #command <szablon rozpoznawczy> => <szablon wynikowy> i identycznie dla dyrektywy translate.

Dyrektywy te umożliwiają definiowanie rozkazów i pseudorozkazów. Analizowany kod źródłowy jest sprawdzany pod kątem wystąpienia zdefiniowanych szablonów wg następującej kolejności:

1. #define,

2. #translate,

3. #command,

a po znalezieniu wzorca następuje podstawienie w jego miejsce tekstu utworzonego wg szablonu wynikowego i ponowne sprawdzenie, czy nie występuje kolejny szablon rozpoznawczy w utworzonym kodzie.

[edytuj] Preprocesor języka Pike

Również preprocesor języka Pike wzorowany jest na preprocesorze języka C. W zasadzie składnia dyrektyw preprocesora tego języka jest identyczna jak w C. Zasadnicze różnice to: brak plików nagłówkowych dołączanych dyrektywą include (choć sama dyrektywa istnieje i służy do dołączania plików z kodem źródłowym), oraz dodatkowe dyrektywy jak np. string dołączająca plik jako wartość tekstową.

[edytuj] Preprocesor języka PL/1

Najbardziej rozbudowanym zestawem instrukcji dysponuje preprocesor języka PL/1 (implementacje IBM w systemie OS). W tym przypadku znakiem wyróżniającym dyrektywę preprocesora jest znak procentu ‘%’, a semantyka poleceń preprocesora jest niemal zgodna z semantyką analogicznych instrukcji języka PL/1. Lista instrukcji tego preprocesora obejmuje większość analogicznych instrukcji samego języka, w tym takich jak:

oraz specyficzne dla preprocesora, jak

Choć preprocesor tego języka, podobnie jak w C, był wbudowany w kompilator, dzięki pewnym sztuczkom mógł być stosowany jako preprocesor dla innych języków programowania, np. FORTRAN.

[edytuj] Preprocesor asemblera

Niektóre asemblery, np. makroasembler IBM, w ramach pakietu oprogramowania dostarczają programy ułatwiające pisanie kodów źródłowych w asemblerze. Przykładem jest program SALUT wchodzący w skład w.w. pakietu, który przekształcał instrukcje strukturalne na instrukcje asemblera. Działał on więc na zasadzie preprocesora lecz nie wbudowanego w program główny, tylko jako osobny program. Przed uruchomieniem procesu asemblacji należało uruchomić program SALUT, i dopiero plik wynikowy tego programu poddać procesowi asemblowania.

W programie tym instrukcje strukturalne zapisane są w pliku źródłowym i poprzedzone znakiem dolara '$'. Program dostarcza takich konstrukcji programowania strukturalnego jak instrukcja warunkowa $IF ... $ELSE ... $ENDIF, instrukcja pętli $DO w różnych wariantach, czy instrukcja przeszukiwania $SEARCH.

[edytuj] Preprocesor a dyrektywy kompilatora

Niektóre implementacje języków programowania (np: Pascal), choć nie posiadają wbudowanego preprocesora, to udostępniają dyrektywy kompilatora, które są rozpatrywane w trakcie kompilacji, a nie jak w przypadku preprocesora przed jej wykonaniem. Zwykle lista takich dyrektyw jest znacznie bardziej uboga i o znikomych możliwościach w porównaniu z preprocesorem.