Compilarea este un proces care facilitează comunicarea între programator și computer. Cum funcționează compilatorul

Una dintre caracteristicile cheie ale PHP este că este un limbaj de programare interpretat. Pe de altă parte, limbajele de programare precum C au fost concepute inițial pentru a fi compilate. Ce înseamnă?

Faptul că un limbaj de programare este compilat sau interpretat nu depinde cu adevărat de natura limbajului de programare. Orice limbaj de programare poate fi interpretat de un așa-numit interpret sau compilat folosind un așa-numit compilator.

Ciclul de lucru al programului

Când utilizați orice limbaj de programare, există un anumit flux de lucru pentru crearea codului. Îl scrieți, îl rulați, găsiți erori și îl depanați. Astfel, rescrieți și adăugați la program, verificați. Despre ce va vorbi acest articol este partea „rulării” a programului.

Când scrieți un program, doriți ca instrucțiunile acestuia să ruleze pe computer. Un computer procesează informații folosind un procesor care execută instrucțiuni codificate în format binar în etape. Ca și în expresia „a = 3; » obțineți instrucțiuni codificate pe care procesorul le poate înțelege?

Facem acest lucru folosind compilarea. Există aplicatii speciale, cunoscut sub numele de compilatoare. Acceptă programul pe care l-ai scris. Apoi analizează și dezasambla fiecare parte a programului și construiesc codul mașinii pentru procesor. Este adesea numit și cod obiect.

La o etapă a procesului de procesare, se folosește un linker care preia părți ale programului care au fost convertite separat în cod obiect și le leagă într-unul singur. fișier executabil. Iată o diagramă care descrie acest proces:

Elementul final al acestui proces este fișierul executabil. Când rulați sau spuneți computerului că este un fișier executabil, acesta ia prima instrucțiune de la acesta, nu filtrează, nu convertește, dar rulează imediat programul și îl execută fără nicio conversie suplimentară. Acest caracteristica cheie proces de compilare - rezultatul acestuia trebuie să fie un fișier executabil care nu necesită traducere suplimentară, astfel încât procesorul să poată începe să execute prima instrucțiune și toate următoarele.

Primele compilatoare au fost scrise direct prin codul mașinii sau folosind asambleri. Dar scopul compilatorului este evident: să traducă programul în cod de mașină executabil pentru un anumit procesor.

Unele limbaje de programare au fost concepute având în vedere compilarea. C, de exemplu, a fost menit să permită programatorilor să implementeze lucrurile cu ușurință. Dar în cele din urmă a fost proiectat în așa fel încât să poată fi tradus cu ușurință în codul mașinii. Compilarea în programare este serioasă!

Nu toate limbajele de programare iau în considerare acest lucru în conceptul lor. De exemplu, Java a fost destinat să ruleze în " interpretativ» și Python trebuie întotdeauna interpretat.

Interpretarea programului

O alternativă la compilare este interpretarea. Principala diferență dintre un compilator și un interpret este modul în care funcționează. Compilatorul preia întregul program și îl convertește în cod de mașină pe care procesorul îl poate înțelege.

Un interpret este un fișier executabil care citește un program pas cu pas și apoi îl procesează, executând imediat instrucțiunile acestuia.

Cu alte cuvinte, interpretul execută programul pas cu pas ca parte a propriului fișier executabil. Codul obiect nu este transmis procesorului; interpretul în sine este cod obiect, construit în așa fel încât să poată fi apelat la un moment dat.

Acest lucru întrerupe ciclul de lucru care a fost prezentat în diagrama de mai sus. Acum avem o nouă diagramă:


Aici vedem că, spre deosebire de compilator, interpretul trebuie să fie întotdeauna la îndemână, astfel încât să-l putem apela și să rulăm programul nostru. Într-un fel, interpretul devine procesorul. Programele scrise pentru a fi interpretate sunt numite „scripturi” deoarece sunt scripturi de acțiune pentru un alt program, mai degrabă decât cod direct de mașină.

De exemplu, așa funcționează limbaje de programare precum Python. Tu scrii un program. Apoi introduceți codul în interpretul Python și acesta va efectua toți pașii pe care i-ați descris. ÎN linie de comandă poti introduce ceva de genul:

C:>python myprogram.py

În această comandă, Python este fișierul executabil. Îl alimentezi cu orice se află în fișierul myprogram.py și execută acele instrucțiuni. Computerul nu va rula myprogram.py fără Python. Acesta nu este un cod de mașină pe care procesorul îl înțelege. Puteți compila programe Python în cod obiect sau mașină și îl puteți rula direct pe procesor. Dar această procedură implică compilarea codului și adăugarea întregului interpret Python ca parte a acestuia.

Natura interpretului

Interpreții pot fi creați în diferite moduri. Există interpreți care citesc programul sursă și nu se execută prelucrare suplimentară. Pur și simplu iau un anumit număr de linii de cod odată și îl execută.

Unii interpreți își fac propria compilare, dar de obicei convertesc programul în cod octet, care are sens doar pentru interpret. Acesta este un fel de limbaj pseudo-mașină pe care doar interpretul îl înțelege.

Un astfel de cod este procesat mai rapid și este mai ușor de scris pentru executant ( parte a interpretului care execută), care citește codul octet mai degrabă decât codul sursă.

Există interpreți pentru care acest tip de cod de octet este mai important. De exemplu, limbajul Programare Java„rulează” pe o așa-numită mașină virtuală. Este un cod executabil sau o parte dintr-un program care citește un anumit cod octet și emulează funcționarea procesorului. Prin procesarea codului octet ca și cum procesorul computerului ar fi un procesor virtual.

Am un emulator pt consola de jocuri Nintendo. Când încarc un fișier ROM Dragon Warrior, acesta este formatat într-un cod de mașină pe care doar procesorul NES îl poate înțelege. Dar dacă creez un procesor virtual care interpretează codul octet în timp ce rulează pe alt procesor, pot rula Dragon Warrior pe orice mașină cu un emulator.

Aceasta folosește conceptul de compilare Java, precum și toți interpreții. Orice procesor pentru care pot crea un interpret/emulator poate rula programele mele interpretate/codul octet. Acesta este principalul avantaj al interpretului față de compilator.

Argumente pro şi contra

Principalul argument pentru utilizarea procesului de compilare este viteza. Abilitatea de a compila orice codul programuluiîntr-un limbaj de mașină pe care procesorul PC-ului îl poate înțelege, eliminând utilizarea codului intermediar. Puteți rula programe fără pași suplimentari, crescând astfel viteza de procesare a codului.

Dar cel mai mare dezavantaj al compilației este specificitatea. Când compilați un program pentru a rula pe un anumit procesor, creați cod obiect care va rula doar pe acel procesor. Dacă doriți ca programul să ruleze pe o altă mașină, va trebui să recompilați programul pentru acel procesor. Și recompilarea poate fi destul de dificilă dacă procesorul are limitări sau caracteristici care nu sunt inerente primului. De asemenea, poate provoca erori de compilare.

Principalul avantaj al interpretării este flexibilitatea. Nu numai că puteți rula un program interpretat pe orice procesor sau platformă pentru care a fost compilat interpretul. Un interpret scris poate oferi o flexibilitate suplimentară. Într-un fel, interpreții sunt mai ușor de înțeles și de scris decât compilatorii.

Folosirea unui interpret este mai ușor să adăugați funcționalități suplimentare, să implementați lucruri precum colectorii de gunoi, mai degrabă decât să extindeți limbajul.

Un alt avantaj al interpreților este că sunt mai ușor de rescris sau recompilat pentru platforme noi.

Scrierea unui compilator pentru un procesor necesită adăugarea multor funcții sau reelaborarea completă a acestuia. Dar odată ce compilatorul este scris, puteți compila o grămadă de interpreți, iar rezultatul este un limbaj promițător. Nu este nevoie să reimplementați interpretul la nivelul de bază pentru un procesor diferit.

Cel mai mare dezavantaj al interpreților este viteza. Pentru fiecare program sunt efectuate atât de multe traduceri și filtrare încât încetinește munca și interferează cu execuția codului programului.

Aceasta este o problemă pentru aplicații specifice în timp real, cum ar fi jocurile de înaltă rezoluție și jocurile de simulare. Unele interprete conțin componente numite compilatoare just-in-time ( JIT). Ei compilează programul imediat înainte de a-l executa. Acest programe speciale, luate în afara sferei de aplicare a interpretului. Dar pe măsură ce procesoarele devin mai puternice, această problemă devine mai puțin relevantă.

Concluzie

Rețineți întotdeauna că unele limbaje de programare sunt concepute special pentru compilarea codului, cum ar fi C. În timp ce alte limbi trebuie întotdeauna interpretate, cum ar fi Java.

Pentru mine, nu contează dacă ceva este compilat sau interpretat atâta timp cât poate îndeplini sarcina eficient.

Unele sisteme nu oferă specificatii tehnice Pentru utilizare eficientă interpreți. Deci, trebuie să le programați folosind ceva care poate fi compilat direct, cum ar fi C. Uneori trebuie să efectuați calcule cât mai intens posibil. De exemplu, cu recunoașterea vocală precisă de către un robot. În alte cazuri, viteza sau putere de calcul poate să nu fie la fel de critic, iar scrierea unui emulator în limba originală poate fi mai ușoară.

Informatică, cibernetică și programare

Compilare Un program reprezentat ca comenzi într-un limbaj de programare se numește program sursă. Constă în instrucțiuni care sunt înțelese de oameni, dar nu sunt înțelese de procesorul computerului. Pentru ca procesorul să lucreze în conformitate cu instrucțiunile...

Compilare

Se numește un program prezentat sub formă de comenzi în limbaj de programareprogramul original. Constă în instrucțiuni care sunt înțelese de oameni, dar nu sunt înțelese de procesorul computerului. Pentru ca procesorul să poată lucra înconform instructiunilor programul original, programul sursă trebuie tradus în limbajul de comandă al procesorului în limbajul mașinii. Sarcina de a converti programul sursă în cod mașină este realizată de un program special compilator

Executabil

Program

programul original

Compilator

Controlul sintactic al textului programului

Mașină generatoare

cod

mesaje despre

greșeli

Orez. 1.1. Diagrama de funcționare a compilatorului

Compilatorul, a cărui diagramă de funcționare este prezentată în Fig. 1.1, efectuează două sarcini succesiv:

  1. Verifică textul programului sursă pentru lipsă erori de sintaxă.
  2. Creează (generează) un cod de mașină de program executabil.

Trebuie menționat că generația program executabil apare numai dacă nu există erori de sintaxă în textul programului sursă, adică programul este scris corect din punct de vedere al regulilor a acestei limbi programare.

Generarea codului mașină de către compilator indică doar că nu există erori de sintaxă în textul programului. Vă puteți asigura că programul funcționează corect numai în procesul de testare a programului și de a analiza rezultatele.

De exemplu, dacă într-un program pentru calcularea rădăcinilor unei ecuații pătratice se comite o eroare în expresia (formula) pentru calcularea discriminantului, atunci, chiar dacă această expresie este corectă din punct de vedere sintactic, programul va produce valori incorecte ale rădăcinii.


Precum și alte lucrări care te-ar putea interesa

75959. 20,83 KB
Guvern Federația Rusă. Puterea executivă a Federației Ruse este exercitată de Guvernul Federației Ruse. Guvernul Federației Ruse este format din Președintele Guvernului Federației Ruse, Vicepreședintele Guvernului Federației Ruse și miniștri federali. Președintele Guvernului Federației Ruse este numit de Președintele Federației Ruse cu acordul Dumei de Stat.
75960. Formarea parlamentarismului rus modern. Alegerile Duma din 1993 și 1995: analiză comparativă 22,11 KB
Sistemul comunist, înființat în 1917, a întrerupt formarea instituțiilor democratice în țara noastră timp de 70 de ani și a oprit dezvoltarea parlamentarismului. Și totuși, germenii democrației politice și ai parlamentarismului nu au fost complet eradicați...
75961. Formarea „grupurilor oligarhice”, evoluția relațiilor lor cu statul din Rusia 26,8 KB
Acum înseamnă un grup restrâns de magnați financiari, cei opt sau șapte baroni ai băncilor, care au relații strânse cu și influențează președintele și guvernul. Termenul de oligarhie maschează o parte din stângăcia situației reale: dominația unui număr mic de grupuri financiare printr-o relație simbiotică cu administrația prezidențială. Având în vedere rolul politic al grupurilor financiare în sistemul Elțîn și fazele dezvoltării acestora, se poate observa că din cauza slăbiciunii organelor puterii reprezentative și...
75962. Trăsăturile caracteristice ale formării unei economii de piață în Federația Rusă 19,88 KB
Caracteristicile formării unei economii de piață în Rusia: economistul intern A. Smirnov privind ponderea proprietății private în economia rusă în 1914. În Rusia, chiar și în perioada de creștere industrială din 1909-1913. Cota Rusiei în producția industrială globală a crescut semnificativ în ajunul Primului Război Mondial, a ocupat locul cinci în lume după Statele Unite, Germania, Anglia, Franța.
75963. Evoluția sistemului de partid-politic al Federației Ruse la începutul secolului XXI 18,23 KB
O creștere bruscă a numărului de partide. În același timp, nu mai mult de cinci sau șase partide au avut o influență reală asupra procesului politic, inclusiv asupra activității legislative. După cum a arătat practica campaniilor electorale, multe partide au fost create inițial în scopuri tehnologice pur politice
75964. Acordurile Belovezhskaya - sens istoric și probleme discutabile 19,6 KB
ACORDUL BELOVEZHA este un termen folosit pentru a se referi la acordul semnat la 8 decembrie 1991 de liderii de vârf ai Rusiei, Belarusului și Ucrainei privind dizolvarea URSS și formarea Comunității Statelor Independente a CSI. Semnificație: După încercarea Comitetului de Stat de Urgență din august 1991, puterea reală a trecut în mâinile elitelor guvernamentale republicane și a președintelui URSS M., iar pe 5 decembrie, Kravciuk a anunțat că Ucraina va denunța tratatul din 1922 privind crearea URSS. Apoi Kravchuk Elțin și Shushkevich s-au adunat la Belovezhskaya Pushcha pentru a rezolva problema conservării URSS.
75965. Declarația de suveranitate de stat a RSFSR - condiții de adoptare și sens istoric 17,91 KB
Declarația de suveranitate de stat a RSFSR este un act politic și juridic care a marcat începutul reformei constituționale în RSFSR, în care suveranitatea este considerată naturală și naturală. conditie necesara existența statalității ruse. Condiții: Declarația a fost adoptată de Primul Congres al Deputaților Poporului al RSFSR la 12 iunie 1990 și semnată de Președintele Consiliului Suprem al RSFSR B. Semnificație semnificație istorică: Pe lângă proclamarea suveranității RSFSR și intenția de a crea un stat juridic democratic ca parte a unei Uniri reînnoite...
75966. Terapia cu șoc și consecințele sale istorice 53 KB
Terapia de șoc este un nume de propagandă (ziar), cu mana usoara unii publiciști au fost lipiți de politica pe care a început să o ducă guvernul reformist din Elțîn-Gaidar când a ajuns la putere - politica de stabilizare a economiei. (Încercarea Rusiei de a trece la o economie de piață)

Note generale despre interpreți

Dezvoltarea interpreților pentru a interpreta programe într-o anumită limbă sursă este una dintre sarcinile principale ale informaticii. Gradul de dificultate al problemei de implementare a interpretului depinde de complexitatea limbii sursă și de gradul de diferență a acesteia față de limba de bază în care interpretul însuși trebuie să fie scris.

Pentru a asigura corectitudinea interpretului, la proiectarea lui, trebuie să pornim de la definirea semantică a limbajului interpretat, sau cel puțin să o verificăm față de aceasta. Să acordăm atenție faptului că definiția matematică a semanticii unei limbi este similară cu programele interpretative.

Un post special este ocupat de interpreți interactivi, incrementali (pas cu pas). Ele nu necesită neapărat pregătirea mai întâi a întregului program, inclusiv datele de intrare și abia apoi interpretarea acestuia. Cu interpretarea interactivă, programul și datele de intrare pot fi pregătite în părți separate, iar partea rezultată - pe cât posibil - poate fi interpretată imediat (limbajul BASIC este special orientat spre interpretarea incrementală).

Acum ne apropiem de crearea de interpreți pentru limbi care arată diferit de limbile clasice orientate spre calcul. În special, ca urmare a cercetărilor pe termen lung, a devenit posibilă interpretarea anumitor limbaje care sunt orientate mai degrabă către specificații decât către calcule (de exemplu, limbajul PROLOG, care este folosit pentru alcătuirea programelor în logica interpretabilă de mașină). ). Cu toate acestea, pentru astfel de limbi există anumite bariere insurmontabile din cauza limitelor de calculabilitate și complexitate, care pentru multe enunțuri de problemă fac ca utilizarea acestor limbi să fie aproape imposibilă.

Compilator ia ca intrare un program în limbajul sursă și produce un program într-un limbaj obiect pe care mașina îl poate înțelege.

Dacă un program scris în PL nivel înalt, vrem să executăm în mod repetat, cu date inițiale noi, se întâmplă adesea program mai eficient nu interpreta, ci mai întâi traduce într-o limbă deja implementată, eventual mai apropiată limbajul mașinii, iar apoi executați programul generat în acest fel. Această metodă face posibilă adaptarea mai bună a programului la structura mașinii efectiv utilizate și, astfel, obținerea unei optimizări de anvergură. În principiu, o astfel de traducere se poate face manual, dar acest lucru necesită timp și pot apărea erori. Prin urmare, programe speciale de traducere numite traducători sau compilatoare(calculator englez).



Compilatorul și interpretul sunt de obicei destul de buni programe complexe, care percep un program în limba sursă sub formă de text, stabilesc structura internă a unui astfel de program dat, verificându-i corectitudinea sintactică (parsing) și traduc programul într-un alt limbaj (obiect) sau execută acest program prin acțiuni adecvate .

Un limbaj este determinat de sintaxa și semantica sa. În procesul de compilare sau interpretare, un program, înțeles ca obiect sintactic, este luat ca intrare și, conform semanticii sale, este transformat într-un program într-un alt limbaj sau într-o succesiune de acțiuni (proces de execuție).

Limbajele de programare vin la niveluri înalte și scăzute.

Direcționarea limbilor tip specific procesor și caracteristicile sale sunt numite limbi nivel scăzut. Fiecare instrucțiune de limbaj de nivel scăzut implementează direct o instrucțiune de microprocesor și sunt întotdeauna orientate către setul de instrucțiuni al unui microprocesor specific. Limbajul de cel mai jos nivel este limbajul de asamblare, care reprezintă pur și simplu fiecare instrucțiune de cod de mașină, nu ca numere, ci folosind simboluri simboluri, numite mnemonice.

Limbi nivel înalt vă permit să setați acțiunile doriteîn program folosind un anumit set operatori. Sunt mult mai aproape și mai ușor de înțeles de o persoană decât de un computer. Fiecare comandă a unui astfel de limbaj poate consta dintr-o duzină sau mai multe comenzi de microprocesor. Este mai ușor să scrieți programe într-o limbă străină.


1 – dependent de mașină (Asamblator). Limbi de nivel scăzut.

2 – orientat către mașină (C)

3 – universal (Fortran, Pascal, Basic)

4 - orientat pe probleme (GPSS, Logo, orientat pe obiecte (fort, Smalltalk))

5,6,7 – (Prolog, Lisp, SNOBALL).

C, C++ - întreaga parte a programului dependentă de mașină este destul de ușor localizată și modificată la transferul programului într-o altă arhitectură.

Fortran – primul limbaj de nivel înalt (1958, IBM), folosit și astăzi, suportă programarea modulară, preferată în special de matematicieni.

Pascal – una dintre cele mai populare în scopuri educaționale (N. Wirth), implementează majoritatea ideilor de programare structurată.

DE BAZĂ – pentru programatorii începători, aproape de conversație Limba engleză, acceptă programarea modulară și structurată.

Logo , printre limbile orientate spre probleme, este folosit în principal în scopuri didactice. Este un limbaj procedural conversațional (sintaxă simplă).

GPSS – concentrat pe modelarea sistemelor folosind evenimente. Este folosit în cazul în care rezultatele cercetării sunt exprimate în termeni de timp de așteptare, lungimea cozii, utilizarea resurselor.

Vorbe mici – unul dintre primele OO PL, designul principal este un obiect și acțiuni cu acesta, destinate sarcinilor nenumerice (la construirea sistemelor de inteligență artificială).

Fort – utilizat în rezolvarea problemelor de simulare în sisteme grafice.

Limbaje de grup funcționale utilizat în principal în sistemele de inteligență artificială. Au un suport puternic pentru instrumente, un compilator rapid, instrumente de organizare încorporate modul cu mai multe ferestre, grafică rezoluție înaltă, un set dezvoltat de funcții matematice.

Prolog – se dau limbajul AI, termenii și conexiunile, iar cu ajutorul lui se creează altele noi.

Lisp – are modele grafice puternice, vă permite să creați programe de proiectare (piese, de exemplu). Este axat pe activități de proiectare. Are o bibliotecă de primitive.

SNOBAL – limbajul AI.

Generații de limbaje de programare

Toate limbajele de programare sunt de obicei împărțite în 5 generații.

1. Începutul anilor 50. Au apărut primele computere și primele limbaje de asamblare, în care programarea a fost efectuată conform principiului „O singură instrucțiune - o linie”.

2. Sfârșitul anilor 50 începutul anilor 60. A fost dezvoltat un asamblator simbolic, în care a apărut conceptul de variabilă. Viteza de dezvoltare și fiabilitatea programelor a crescut.

3. anii 60. Nașterea limbilor de nivel înalt. Ușurință de programare, independență față de un anumit computer, noi construcții de limbaj puternice.

4. De la începutul anilor 70 până în prezent. Limbi orientate spre probleme care operează cu concepte specifice de îngust domeniul subiectului. Operatori puternici care necesitau mii de linii de cod sursă în limbi de generație inferioară.

5. Mijlocul anilor 90. Sisteme crearea automată programe de aplicație prin folosire ajutoare vizuale dezvoltare, fără cunoștințe de programare. Instrucțiunile sunt introduse în computer într-o formă vizuală folosind metode care sunt cele mai convenabile pentru o persoană care nu este familiarizată cu programarea.

La institutul nostru în diferite cursuri vei învăța să programezi în diverse limbi programare.

Compilator(din engleză Compile - adunați împreună, compuneți) - program de sistem, care transformă un program scris într-un limbaj algoritmic într-un program într-un limbaj apropiat de limbajul mașină, și într-un anumit sens echivalent cu primul.
Compilatoarele sunt scrise atât în ​​codare automată, cât și în limbaje de nivel înalt. În plus, există limbi speciale proiectarea compilatoarelor - compilatoare de compilatoare.
Compiler Compiler (CC) - un sistem care vă permite să generați compilatoare; intrarea sistemului este un set de gramatici, iar ieșirea, în mod ideal, este un program. Uneori, CC este înțeles ca un limbaj de programare în care programul sursă este o descriere a compilatorului unui anumit limbaj, iar programul obiect este compilatorul însuși pentru acest limbaj. Programul original QC este pur și simplu un formalism folosit pentru a descrie compilatorii, care conține, explicit sau implicit, o descriere a lexicale și analizarea tori, generator de cod și alte părți ale compilatorului creat. De obicei, QC utilizează o implementare a așa-numitei scheme. traducere controlată sintactic. În plus, unele dintre ele sunt limbaje speciale de nivel înalt în care este convenabil să descrieți algoritmii utilizați pentru a crea compilatoare.

Istoria compilatoarelor
Primele compilatoare au apărut la începutul anilor 1950. Astăzi este dificil de determinat când a apărut primul compilator, deoarece multe experimente și dezvoltări au fost efectuate în acei ani de către diferite grupuri independente. Practic, scopul dezvoltării primelor compilatoare a fost de a converti formulele aritmetice în cod mașină.

Anul nașterii teoriei compilatorilor poate fi considerat 1957, când a apărut primul compilator de limbaj Fortran, creat de Backus, care a furnizat un cod obiect destul de eficient. A rulat pe platformele IBM 7040, IBM 360 și DEC PDP-11. În 1980 a fost dezvoltat noua versiune pentru IBM 360 și IBM PC, care a susținut standardul FORTRAN 77 Un an mai târziu, s-a format Watcom, care a introdus compilatorul C în 1988. A câștigat imediat o mare popularitate în rândul programatorilor, deoarece a generat cel mai mult. cod rapid printre compilatorii de atunci.

Bazele
Majoritatea compilatoarelor traduc un program dintr-un limbaj de programare de nivel înalt în cod de mașină care poate fi executat direct procesor central. De regulă, acest cod trebuie să fie executat și în mediul unui anumit sistem de operare, deoarece folosește capabilitățile oferite de acesta (apeluri de sistem, biblioteci de funcții). Arhitectura (set de software și hardware) pentru care se realizează compilarea se numește mașina țintă.
Unele compilatoare (de exemplu, Java) traduc programul nu în cod de mașină, ci într-un program într-un limbaj special creat de nivel scăzut. Un astfel de limbaj - bytecode - poate fi considerat și un limbaj de instrucțiuni de mașină, deoarece este supus interpretării mașină virtuală. De exemplu, pentru limbajul Java acesta este JVM (Java Virtual Machine Language), sau așa-numitul bytecode Java (după care toate limbajele intermediare de nivel scăzut au început să fie numite bytecodes). Pentru limbaje de programare bazate pe .NET Framework (C#, C++ gestionat, Visual Basic.NET și altele) este MSIL (Microsoft Intermediate Language).

Un program bytecode este supus interpretării de către o mașină virtuală sau o altă compilare în codul mașinii imediat înainte de execuție. Acesta din urmă se numește „Just-In-Time compilation” (JIT), după numele unui compilator similar pentru Java. Codul MSIL este, de asemenea, compilat în codul mașinii țintă de către un compilator JIT, iar bibliotecile .NET Framework sunt compilate în avans).
Pentru fiecare mașină țintă (IBM, Apple etc.) și fiecare sistem de operare sau familie sisteme de operare rulând pe mașina țintă, trebuie să vă scrieți propriul compilator. Există, de asemenea, așa-numitele compilatoare încrucișate care vă permit să obțineți cod pe o mașină și într-un mediu OS care este destinat să fie executat pe o altă mașină țintă și/sau într-un alt mediu OS. În plus, compilatoarele pot fi optimizate pentru diferite tipuri procesoare din aceeași familie (prin folosirea instrucțiunilor specifice acestor procesoare). De exemplu, codul compilat pentru procesoarele din familia i686 poate folosi seturi de instrucțiuni specifice acestor procesoare - MMX, SSE, SSE2.
Există programe care rezolvă problema inversă - traducerea unui program dintr-un limbaj de nivel scăzut într-unul de nivel înalt. Acest proces se numește decompilare, iar programele se numesc decompilatoare. Dar, deoarece compilarea este un proces cu pierderi, este imposibil să reconstruiți cu exactitate codul sursă în, de exemplu, C++ în caz general imposibil. Programele în bytecodes sunt decompilate mai eficient - de exemplu, există un decompilator destul de fiabil pentru Flash.

Structura logică compilator

  1. Analiza lexicala. Analizatorul lexical recunoaște simbolurile de limbă și le înlocuiește cu coduri corespunzătoare. Lexemele sunt înțelese ca unități elementare incluse în structura unei propoziții de limbă, cum ar fi cuvinte cheie, constante, nume etc. Corectitudinea stabilirii structurii de propoziție a limbii la faza de analiză lexicală nu este îndeplinită. Rezultatul este un flux de lexeme (coduri - link-uri către tabele) echivalent cu textul sursă.
  2. Este necesar un parser pentru a determina dacă propozițiile care alcătuiesc programul sursă îndeplinesc regulile gramaticii limbii. Procesul de analizare poate fi considerat ca construirea unui copac analiza gramaticală pentru oferte de difuzare. Gramaticile pot fi folosite atât pentru a genera, cât și pentru a recunoaște propoziții într-o limbă. Generația începe cu concept initial(sau axiome ale gramaticii). Când este recunoscut folosind reguli gramaticale este generată o propoziție, care este apoi comparată cu șirul de intrare. În acest caz, aplicarea regulilor de substituție pentru a genera următorul caracter al unei propoziții depinde de rezultatele comparării caracterelor anterioare cu caracterele corespunzătoare ale șirului de intrare. Este convenabil să reprezinte rezultatul analizei propoziției originale în termeni de construcții gramaticale sub formă de arbore. Astfel de arbori sunt de obicei numiți arbori de analiză sau arbori de sintaxă. CITEȘTE(VALOARE).
  3. Analiza semantică. În această etapă, se verifică tipul și aspectul tuturor identificatorilor și altor operanzi.
  4. Optimizare. Programul original este convertit într-o formă de notație intermediară (de exemplu, poloneză). Optimizarea codului intermediar - extragerea subexpresiilor comune si evaluarea subexpresiilor constante. Faza de optimizare este concepută pentru a reduce redundanța programului în termeni de timp și memorie. În funcție de criteriile de proiectare ale traducătorului, această fază a procesării programului poate fi exclusă din ciclul de procesare a programului.
  5. Alocarea memoriei. În această etapă, adresele de utilizator specifice sunt alocate pentru variabilele care sunt generate de compilator.
  6. Generator de cod obiect (asambler) - efectuează înlocuirea mostrelor de cod în limbajul de ieșire corespunzător codurilor de program intermediare. Este posibil ca generatorul de cod să nu necesite șabloane; totul poate fi implementat procedural.
  7. Compilare dependentă de mașină. Depinde ce registre sunt folosite. Funcționarea acestei proceduri depinde de convențiile adoptate pentru partea executabilă a programului. De exemplu, este alocat registrul de bază pentru intrarea activă în prezent pe stivă. În implementările specifice ale compilatorului, aceste etape pot fi separate sau combinate într-o formă sau alta.
Traducător
Un translator este un program care traduce un program sursă într-unul echivalent program obiect. Dacă limbaj obiect este codare automată sau un limbaj de mașină, atunci traducătorul se numește compilator.

Autocode este foarte aproape de limbajul mașinii; Majoritatea comenzilor de codificare automată sunt reprezentări simbolice exacte ale comenzilor mașinii.

Important caracteristică istorică Caracteristica principală a compilatorului a fost că putea realiza și legături (adică conținea două părți - un traducător și un linker). Acest lucru se datorează faptului că compilarea și legarea separată ca o etapă de asamblare separată au apărut mult mai târziu decât apariția compilatoarelor, iar multe compilatoare populare (de exemplu, GCC) sunt încă combinate fizic cu linkerii lor. În acest sens, în locul termenului „compilator”, termenul „traducător” este uneori folosit ca sinonim: fie în literatura veche, fie atunci când doresc să sublinieze capacitatea acestuia de a traduce un program în codul mașinii (și invers, termenul „compilator” este folosit pentru a sublinia capacitatea de a compila din mai multe fișiere unul).

Exemple de compilator
GCC
Compilator Pascal gratuit
Compilatoare C, C++ și Fortran de la Sun Microsystems Inc.
Compilatorul Watcom Fortran/C++
Compilatorul Intel C++/Fortran
ICC AVR.

Literatură:
1. Alfred Aho, Ravi Sethi, Jeffrey Ullman, „Compilatorii. Principii, tehnologii, instrumente”, „Williams”, M.-S.-Pb.-K. 2003
2. Karpov V.E. „Teoria clasică a compilatorilor”, Tutorial- Institutul de Stat de Electronică și Matematică din Moscova, M., 2003
3. Robin Hunter „Conceptele de bază ale compilatorilor” M.: „Williams”, 2002
4. Hunter R. Proiectare și construcție de compilatoare: Trad. din engleză S. M. Krugovoy - M. Finanțe și Statistică, 1984

Când creează un program specific în etapa finală, orice programator trebuie să apeleze la serviciile unui compilator. ÎN documentatia tehnica acestui program i se dă o definiție destul de modestă ca un utilitar care realizează compilarea. Compilarea este procesul de transformare a unui program scris într-un limbaj care poate fi citit de om (limbaj de nivel înalt) în comenzi care pot fi înțelese de o mașină (limbaj de nivel scăzut). Ca rezultat, obținem un program care este aproape. Poate arăta ca un modul obiect, cod absolut. Uneori un astfel de program arată ca

Astfel, compilarea este atunci când informația de intrare (codul sursă), reprezentând o descriere a unui algoritm sau a unui program scris într-un limbaj orientat către probleme, este rescrisă într-o listă echivalentă de comenzi reprezentate în codul obiect (limbaj orientat pe mașină).

Pentru a simplifica și mai mult definiția, compilarea înseamnă traducerea unui program de mașină dintr-un limbaj orientat spre probleme într-un limbaj orientat către mașină.

În ciuda transparenței și simplității definiției, compilarea este un proces destul de multifațetat. Există mai multe tipuri. Compilarea loturilor este efectuată pe mai multe module sursă la un punct de lucru. Compilarea rând cu linie este aceeași cu interpretarea (compilarea independentă pas cu pas a fiecărei instrucțiuni ulterioare). Există și compilare condiționată. În acest caz, textul tradus depinde de condițiile care sunt specificate în programul sursă prin directivele compilatorului.

Schimbând valoarea unei anumite constante, puteți controla dacă traducerea unei părți a textului programului este activată sau dezactivată.

Pentru comoditatea programatorilor atunci când rezolvă diverse sarcini Sunt utilizate cele mai convenabile și adaptate compilatoare. Dacă le clasificăm, putem distinge mai multe tipuri de astfel de utilități.

Compilatorul de vectorizare traduce codul sursă în cod mașină codul computerului, adaptându-se la procesoare vectoriale.

Compilatorul flexibil a fost dezvoltat pe baza principiul modular. Este gestionat de tabele. Este programat pentru limbaj de nivel înalt. De asemenea, este posibil să-l implementați folosind un compilator de compilatoare.

Un compilator incremental retraduce fragmentele de program și completările la acesta, în timp ce recompilarea întregului program este exclusă.

Un compilator interpretativ sau pas cu pas folosește principiul realizării secvenţiale de compilare independentă pentru fiecare instrucţiune sau instrucţiune din programul sursă.

care percepe descriere formală pentru un limbaj de programare. Este capabil să genereze independent un compilator pentru limbaj specific.

Compilatorul de depanare poate corecta în mod independent unele tipuri de erori de sintaxă.

Compilatorului rezident i se alocă un loc permanent în RAM, și este disponibil la reutilizare o gamă largă de sarcini.

Există compilatoare autocompilabile. Sunt scrise în aceeași limbă din care are loc difuzarea.

Un compilator universal se bazează pe o descriere formală a semanticii și sintaxei limbajului de intrare. Este format dintr-un nucleu, încărcătoare sintactice și semantice.

Cea mai comună sarcină în care se folosesc compilatoarele este compilarea nucleului pentru platforma Linux. Această operațiune vă permite să rezolvați o gamă largă de probleme asociate cu coordonarea echipamentelor și configurarea celei mai adecvate versiuni a platformei.

Compilarea Java este implementată folosind compilatoare care rulează cel mai mult diverse platforme. Acest lucru permite codurile sursă recompilați pentru a se potrivi nevoilor sistemelor de operare de la diferiți producători.