Kompajler je softverski alat koji se koristi za prevođenje izvornog koda napisanog na nekom programskom jeziku u izvršni kod koji može biti izvršen na računaru. Ovo je proces koji obuhvata nekoliko faza, uključujući leksičku analizu, sintaksnu analizu i semantičku analizu izvornog koda. Kompajler zatim generiše izvršni kôd koji je spreman za izvršavanje. Iako se može koristiti jednostavan jezik za objašnjavanje kompajlera, razumevanje njegovog rada i procesa prevođenja može biti od suštinske važnosti za softver inženjere i programere koji kodiraju softver. Zato smo ovu temu odvojili od prethodnog posta, pogledajte ovde; i dali mu poseban značaj. Prvo dobro pitanje koje bi ste verovatno imali za mene jeste, u kom programu je napisan kompajler za C programski jezik? Ukoliko se vratimo malo u istoriju, mi znamo da su stariji računari uglavnom koristili asemblerski jezik, dok su viši programski jezici počeli da se razvijaju kada su se prednosti ponovnog korišćenja softvera na različitim procesorima povećale. Prvi viši programski jezik, Plankalkül, je predložen još 1943. godine. Od tada, razvijeno je nekoliko eksperimentalnih kompajlera. Fortran-ov tim, predvođen John Backus -om iz IBM-a, predstavio je prvi kompletni kompajler 1957 godine. Od tada kompajleri su postajali sve složeniji kako su se računarske arhitekture razvijale. Danas je uobičajena praksa implementirati kompajlere u istom jeziku koji se kompajlira. Zato se pretpostavlja da je kompajler C programskog jezika, kodiran u C programskom jeziku, kao što na primer svi .Net programski jezici imaju Microsoft-ov kompajler otvorenog koda zvani Roslyn koji je napisan u C# programskom jeziku. Međutim, za stvaranje prvog C kompajlera, njegov tvorac Dennis Ritchie je koristio prethodni programski jezik B, koji je razvio Ken Thompson. Dennis Ritchie je kasnije proširio B programski jezik i stvorio C programski jezik, pa je originalni C kompajler takođe pisan na B jeziku. Mi uglavnom koristimo GCC kompajler verziju 12 ili neku noviju, ovaj tekst je pisan 2023 godine; i nema teoretske šanse da ćete u njemu pronaći ni jednu komandu u B programskom jeziku. Zato što GCC kompajler ne podržava B programski jezik, smatra ga previše zastarelim. Ali znamo da je GCC kompajler napisan kombinacijom C i C++ programskog jezika, s time da je moguće da sadrži i neke delove napisane u drugim programskim jezicima kao što su Objective-C i neki noviji.
Proces prevođenja se izvodi u 8 logičkih koraka, stime da prevodilac može da kombinuje nekoliko faza sve dok to ne utiče na rezultat.
1. Faza
Iz izvorne tekstualne datoteke čitaju se znakovi i tamo gde je potrebno se prevode u znakove iz skupa izvornih datoteka. Svi trigrafi se pretvaraju u znak koji predstavljaju. Trigrafi su troznakovne leksičke jedinice:
- ??( - ekvivalent [
- ??) - ekvivalent ]
- ??< - ekvivalent {
- ??> - ekvivalent }
- ??= - ekvivalent #
- ??/ - ekvivalent \
- ??! - ekvivalent |
- ??’ - ekvivalent ^
- ??- - ekvivalent ~
Digrafi se ne zamenjuju odgovarajućim znakom. Digrafi su dvoznakovne leksičke jedinice:
- %: - ekvivalent #
- %:%: - ekvivalent ##
Indikatori kraja reda biće zamenjeni izuzev znaka za novi red. Svaka izvorna datoteka mora da se završi znakom za novi red ukoliko nije prazna.
2. Faza
Ako se iza znaka za novi red nalazi „\“ – obrnuta kosa crta, pretprocesor briše oba znaka. Pošto se pretprocesorska direktiva završava znakom za kraj reda, ovo brisanje omogućava da stavite obrnutu kosu crtu na kraj reda kako bi ste naredbu nastavili u sledećem redu.
3. Faza
Izvorna datoteka se razlaže na pretprocesorske tokene i na sekvence razmaka. Tokeni su vam npr:
Printf
(
)
Svaki komentar tumači se kao jedan razmak.
4. Faza
Izvršavaju se pretprocesorske direktive i proširuju pozivi makroa. Makro vam je u stvari naredba, prečica, automatizovana procedura ili radnja. Postoje tasterski i programerski makroi. Tasterski makroi beleže i reprodukuju akcije pritiska na taster ili kretanje miša, dok programerski makroi su u suštini programirana rutina.
Sve 4 faze, primenjuju se za sve datoteke umetnute direktivom #include. Kad prevodilac izvrši pretprocesorske direktive, uklanja ih iz svoje radne kopije izvornog koda.
5. Faza
Svi znakovi i izlazne sekvence u znakovnim konstantama i literalima znakovnih nizova, pretvaraju se u odgovarajuće znakove iz izvršnog skupa znakova.
6. Faza
Susedni literali se međusobno nadovezuju i spajaju u jedan znakovni niz.
7. Faza
Odvija se prevođenje, prevodilac analizira sekvencu tokena i generiše odgovarajući mašinski kod.
8. Faza
Povezivač izdvaja reference na spoljne objekte i funkcije i generiše izvornu datoteku. Ako se u modulu poziva spoljni objekat ili funkcija koji nisu definisani ni u jednoj jedinici za prevođenje, povezivač ih uzima iz standardne biblioteke. Spoljni objekti i funkcije smeju se definisati samo u jednom programu.
Na kraju bi dodao da pretprocesor je zaseban program i on može da obavlja samo faze pretprocesiranje tj. faze od 1 do 4. U novijim programskim jezicima procesi su drugačiji jer pored leksičkih analiza, pretprocesiranja, parsiranja, semantički analiza, generišu i optimizuju kôd. Nadam se da vam je posle ovog posta jasnije kako se kompajlira C program. Pogledajte video ukoliko niste u prošlom postu!
No comments:
Post a Comment