десно|мини|440п|Упрошћено представљен процес превођења два програма писана у два различита програмска језика. Циљно окружење у којем ће да се извршава програм је такође различито. Ова два процеса превођења се најчешће не одвијају паралелно, али преводилац користи заједнички софтвер за оптимизацију међукода.

Компилатор или програмски преводилац () је рачунарски програм (или низ програма) који трансформише код једног програмског језика у други програмски језик. Код који се преводи обично се зове изворни код, а код добијен трансформацијом машински код.

Најчешћи разлог за превођење изворног кода јесте прављење извршног програма. Име компилатор се користи за програме који преводе изворни код са вишег програмског језика на језик нижег нивоа (нпр. асемблерски језик, машински језик). Програм који преводи са нижег на виши програмски језик је декомпилатор. Програм који преводи са једног вишег програмског језика на други се обично зове преводилац језика, преводилац извора у извор, или конвертор језика. Преиначилац језика је обично програм који преводи форму израза без промене језика.

Превођење програма често се састоји из више фаза. То могу да буду неки од следећих процеса: лексичка анализа, препроцесирање, синтаксна анализа, семантичка анализа, генерисање кода и оптимизација кода.

Процес компилације се обично обично одвија кроз две главне етапе: анализу изворног кода и синтезу објектног кода.

У етапи анализе, изворни програм се преводи у одређену посредну репрезентацију, која је погодна за даље манипулисање. У етапи синтезе се из посредне репрезентације добија објектни код.

Са своје стране, етапа анализе се дели у три фазе: лексичку анализу синтаксичку анализу семантичку анализу

Историја

За старије генерације рачунара, софтвер је годинама писан асемблерским језиком. Виши програмски језици нису пронађени све док предности могућности поновног коришћења софтвера на разним врстама процесора нису постале значајно веће од цене писања компилатора. Веома ограничен капацитет меморија старијих рачунара је такође стварао пуно техничких проблема при имплементацији компилатора.

Први виши програмски језик (Планкалкул) је предложен од стране Конрада Цузеа 1943. године. Крајем 50-их година прошлог века, предложени су машински независни програмски језици. Према том предлогу, развијено је неколико експерименталних компилатора. Грејс Хопер је 1952. написала први компилатор за А-0 програмски језик. Фортранов тим који је водио Џон Бакус из IBMа је генерално акредитован са представљањем првог комплетног компилатора 1957. године. Кобол је био рани језик који је компилиран на вишеструким архитектурама 1960. године.

У многим апликационим доменима, идеја коришћења виших програмских језика је брзо прихваћена. Због ширења функционалности праћених новијим програмским језицима и повећавања комплексности рачунарских архитектура, компилатори су постајали све сложенији.

Старији рачунари су писани асемблерским језиком. Први само-домаћи компилатор – способан да компилира сопствени код у виши програмски језик- креирали су Харт и Левин за Lisp на МИТу 1962. године. Још од 1970-их, имплементација компилатора у језику којег компилира је постала уобичајена пракса, иако су Паскал и C били популарни избори за имплементацију језика. Прављење само-домаћег компилатора је проблем бутстраповања – први такав компилатор за језик мора бити компилиран или компајлером писаним различитим језиком или (као у Харт и Левиновом компајлеру за Lisp) или покретањем компилатора у интерпретеру.

Компилатор у образовању

Конструкција компилатора и оптимизација компилатора се учи на универзитетима као део наставног плана рачунарске науке. Такви курсеви су обично допуњени имплементацијом компилатора за образовни програмски језик. Добро документован пример је ПЛ/0 компилатор Никлаус Вирта, који је Вирт користио да би подучавао конструкцију компилатора у 1970-им. Упркос својој једноставности, ПЛ/0 компилатор је имао неколико концепата: Развој програма постепеним усавршавањем Употреба рекурзивног десцентног парсера Употреба ЕБНФа да би се описала синтакса језика Генератор кода који производи портабилни П код Употреба Т-дијаграмa у формалном описивању проблема бутстраповања

Излаз компилатора

Један метод за класификацију компилатора је преко платформе на којој се извршава генерисани код који они производе. Позната је као циљна платформа.

Природни или домаћи компилатор је онај чији је излаз намењен да се директно покреће на истом типу рачунара и оперативног система на којима се покреће и компилатора. Излаз укрштеног компилатора је дизајниран да се покреће на другачијој платформи. Укрштени компилатори се често користе када се развија софтвер за укопане системе који нису планирани за подршку софтверског развојног окружења.

Излаз компилатора који производи код за виртуалну машину (ВМ) може или не може бити извршаван на истој платформи као компилатор који га је произвео. Зато такви компилатори често нису класификовани као природни или укрштени компилатори.

Компилирани насупрот интерпретираних језика

Виши програмски језици су, погодности ради, подељени на компилиране језике и интерпретиране језике. Ипак, ретко постоји нешто у вези језика што захтева да буде искључиво компилиран или искључиво интерпретиран. Категоризација често одражава најпопуларније или најраспрострањеније имплементације језика – нпр. БЕЈЗИК је интерпретиран језик и C је компилирани, упркос постојању БЕЈЗИК компилатора и C интерпретера.

Сви програмски језици могу да се посматрају као интерпретирани. Извршавање машинског кода био би само специјалан случај интерпретације коју изводи хардвер централне процесорске јединице. Модерни трендови као што су правовремена компилација и интерпретација бајткода такође нарушавају традиционалну категоризацију.

Постоје изузеци. Неке спецификације језика наговештавају да имплементације морају укључивати лаку компилацију, нпр. Common Lisp. Остали језици имају особину да се веома лако имплементирају у интерпретеру, али је писање компилатора знатно теже, нпр. АПЛ, СНОБОЛ4, и многи писани језици дозвољавају програмима да конструишу произвољан изворни код на почетку са операцијама регуларних стрингова, и онда да извршавају тај код додајући га специјалној функцији процене. Да би имплементирали ове особине у компилираним језицима, програми обично морају бити смештени у почетној библиотеци која укључује верзију самог компилатора.

Компилација хардвера

Излази неких компајлера могу користити хардвер на веома ниском нивоу. Нпр. Низови пролаза програмибилних поља (НППП) или структурално Апликативно специфично интегративно коло (АСИК). За такве компилаторе се каже да су компилатори хардвера или алати синтезе јер програми које они компилирају ефикасно контролишу финалну конфигурацију хардвера и начин њиховог деловања; излаз компилације нису инструкције које су извршене у секвенци – само веза транзистора или -{lookup}- табеле. На пример, -{XST}- је -{Xilinx Synthesis Tool}- који се користи за конфигурисање -{FGPA}-. Слични алати су доступни из -{Altera}--e, -{Synplicity}--ja, -{Synopsys}--a и других продаваца.

Дизајн компилатора

Приступ за дизајнирање компилатора је узрокован комплексношћу потребног процесирања, искуством особе(а) које га дизајнирају и ресурсима који су на располагању (нпр. људи и алат).

Компилатор за релативно једноставан језик који је написала једна особа, може бити једно парче софтвера. Када је изворни језик велики и сложен и када је захтеван висококвалитетан излаз, дизајн може бити подељен у број релативно независних фаза или пролаза. Имати одвојене фазе значи да развој може бити подељен на мале делове и дат различитим људима. Тада је такође пуно лакше заменити једну фазу побољшаном или убацити нове фазе касније (нпр. додатне оптимизације).

Идеја о подели процеса компилације на фазе (или пролазе) је победила захваљујући Пројекту продукције квалитета компилатора на универзитету Карнеги Мелон. Овај пројекат је увео термине -{front end}-, -{middle end}- (данас ретко коришћен) и -{back end}-.

Сви осим најмањих компилатора имају више од две фазе. Ипак, ове фазе су обично посматране као део -{front end-а}- или -{back end-а}-. Тачка на којој се ова два краја сусрећу је увек дискутабилна. -{front end}- је генерално разматран да буде тамо где се обављају синтаксичко и семантичко процесирање заједно са померањем у нижи ниво репрезентације (него изворни код).

-{Middle end}- је обично дизајниран да изведе оптимизацију на форми различитој од изворног или машинског кода. Ова независност изворног (машинског) кода има за циљ да омогући да генеричке оптимизације буду подељене између верзија компилатора подржавајући разне језике и циљне процесоре.

-{Back end}- узима излаз из средине. Може да изводи више анализа, трансформација и оптимизација које су за неки посебан рачунар. Потом, генерише код за посебан процесор и ОС.

Овај -{front-end/middle/back-end}- приступ даје могућност комбиновања -{front end}--ова за различите језике са -{back end}--овима за различите централне процесорске јединице. Практични примери овог приступа су ГНУ компајлер колекција, ЛЛВМ и Амстердам компилатор алат који имају вишеструке -{front end}--ове, подељене анализе и вишеструке -{back end}--ове.

Једнопролазни насупрот вишепролазног компилатора

Класификација компилатора према броју пролаза има своју позадину у ограничењу хардверских ресурса рачунара. Компилација укључује пуно посла и старији рачунари нису имали довољно меморије да би садржали програм који би радио сав поменути посао. Зато су компилатори били подељени на мање програме од којих је сваки имао пролаз преко извора (или неке његове репрезентације) изводећи неке од захтеваних анализа и транслација.

Способност компилације у једном пролазу је често виђена као предност јер поједностављује посао писања компилатора и једнопролазни компилатори су генерално бржи од вишепролазних компилатора. Многи језици су дизајнирани тако да могу бити компилирани у једном пролазу (нпр. Паскал).

У неким случајевима дизајнирање особине језика може захтевати да компилатор изведе више од једног пролаза преко извора. Нпр. узимајући у обзир појављивање декларације у 20. линији извора што утиче на померање појављивања исказа у линији 10. У овом случају, први пролаз треба да сакупи информације о појављивањима декларација после исказа на које утичу са померањем догађаја за време следећег пролаза.

Недостатак компилације у једном пролазу је што она не може да омогући многе од добрих оптимизација потребних за генерисање високо – квалитетног кода. Може бити тешко да се преброји колико тачно фаза оптимизирајући компилатор прави. Нпр. различите фазе оптимизације могу анализирати један израз више пута али само једном неки други израз.

Подела компилатора на мање програме је техника коју користе истраживачи заинтересовани за стварање коректних компилатора. Доказивање коректности групе малих програма често захтева мање напора него доказивање коректности једног већег, еквивалентног програма.

Док типични вишепролазни компилатор избацује машински код из свог последњег пролаза, постоји неколико других типова: Извор – у – извор компилатор је тип компилатора који користи језик високог нивоа као улаз, а излаз је такође језик високог нивоа. Нпр. аутоматски паралелизујући компилатор ће учестало узимати програмски језик високог нивоа као улаз и онда трансформисати код и прибележити га са паралелним кодом (нпр. -{OpenMP}-) или конструкције језика (нпр. Фортранови -{DOALL}- искази). Фазни компилатор који компилира у асемблерски језик теоријске машине као неке Пролог имплементације Ова Пролог машина је такође позната и као Воренова апстрактна машина (ВАМ). Бајткод компилатори за Јаву, Пајтон и многе друге су такође подтипови ових. Правовремени компилатор који користе -{Smalltalk}- и Јава системи, и такође -{Microsoft .Net}- - ов Обичан интермедијални језик (-{CIL}-) Апликације се испоручују у бајткоду који је компилиран у природни машински код баш пре извршења.

-{Front end}-