Definisjonen og formålet med en kompilator

Globale data, konseptuelle kunstverk

ANDRZEJ WOJCICKI / Getty Images





EN kompilator er en program som oversetter menneskelig lesbar kildekode inn i datamaskin-kjørbar maskinkode. For å gjøre dette vellykket, må den menneskelesbare koden være i samsvar med syntaks regler for hvilket programmeringsspråk den er skrevet i. Kompilatoren er bare et program og kan ikke fikse koden for deg. Hvis du gjør en feil, må du korrigere syntaksen, ellers vil den ikke kompilere.

Hva skjer når du kompilerer kode?

En kompilator sin kompleksitet avhenger av syntaksen til språket og hvor mye abstraksjon det programmeringsspråket gir. En C-kompilator er mye enklere enn en kompilator for C++ eller C#.



Leksikalsk analyse

Ved kompilering leser kompilatoren først en strøm av tegn fra en kildekodefil og genererer en strøm av leksikalske tokens. For eksempel, C++-koden:

|_+_||_+_|

kan analyseres som disse tokens:



  • skriv 'int'
  • variabel 'C'
  • er lik
  • venstre brakett
  • variabel 'A'
  • ganger
  • variabel 'B'
  • høyre parentes
  • i tillegg til
  • bokstavelig '10'

Syntaktisk analyse

Den leksikale utgangen går til den syntaktiske analysatordelen av kompilatoren, som bruker grammatikkreglene for å avgjøre om inndata er gyldig eller ikke. Med mindre variabler A og B ble tidligere erklært og var i omfang, kan kompilatoren si:

  • 'A': uoppgitt identifikator.

Hvis de ble erklært, men ikke initialisert. kompilatoren gir en advarsel:

  • lokal variabel 'A' brukes uten å bli initialisert.

Du bør aldri ignorere kompilatoradvarsler. De kan knekke koden din på rare og uventede måter. Reparer alltid kompilatoradvarsler.

Ett pass eller to?

Noen programmeringsspråk er skrevet slik at en kompilator bare kan lese kildekoden én gang og generere maskinkoden. Pascal er et slikt språk. Mange kompilatorer krever minst to pass. Noen ganger er det på grunn av videre erklæringer av funksjoner eller klasser.



I C++ kan en klasse deklareres, men ikke defineres før senere. Kompilatoren klarer ikke å finne ut hvor mye minne klassen trenger før den kompilerer kroppen til klassen. Den må lese kildekoden på nytt før den genererer riktig maskinkode.

Generer maskinkode

Forutsatt at kompilatoren fullfører de leksikalske og syntaktiske analysene, er det siste trinnet å generere maskinkode. Dette er en komplisert prosess, spesielt med moderne CPUer.



Hastigheten til det kompilerte kjørbar koden skal være så rask som mulig og kan variere enormt i henhold til kvaliteten på den genererte koden og hvor mye optimalisering som ble forespurt.

De fleste kompilatorer lar deg spesifisere optimaliseringsmengden – vanligvis kjent for raske feilsøkingskompileringer og full optimalisering for den utgitte koden.



Kodegenerering er utfordrende

Kompilatorforfatteren møter utfordringer når han skriver en kodegenerator. Mange prosessorer fremskynder behandlingen ved å bruke

  • Instruksjon pipelining
  • Innvendig cacher .

Hvis alle instruksjonene i en kode Løkke kan holdes i prosessor cache, så går den løkken mye raskere enn når CPU-en må hente instruksjoner fra hoved-RAM. CPU-cachen er en minneblokk innebygd i CPU-brikken som får tilgang til mye raskere enn data i hoved-RAM.



Cacher og køer

De fleste CPU-er har en forhåndshentingskø der CPU-en leser instruksjoner inn i hurtigbufferen før de utføres. Hvis en betinget gren skjer, må CPU-en laste inn køen på nytt. Koden bør genereres for å minimere dette.

Mange CPUer har separate deler for:

  • Heltallsaritmetikk (heltall)
  • Flytende kommaaritmetikk (brøktall)

Disse operasjonene kan ofte kjøres parallelt for å øke hastigheten.

Kompilatorer genererer vanligvis maskinkode til objektfiler som er det koblet sammen av et linkerprogram.