Preprocesory syntaktyczne zostały wprowadzone wraz z rodziną języków Lisp. Ich zadaniem jest przekształcanie drzew składni zgodnie z pewną liczbą reguł zdefiniowanych przez użytkownika. W przypadku niektórych języków programowania reguły te są zapisane w tym samym języku co program (compile-time reflection). Tak jest w przypadku języków Lisp i OCaml. Niektóre inne języki polegają na całkowicie zewnętrznym języku do definiowania transformacji, takich jak preprocesor XSLT dla XML lub jego statycznie typowany odpowiednik CDuce.

Syntaktyczne preprocesory są zwykle używane do dostosowywania składni języka, rozszerzania języka przez dodawanie nowych prymitywów lub osadzania języka programowania specyficznego dla danej dziedziny (DSL) wewnątrz języka ogólnego przeznaczenia.

Dostosowywanie składniEdit

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 „zmienionej składni” i mogą być ładnie wydrukowane z dowolną z nich na żądanie.

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

Rozszerzanie językaEdit

Najlepsze przykłady rozszerzania języka przez makra można znaleźć w rodzinie języków Lisp. Choć języki te same w sobie są prostymi, dynamicznie typowanymi rdzeniami funkcyjnymi, standardowe dystrybucje Scheme i Common Lisp pozwalają na programowanie imperatywne lub obiektowe, a także na statyczne typowanie. Prawie wszystkie te cechy są implementowane przez preprocessing składniowy, choć warto zauważyć, że w Lispie faza kompilacji „ekspansji makr” jest obsługiwana przez kompilator. To wciąż może być uważane za formę przetwarzania wstępnego, ponieważ ma miejsce przed innymi fazami kompilacji.

Specjalizowanie językaEdit

Jedną z niezwykłych cech rodziny języków Lisp jest możliwość używania makr do tworzenia wewnętrznego DSL. Zazwyczaj, w dużym projekcie opartym na Lispie, moduł może być napisany w wielu takich minil językach, jeden może używać dialektu Lispa opartego na SQL, inny dialektu wyspecjalizowanego do GUI lub ładnego drukowania, itd. Biblioteka standardowa Common Lispa zawiera przykład takiego poziomu abstrakcji składniowej w postaci makra LOOP, które implementuje podobny do Algola minilanguage do opisu złożonej iteracji, jednocześnie umożliwiając użycie standardowych operatorów Lispa.

Preprocesor/język MetaOCaml dostarcza podobnych cech dla zewnętrznych DSL. Ten preprocesor bierze opis semantyki języka (tj. interpreter) i, łącząc interpretację w czasie kompilacji i generowanie kodu, przekształca tę definicję w kompilator do języka programowania OCaml – i z tego języka, albo do kodu bajtowego, albo do kodu natywnego.

.

admin

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.

lg