Компилатор
За информацията в тази статия или раздел не са посочени източници. Въпросната информация може да е непълна, неточна или изцяло невярна. Имайте предвид, че това може да стане причина за изтриването на цялата статия или раздел. |
Компилаторът (англ. compiler, от compile – съчетавам, съставям) е компютърна програма, която превежда (компилира) даден компютърен изходен код в семантично отговарящ код на език от (обикновено) по-ниско ниво. Целевият език може да бъде машинен език или асемблерен език за конкретен процесор или процесорна фамилия, както и междинен език за конкретна виртуална машина (например байткод за виртуална машина на Java) или друг език от високо ниво. Когато се компилира до машинен език, крайният продукт е изпълнима програма или обектен код.
Стъпки на превеждане
[редактиране | редактиране на кода]Има две основни фази при създаването на кода:
- Аналитична, при която се изследва изходният код, като резултатът е синтактична дървовидна структура съдържаща (спомагателни) атрибути.
- Синтезираща (съчетаваща), където се създава крайният код въз основа на данните получени от предишната фаза.
Аналитичната фаза
[редактиране | редактиране на кода]Нарича се също така предно стъпало (frontend).
Лексически анализ
[редактиране | редактиране на кода]Изходният код се разгражда на отделни лексикални единици – токени (tokens), напр. ключови думи, идентификатори, числа и оператори. С това се занимава програма, наречена лексически анализатор или скенер.
Лексическият анализатор понякога използва решетъчник (screener), който „пресява“ програмния код от белите знаци (whitespace) и от коментарите.
Синтактичен анализ
[редактиране | редактиране на кода]При тази стъпка се проверява дали използваните градивни единици са формално допустими, т.е. дали отговарят на зададената граматика за програмния език. За целта програмният код се превръща в синтактична дървовидна структура.
Семантичен анализ
[редактиране | редактиране на кода]Следващата стъпка е да се провери дали зададените програмни единици са логически свързани помежду си. Например:
- дали една променлива е обявена за използване (т.е. дали е заделена оперативна памет за нея), преди да бъде използвана в програмата,
- при прехвърляне на стойността на една променлива в друга, дали типовете на данните им са съвместими.
Тези проверки се осъществяват посредством атрибутивна граматика (attribute grammar).
Синтезираща фаза
[редактиране | редактиране на кода]Нарича се също така задно стъпало (backend), където създадената синтактична дървовидна структура се превежда в крайния код.
Създаване на междинен код
[редактиране | редактиране на кода]При тази стъпка се създава междинен код, който по правило е близък до структурата на целевия език. Чрез него се осъществява и подобрение на бързината на изпълнение. Това стъпало се използва и за изходна точка при създаване на код за различни платформи.
Оптимизация
[редактиране | редактиране на кода]Това е най-сложната част от превеждането на програмите. Оптимизацията може да бъде в различни насоки, в зависимост от желаната цел:
- увеличаване на бързината на изпълнение
- намаляване на използваната оперативна памет
- намаляване на разхода на електроенергия
- намаляване на размера на кода
Окончателно създаване на код
[редактиране | редактиране на кода]При таза стъпка окончателно се превежда синтактичната дървовидна структура на програмата в целевия език. Ако последният е машинен език, създаденият код може директно да бъде изпълнен или се създава така нареченият обектен файл, който чрез свързване (linking) с други обектни файлове и библиотеки води до създаване на изпълним код.
Свързването се нарича статично ако необходимите програмни функции от библиотеки или програми се „копират“ в машинния код директно. Свързването се нарича динамично, ако програмата се компилира с използване на споделени библиотеки, които се зареждат в оперативната памет, само когато са нужни. Самият код съдържа извикване на функциите от тези библиотеки. Тези библиотеки използват относителни адреси в паметта и целта на програмата зареждач на операционната система е да нагоди адресите според адресното пространство на стартираната програма. Такива библиотеки се казва, че са компилирани с позиционно независим код. Същестува и възможността за компилиране с позиционно зависим код, който се използва в определени случаи тъй като пропускането на процеса на релокация спестява изчислителни ресурси и води до подобрение на скоростта на изпълнение. Позиционно зависим код се използва и при вградените ОС като Windows CE, където програмите се зареждат винаги на строго определен адрес.
Видове компилатори
[редактиране | редактиране на кода]- Местен (native) компилатор
- Резултатът от превеждането е код, изпълним на платформата, върху която върви самият компилатор.
- Смесен (cross) компилатор
- Резултатът е изпълним код, предназначен за платформа различна от тази на която е извършена компилацията. Използва се например при създаване на код за вградени системи (embedded systems), където няма възможност, или е по-трудно, да се създават програми.
- Еднопреходен компилатор (single-pass compiler), също ограничен компилатор (narrow compiler)
- Този компилатор превежда програмата последователно и на един път (single-pass) за всеки компилиран блок. Казано по друг начин, компилаторът не се връща обратно на вече преведени части. Много програмни езици са замислени така, че да бъдат превеждани еднопреходно (напр. Паскал).
- Многопреходен компилатор (multi-pass compiler), също разширен компилатор (wide compiler)
- Този компилатор превежда програмата на няколко стъпки и намира приложение най-вече за:
- прекъсване на предходни заявявания на променливите (forward declaration, forward reference)
- провеждане на оптимизациите (свързани с изразходване на много ресурси) върху пълната синтактична дървовидна структура
Особени видове компилатори
[редактиране | редактиране на кода]- Транскомпилатор (също транспилатор) е особен компилатор, който превежда програмен код от един програмен език на друг програмен език, например от Паскал на C.
- Компилатор-Компилатор (compilergenerator) или помощни програми, създаващи автоматично компилаторни части или цели компилатори. Такива програми са напр. JavaCC, Yacc, Bison
- На-момента-компилатори (англ. Just-In-Time compiler/JIT compiler) превеждащи кода преди самото му изпълняване.