Un preprocesor este un program de calculator care preia și scoate date destinate introducerii de către un alt program (cum ar fi un compilator ). Ieșirea preprocesorului se spune că este într-o formă preprocesată adecvată pentru procesarea de către programele ulterioare (compilator). Rezultatul și tipul prelucrării depind de tipul de preprocesor; de exemplu, unele preprocesoare pot efectua doar înlocuirea simplă a textului, altele sunt capabile de capabilități comparabile cu limbajele de programare. Cea mai comună utilizare a unui preprocesor este procesarea codului sursă înainte de a-l trece la următorul pas de compilare. Limbaje de programare C / C++iar sistemul de layout al computerului TeX utilizează preprocesoare care își extind foarte mult capacitățile.
În unele limbaje de programare, etapele de compilare și traducere se numesc „preprocesare”.
Preprocesoarele lexicale sunt numite preprocesoare de nivel scăzut deoarece necesită doar analiză lexicală , adică procesează doar textul sursă înainte de parsare , pur și simplu înlocuind lexemele și caracterele speciale cu secvențe date de caractere, conform regulilor stabilite de utilizatori. În mod obișnuit, efectuează înlocuirea macrocomenzilor , inserările de text din alte fișiere și compilarea condiționată sau legarea fișierelor.
Cel mai utilizat preprocesor lexical este preprocesorul limbajului C folosit în limbajele de programare C și descendentul său, C++ . Preprocesorul elimină comentariile din cod , transformă codul în conformitate cu macrocomenzi și execută alte directive care încep cu caracterul „#” (cum ar fi #include, #define, diverse directive precum #pragma).
PHP este cel mai frecvent utilizat în procesarea paginilor web . Textul paginii este citit și afișat neschimbat. Singura excepție este prezența instrucțiunilor PHP în corpul paginii, delimitate <?phpla început și ?>la sfârșit.
Un exemplu de text al unei pagini care conține ora curentă:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> < html > < head > < title > Current ora </ title > </ head > < body > < h1 > Ora curentă </ h1 > <?php print strftime('Ora curentă este %H ore, %M minute %S secunde'); ?> </ body > </ html >Preprocesorul PHP va înlocui linia evidențiată cu:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> < html > < head > < title > Current ora </ title > </ head > < body > < h1 > Ora curentă </ h1 > Acum sunt 10 ore, 15 minute și 20 de secunde </ body > </ html >Alte preprocesoare lexicale acceptă limbajul universal m4 , folosit în mod obișnuit în sistemele de compilare multiplatformă, cum ar fi autoconf , și GEMA , un motor macro open source bazat pe șabloane de context .
Preprocesoarele de sintaxă au fost introduse pentru prima dată în familia de limbi Lisp . Rolul lor a fost de a procesa arbori de sintaxă conform unui set de reguli definite de utilizator. Pentru unele limbaje de programare, regulile au fost scrise în același limbaj cu programul însuși (simetrie de compilare). Lisp și OCaml sunt exemple . Unele limbi folosesc un limbaj complet independent pentru a descrie transformările, cum ar fi preprocesorul XSLT pentru XML sau echivalentul acestuia cu tipurile statice CDuce .
Preprocesoarele de sintaxă sunt utilizate în mod obișnuit pentru a rafina sintaxa unui limbaj, pentru a extinde un limbaj prin adăugarea de noi primitive sau pentru a încorpora un limbaj de programare specific domeniului într-un limbaj gazdă.
Un bun exemplu de modificare a sintaxei este existența a două sintaxe diferite [1] în limbajul de programare Objective Caml . Programele pot fi scrise folosind sintaxa obișnuită sau sintaxă fixă , alegerea depinzând de preferințele programatorului.
În mod similar, un set de programe scrise în OCaml are capacitatea de a personaliza sintaxa limbajului prin adăugarea de noi operatori.
Un exemplu excelent de extindere a unui limbaj cu macrocomenzi este utilizarea lor în familia Lisp de limbaje de programare . În timp ce aceste limbaje însele au nuclee simple axate pe tipuri dinamice, livrările standard Scheme , Common Lisp imperatives , programarea orientată pe obiecte sunt axate pe tipuri statice. Aproape toate aceste caracteristici sunt implementate de preprocesoare sintactice, deși aceasta poartă amprenta pasului de compilare „extindere macro” controlat de compilatorul Lisp. Aceasta poate fi considerată în continuare o formă de preprocesare, așa cum se întâmplă înainte de restul pașilor de compilare.
În mod similar, expresii regulate sau generarea de cod sigure pentru tipare pot fi adăugate la sintaxa și semantica OCaml folosind macro-uri, cum ar fi microthread-uri (cunoscute și ca coroutine sau fibre ), monade sau procesare XML transparentă.
Una dintre caracteristicile neobișnuite ale familiei de limbi Lisp este capacitatea de a utiliza macrocomenzi pentru a crea un limbaj de programare încorporat specific domeniului . De obicei, într-un număr mare de proiecte scrise în Lisp, un modul poate fi scris în multe astfel de minilimbaje, adică unul poate folosi dialectul SQL al Lisp, iar altul poate fi scris într-o GUI sau dialect orientat către imprimantă și așa mai departe. Biblioteca standard Common Lisp conține un exemplu de un astfel de nivel de abstractizare sintactică sub forma macro-ului LOOP, care implementează minilimbaje precum Algol pentru a descrie iterația complexă, păstrând în același timp capacitatea de a utiliza operatori standard Lisp.
Preprocesorul/limbajul MetaOCaml oferă capabilități similare cu un limbaj de programare extern specific domeniului . Acest preprocesor, primind o descriere a semanticii limbajului (așa-numita „interpretare”) și combinând interpretarea în timpul compilării și generării codului, transmite această definiție compilatorului limbajului OCaml , care, pe baza acestui limbaj, creează bytecode. sau cod natural.
Preprocesoarele, care efectuează doar una dintre etapele traducerii, sunt concentrate pe sarcina de prelucrare fragmentară a datelor (de exemplu, compilarea limbajului C ). Programele similare, numite atunci macroprocesoare , pot fi de asemenea destinate unor scopuri generale, adică nu sunt destinate să implementeze o anumită utilizare sau limbaj de programare, ci sunt concepute pentru a utiliza o gamă largă de sarcini de prelucrare a datelor.
Macroprocesorul m4 este probabil cel mai cunoscut exemplu de astfel de macroprocesor de uz general.