Компилатор

Компилаторът (англ. compiler - от compile - съчетавам, съставям) е компютърна програма, която превежда (съставя, компилира) даден компютърен изходен код в семантично отговаряща програма (на друг компютърен език). Английското "съставям" е малко подвеждащо, тъй като компилаторът е повече от само съставяне на таблици, необходими за вътрешната обработка на данни.

Повечето компилатори превеждат изходен код, написан на език за програмиране от високо ниво, в езици от по-ниско ниво напр. обектен код, машинен език, асемблер, които често могат директно да бъдат изпълнени от компютър или виртуална машина .

Стъпки на превеждане

Има две основни фази при създаването на кода:

  • Аналитична където се изследва първоначалния код, като резултатът е синтактичната дървовидна структура съдържаща (спомагателни) атрибути.
  • Съчетаваща (синтезираща) където се създава крайният код въз основа на създадента преди това синтактичната дървовидна структура.

 

Аналитичната фаза

Нарича се също така предно стъпало (англ. Frontend).

Лексикален анализ

Изходният код се разгражда на взаимно свързани градивни единици (англ. Token) от различни групи, напр. ключови думи, еднозначни определения (англ. Identifier), числа и задействащи символи (оператори от англ. Operator). Тази част на компилатора се нарича преведено речник (англ. Lexer) или описвач (англ. Scanner).

Описвачът (Scanner) понякога използва преведено решетъчник (англ. Screener), който "пресейва" програмния код от знаците за пауза и нов ред (англ. Whitespace) и от междуметията (англ. Comment).

Синтактичен анализ

При тази стъпка се проверява дали използваните градивни единици са формално допустими, т.е. отговарят на зададената граматика за програмния език. За целта програмния код се превръща в синтактична дървовидна структура. Другото наименование на тази стъпка е преведено раздробвач (англ. Parser).

Смислов (семантичен) анализ

Следващата стъпка е да се провери дали зададените програмни единици са логично свързани по между си (англ. Semantik (гр. значение)). Напр.

  • дали една променлива (англ. Variable) e обявена за използване (т.е. дали е заделена оперативна памет за нея), преди да бъде използвана в програмата

или пък дали

  • при прехвърляне на стойността на една променлива в друга, дали вида на променливите (англ. Datatype) е съвместим по между им.


Тези проверки се осъществяват посредством така преведената атрибутирана граматика (англ. Attribute grammar), (от лат. attribute свойствени / допълнително обяснени и гр. изкуство на буквите).

Синтезираща фаза

Нарича се също така задно стъпало (англ. Backend), където създадената синтактична дървовидна структура се превежда в крайния код.

Създаване на междинен код

При тази стъпка се създава междинен код, който по правило е близък до структурата на крайния език. Чрез него се и осъществява и подобрение на бързината на изпълнение (англ. Optimization). Това стъпало се използва и за изходна точка за създаване на код за различни операционни системи.

Оптимизация

Това е най-сложната част от превеждането на програмите. Целта е

  • подобрение е бързината на изпълнение и
  • намаляване на използваната оперативна памет.

 

Окончателно създаване на код

При таза стъпка се превежеда окончателно синтактичната дървовидна структура на програмата в крайния език. Ако крайният език е машинен език, създаденият код може директно да бъде изпълнен или пък се създава така наречения обектен файл (.obj), който чрез свързване (англ. linking) с други обектни файлове и (динамични) споделени библиотеки (централно място за често използвани функции в работен режим от различни програми) води до създаване на изпълним код.

Свързването (linking) се нарича статично ако необходимите програмни функции от библиотеки или пр. се "копират" в машиния код директно. Свързването се нарича динамично, ако програмата се компилира с използване на споделени библиотеки, които се зареждат в оперативната памет, само когато са нужни. Самият код съдържа извикване на функциите от тези библиотеки. Тези библиотеки използват относителни адреси в паметта и целта на програмата зареждач на операционната система е да нагоди адресите според адресното пространство на стартираната програма. Такива библиотеки се казва, че са компилирани с позиционно независим код. Същестува и възможността за компилиране с позиционно зависим код, който се използва в определени случаи тъй като пропускането на процеса на релокация спестява изчислителни ресурси и води до подобрение на скоростта на изпълнение. Позиционно зависим код се използва и при вградените ОС като Windows CE, където програмите се зареждат винаги на строго определен адрес.