Kompilator
Den här artikeln behöver källhänvisningar för att kunna verifieras. (2018-12) Åtgärda genom att lägga till pålitliga källor (gärna som fotnoter). Uppgifter utan källhänvisning kan ifrågasättas och tas bort utan att det behöver diskuteras på diskussionssidan. |
En kompilator är inom datavetenskap ett datorprogram som utifrån en programtext skrivet i ett programspråk som till exempel C, Modula, eller Ada, skapar ett motsvarande lågnivåprogram som kan omvandlas till exekverbar kod (maskinkod) som kan utföra de aktiviteter som programtexten beskriver, alltså ett slags översättare. Normalt genererar en kompilator assembler, för senare omvandling till maskinkod för en specifik datortyp, men även andra varianter förekommer.
Implementering
Denna process sker vanligen som ett antal separata faser eller steg. Normalt delas dessa in i två huvudkomponenter: en språkspecifik del tolkar programtexten och översätter den (typiskt) till något lämpligt internt temporärformat, ofta någon form av träd eller graf. Detta används sedan av en kodgenerator för att skapa den slutliga översättningen till maskinkod.
Språkberoende analys
Denna består ofta av tre steg: lexikalanalys, syntaxanalys samt semantisk analys, vilka kan vara mer eller mindre separerade.
- Den lexikala analysen tar bort kommentarer och delar upp programtexten i betydelsebärande textfragment i programspråket:
if for := += 3.14 "test"
etc.
- Syntaxanalysen känner igen korrekta satser och uttryck i programspråket bestående av sådana textfragment. Detta görs ifrån en uppsättning grammatiska regler för hur de olika typerna av ord och symboler kan kombineras.
- Den semantiska analysen kontrollerar att detta beskriver meningsfulla, möjliga, och tillåtna aktiviteter eller deklarationer, och bygger upp en intern representation av programmet. En viktig del av detta (i de flesta språk) är typkontroll, att alla uttryck är av rätt typ, till exempel att funktioner anropas med rätt sorts parametrar. När ett uttrycks typ fastställts så lagras typinformationen i den interna representationen av programmet så att senare steg vet om till exempel en addition är mellan heltal eller reella tal.
Kodgenerator
Denna genomför olika transformationer på den interna representationen för att slutligen kunna översätta programmet till effektiv maskinkod/assembler.
- Optimeringssteg kan förekomma på flera olika nivåer i översättningen; konstanta (del-) uttryck kan beräknas på förhand, invariant kod kan flyttas ut ur repetitioner etc.
- För att underlätta översättningen görs den ofta först till ett internt generellt lågnivåspråk för en tänkt godtycklig processorarkitektur.
- Därefter genomförs ofta registerallokering; processorns interna register reserveras (dynamiskt) för aktuella variabler och mellanresultat i varje uttryck, block, och/eller rutin.
- Det sista steget är kodgenerering där kompilatorn väljer maskininstruktioner som ska ersätta instruktionerna i det generella interna lågnivåspråket (se ovan). För en så kallad CISC-processor kan det krävas en väsentlig insats för att uppnå den "optimala" översättningen då det kan finnas instruktioner som motsvarar ett flertal instruktioner i mellanspråket. Kodgenerering för en RISC-arkitektur är ofta enklare eftersom urvalet av instruktioner är mindre.
Fördelen med att bygga upp en kompilator så här är att det blir enklare att till exempel generera kod för en annan processor, man behöver bara skriva om den sista delen. För att lägga till ett nytt programspråk behöver bara den första delen skrivas om. I äldre eller enklare kompilatorer är dock kodgenereringen ofta invävd i de språkberoende delarna.
Ett program kompilerat till maskinkod behöver länkas till systemrutiner för att göras till ett körbart program.