За информацията в тази статия или раздел не са посочени източници. Въпросната информация може да е непълна, неточна или изцяло невярна. Имайте предвид, че това може да стане причина за изтриването на цялата статия или раздел. |
Компилаторът (англ. compiler, от compile – съчетавам, съставям) е компютърна програма, която превежда (компилира) даден компютърен изходен код в семантично отговарящ код на език от (обикновено) по-ниско ниво. Целевият език може да бъде машинен език или асемблерен език за конкретен процесор или процесорна фамилия, както и междинен език за конкретна виртуална машина (например байткод за виртуална машина на Java) или друг език от високо ниво. Когато се компилира до машинен език, крайният продукт е изпълнима програма или обектен код.
Има две основни фази при създаването на кода:
Нарича се също така предно стъпало (frontend).
Изходният код се разгражда на отделни лексикални единици – токени (tokens), напр. ключови думи, идентификатори, числа и оператори. С това се занимава програма, наречена лексически анализатор или скенер.
Лексическият анализатор понякога използва решетъчник (screener), който „пресява“ програмния код от белите знаци (whitespace) и от коментарите.
При тази стъпка се проверява дали използваните градивни единици са формално допустими, т.е. дали отговарят на зададената граматика за програмния език. За целта програмният код се превръща в синтактична дървовидна структура.
Следващата стъпка е да се провери дали зададените програмни единици са логически свързани помежду си. Например:
Тези проверки се осъществяват посредством атрибутивна граматика (attribute grammar).
Нарича се също така задно стъпало (backend), където създадената синтактична дървовидна структура се превежда в крайния код.
При тази стъпка се създава междинен код, който по правило е близък до структурата на целевия език. Чрез него се осъществява и подобрение на бързината на изпълнение. Това стъпало се използва и за изходна точка при създаване на код за различни платформи.
Това е най-сложната част от превеждането на програмите. Оптимизацията може да бъде в различни насоки, в зависимост от желаната цел:
При таза стъпка окончателно се превежда синтактичната дървовидна структура на програмата в целевия език. Ако последният е машинен език, създаденият код може директно да бъде изпълнен или се създава така нареченият обектен файл, който чрез свързване (linking) с други обектни файлове и библиотеки води до създаване на изпълним код.
Свързването се нарича статично ако необходимите програмни функции от библиотеки или програми се „копират“ в машинния код директно. Свързването се нарича динамично, ако програмата се компилира с използване на споделени библиотеки, които се зареждат в оперативната памет, само когато са нужни. Самият код съдържа извикване на функциите от тези библиотеки. Тези библиотеки използват относителни адреси в паметта и целта на програмата зареждач на операционната система е да нагоди адресите според адресното пространство на стартираната програма. Такива библиотеки се казва, че са компилирани с позиционно независим код. Същестува и възможността за компилиране с позиционно зависим код, който се използва в определени случаи тъй като пропускането на процеса на релокация спестява изчислителни ресурси и води до подобрение на скоростта на изпълнение. Позиционно зависим код се използва и при вградените ОС като Windows CE, където програмите се зареждат винаги на строго определен адрес.