Preprocesor — Preprocessor

W informatyce , o preprocesora (lub Prekompilator ) to program, który przetwarza jego dane wejściowe do wyjścia spożywczego, który jest używany jako wejście do innego programu. Mówi się, że dane wyjściowe są wstępnie przetworzoną formą danych wejściowych, która jest często używana przez niektóre kolejne programy, takie jak kompilatory . Ilość i rodzaj wykonanego przetwarzania zależy od charakteru preprocesora; niektóre preprocesory są w stanie wykonać tylko stosunkowo proste podstawienia tekstowe i rozszerzenia makr , podczas gdy inne mają moc pełnoprawnych języków programowania .

Typowym przykładem z programowania komputerowego jest przetwarzanie wykonywane na kodzie źródłowym przed następnym krokiem kompilacji. W niektórych językach komputerowych (np. C i PL/I ) występuje faza tłumaczenia znana jako przetwarzanie wstępne . Może również obejmować przetwarzanie makr, dołączanie plików i rozszerzenia językowe.

Preprocesory leksykalne

Preprocesory leksykalne są najniższym poziomem preprocesorów, ponieważ wymagają jedynie analizy leksykalnej , to znaczy operują na tekście źródłowym, przed jakąkolwiek parsowaniem , wykonując proste zastąpienie tokenizowanych sekwencji znaków innymi tokenizowanymi sekwencjami znaków, zgodnie ze zdefiniowanymi przez użytkownika zasady. Zwykle wykonują zastępowanie makr , dołączanie tekstowe innych plików oraz warunkową kompilację lub dołączanie.

Preprocesor C

Najczęstszym tego przykładem jest preprocesor C , który jako dyrektywy przyjmuje wiersze zaczynające się od '#' . Ponieważ nie wie nic o języku bazowym, jego użycie zostało skrytykowane, a wiele jego funkcji zostało wbudowanych bezpośrednio w inne języki. Na przykład makra zastąpione agresywnym wstawianiem i szablonami, obejmują importy w czasie kompilacji (wymaga to zachowania informacji o typie w kodzie wynikowym, co uniemożliwia przekształcenie tej funkcji w język); kompilacja warunkowa jest skutecznie realizowany z if-then-elsei eliminacja kod martwy w niektórych językach. Jednak kluczową kwestią do zapamiętania jest to, że wszystkie dyrektywy preprocesora powinny zaczynać się w nowym wierszu.

Inne preprocesory leksykalne

Inne preprocesory leksykalne obejmują uniwersalny m4 , najczęściej używany w wieloplatformowych systemach budowania, takich jak autoconf , oraz GEMA , procesor makr o otwartym kodzie źródłowym, który działa na wzorcach kontekstu.

Preprocesory składniowe

Preprocesory składniowe zostały wprowadzone wraz z rodziną języków Lisp . Ich rolą jest przekształcanie drzew składniowych zgodnie z szeregiem reguł zdefiniowanych przez użytkownika. W przypadku niektórych języków programowania reguły są napisane w tym samym języku co program (odbicie w czasie kompilacji). Tak jest w przypadku Lisp i OCaml . Niektóre inne języki do definiowania przekształceń opierają się na języku w pełni zewnętrznym, takim jak preprocesor XSLT dla XML lub jego statycznie typowany odpowiednik CDuce .

Preprocesory składniowe są zwykle używane do dostosowywania składni języka, rozszerzania języka przez dodanie nowych prymitywów lub osadzania języka programowania specyficznego dla domeny (DSL) w języku ogólnego przeznaczenia.

Dostosowywanie składni

Dobrym przykładem dostosowywania składni jest istnienie dwóch różnych składni w języku programowania Objective Caml . Programy mogą być pisane obojętnie przy użyciu „normalnej składni” lub „poprawionej składni” i mogą być ładnie wydrukowane z dowolną składnią na żądanie.

Podobnie wiele programów napisanych w OCaml dostosowuje składnię języka poprzez dodanie nowych operatorów.

Rozszerzanie języka

Najlepsze przykłady rozszerzenia języka za pomocą makr można znaleźć w rodzinie języków Lisp . Podczas gdy języki same w sobie są prostymi, dynamicznie typowanymi rdzeniami funkcjonalnymi, standardowe dystrybucje Scheme lub Common Lisp pozwalają na programowanie imperatywne lub obiektowe, a także na typowanie statyczne. Prawie wszystkie te funkcje są implementowane przez wstępne przetwarzanie składniowe, chociaż należy zauważyć, że faza "rozwijania makr" kompilacji jest obsługiwana przez kompilator w Lisp. Można to nadal uznać za formę przetwarzania wstępnego, ponieważ odbywa się przed innymi fazami kompilacji.

Specjalizacja języka

Jedną z niezwykłych cech rodziny języków Lisp jest możliwość wykorzystania makr do tworzenia wewnętrznego DSL. Zazwyczaj w dużym projekcie opartym na Lispie , moduł może być napisany w różnych minijęzykach , jeden być może przy użyciu dialektu Lisp opartego na SQL , inny napisany w dialekcie wyspecjalizowanym dla GUI lub ładnego drukowania, itp. Common Lisp Standardowa biblioteka zawiera przykład tego poziomu abstrakcji składniowej w postaci makra LOOP, które implementuje minijęzyk podobny do Algola do opisu złożonej iteracji, jednocześnie umożliwiając korzystanie ze standardowych operatorów Lisp.

MetaOCaml preprocesor / język zapewnia podobne funkcje DSL zewnętrznych. Ten preprocesor pobiera opis semantyki języka (tj. interpreter) i, łącząc interpretację w czasie kompilacji i generowanie kodu, zamienia tę definicję w kompilator języka programowania OCaml — a z tego języka albo do kodu bajtowego, albo do kod natywny.

Preprocesor ogólnego przeznaczenia

Większość preprocesorów jest specyficzna dla konkretnego zadania przetwarzania danych (np. kompilacja języka C). Preprocesor może być promowany jako przeznaczony do użytku ogólnego , co oznacza, że ​​nie jest przeznaczony do określonego zastosowania lub języka programowania i jest przeznaczony do wykorzystania w wielu różnych zadaniach związanych z przetwarzaniem tekstu.

M4 jest prawdopodobnie najbardziej znanym przykładem takiego preprocesora ogólnego przeznaczenia, chociaż preprocesor C jest czasami używany w roli innej niż C. Przykłady:

  • za pomocą preprocesora C do wstępnego przetwarzania JavaScript .
  • przy użyciu preprocesora C do przetwarzania drzewa urządzeń w jądrze Linuksa .
  • przy użyciu preprocesora M4 (patrz przykład w artykule) lub preprocesora C jako silnika szablonów do generowania HTML .
  • imake , interfejs make używający preprocesora C, napisany dla X Window System, ale teraz przestarzały na rzecz automake .
  • gropp , preprocesor plików wejściowych symulacji dla GROMACS (szybki, darmowy, open-source kod do niektórych problemów w chemii obliczeniowej ), który wywołuje preprocesor systemu C (lub inny preprocesor określony przez plik wejściowy symulacji) do parsowania topologii, używając głównie mechanizmów #define i #include do określenia efektywnej topologii w czasie wykonywania programu gropp.

GPP to uniwersalny preprocesor leksykalny, który przypomina cpp. Między innymi może służyć do wstępnego przetwarzania plików przecen.

Zobacz też

Bibliografia

Zewnętrzne linki