Компилатор
от Уикипедия, свободната енциклопедия
Компилаторът (англ. compiler - от compile - съчетавам, съставям) е компютърна програма, която превежда (съставя, компилира) даден компютърен изходен код в семантично отговаряща програма (на друг компютърен език). Aнглийското "съставям" е малко подвеждащо, тъй като компилаторът е повече от само съставяне на таблици, необходими за вътрешната обработка на данни.
Повечето компилатори превеждат изходен код, написан на език за програмиране от високо ниво, в езици от по-ниско ниво напр. обектен код, машинен език, асемблер, които често могат директно да бъдат изпълнени от компютър или виртуална машина .
Съдържание |
[редактиране] Стъпки на превеждане
Има две основни фази при създаването на кода:
- Аналитична където се изследва първоначалния код, като резултатът е синтактичната дървовидна структура съдържаща (спомагателни) атрибути.
- Съчетаваща (синтезираща) където се създава крайният код въз основа на създадента преди това синтактичната дървовидна структура.
[редактиране] Аналитичната фаза
Нарича се също така предно стъпало (англ. 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, където програмите се зареждат винаги на строго определен адрес.
[редактиране] Подреждане на различните компилатори
- Местен (англ. Native) компилатор
- Резултатът от превеждането е код (напр. машинен език) на който е написана и операционната система , върху която върви самият компилатор
- Смесен (англ. Cross) компилатор
- Резултатът е изпълним код, който върви на друга операционна система от тази на компилатора. Използва се например при създадаване на код за вградени операциони системи (англ. Embedded systems), където няма възможност или е по-трудно да се създават програмите. Някои от така наречените изкуствени машини (англ. Virtual machines) подобряват начина на работа (замествайки по този начин целта на смесените компилатори) като един и същ преведен код може да бъде използван и за системата на компилатора и за системата използващата програмата.
- Еднопреходен компилатор (англ. Single-pass-Compiler), също ограничен компилатор (англ. Narrow compiler)
- Този компилатор превежда програмата последователно на един път (англ. Single-pass) за всеки компилиран блок. Казано по друг начин компилаторът не може да се връща обратно на вече преведени части. Много програмни езици са замислени така, че да бъдат превеждани еднопреходно (напр. Паскал)
- Многопреходен компилатор (англ. Multi-pass-Compiler), също разширен компилатор (англ. Wide compiler)
- Този компилатор превежда програмата на няколко стъпки и намира приложение най-вече за:
- прекъсване на предходящи заявявания на променливите (англ. Forward declaration или също Forward reference)
- провеждане на оптимизациите (свързани с изразходване на много ресурси) върху пълната синтактична дървовидна структура (англ. [[Аbstract syntax tree]]).
[редактиране] Особени видове компилатори
- Транскомпилатор (също транспилатор (англ. Transpiler)) е особен компилатор, който превежда програмен код от един програмен език на друг програмен език, напр, от Паскал на C.
- Компилатор-Компилатор или помощни програми създаващи автоматично компилаторни части или цели компилатори (англ. Compilergenerator). Такива програми са напр. JavaCC, Lex, Yacc
- На-момента-компилатори (англ. Just-In-Time-Compiler/JIT-Compiler) превеждащи само необходимите програмни части едва по време на изпълнението му. Това са също така наречените преводачески програми (англ. Interpreter).