Compiler

Fra Wikipedia, den frie encyklopædi
Gå til: navigation, søg

En compiler (også kaldet kompiler eller oversætter) er et program der automatisk kan oversætte fra et programmeringssprog til et andet. En compiler bruges til at lave nye programmer med idet man oversætter fra kildekode til maskinkode og derved opnår eksekverbare filer (på Windows kaldet ".exe-filer").

Processen hvorved et program oversættes mellem to formelt definerede sprog kan også kaldes en transformation. Oversættelsen foregår typisk fra et sprog med meget abstraktion til et med mindre, selvom det ikke altid er tilfældet. Denne skelnen kan også karakteriseres ved at kalde det ene sprog for et højniveausprog og det andet for et lavniveausprog. Et typisk lavniveausprog er maskinkode, som er instruktionssprog computeren forstår.

Der er dog også praktiske grunde til at oversætte til andre højniveausprog eller til maskinkode til virtuelle maskiner. Hvis man oversætter til et højniveausprog, kan man afvikle sit program i de miljøer som eksisterer til det givne sprog og efterfølgende oversætte det videre. For eksempel oversættes programmeringssproget Haskell til programmeringssproget C før det oversættes til maskinkode. Det kan der være nogle fordele ved.

Hvis man oversætter til en virtuel maskine, kan man afvikle sit program på alle fysiske maskiner, der understøtter en simulering af den virtuelle maskine. Eksempler på sprog som udnytter sidstnævnte er Java til JVM og ActionScript til AVM.

Teknikken[redigér | redigér wikikode]

En compiler oversætter typisk fra kildekode, der ligger i en fil og kan læses af et menneske, til et binært maskinkode-format, der kun kan læses af andre programmer. En compiler indeholder typisk kontrol af fejl i kildekoden, så ugyldige programmer frasorteres med fejlmeddelelser, samt optimering mht. udførelsestid og lagerforbrug af den resulterende kode. Derefter kan det resulterende binære program typisk udføres hurtigere og med mindre brug af plads. Dette er i modsætning til en fortolker der udføre kildekoden direkte, linje for linje, og derfor ikke kan udføre programmet så hurtigt som hvis det var oversat.

En anden fordel ved at compilere er at man kan nøjes med at give den binære version af programmet til andre så de kun kan udføre programmet, men ikke nemt kan rette i programmet. Der er dog ingen garanti imod at andre kan regne ud hvordan ens program virker hvis de har den binære kode. At regne baglæns fra binær maskinkode til et læseligt, men muligvis lavniveausprog, kaldes dekompilering eller reverse engineering. For at gøre processen sværere findes såkaldte obfuskatorer.

Til nogle programmeringssprog, som f.eks. BASIC, findes både compiler og fortolker. Når man udvikler i sprog hvor begge dele er tilgængelige, bruger man typisk en fortolker, mens programmet udvikles (debugger/fejlfinder), og en compiler, når resultatet skal anvendes i praksis.

Nogle gange oversætter man typisk til et binært format som kaldes mellemkode, som er et programmeringssprog hvis formål er at levere et abstraktionsniveau mellem højniveausproget og lavniveausproget. For eksempel kan højniveausproget understøtte vilkårligt mange variable, mens lavniveausproget har et begrænset antal registre som skal repræsentere variablene. Man kan derfor have lyst til at have et lavniveausprog hvor man stadig har vilkårligt mange registre og håndtere register-allokering som en separat proces.

En decompiler er en compiler, der ud fra resulterende kode forsøger at genskabe kildekoden.

En compiler, der er beregnet til at køre på én computertype, men som leverer maskinkode beregnet til kørsel på en anden type computer, omtales som en krydsoversætter (eng. cross compiler).

Oversættelsesprocessen[redigér | redigér wikikode]

Oversættelsen foregår i flere trin.

  • Der kan være en præ-proces, der udvider makroer
  • Kommentarer fjernes fra kildekoden.
  • Der foretages en leksikalsk analyse, der resulterer i en liste af symboler, som kan genkendes af oversætteren.

Eksempelvis gøres en samlet tekststreng:

'abekat=abe+kat;'

til nu delt i flere tekststrenge og evt. i hvert sit objekt:

'abekat', '=', 'abe', '+', 'kat', ';'

Processen håndterer også, at programmeringssprog som C og Java eksempelvis både bruger '+', '++', '+=', '=' og '=='.

  • Der opbygges et parsetræ (Proces: Syntaktisk analyse), ud fra programmeringssprogets grammatik.
  • Der udføres en semantisk analyse, der eksempelvis kan afsløre om variabler, der bliver brugt også er defineret korrekt.
  • Eventuel optimering ved beskæring eller andre transformationsændringer af parsetræet.
  • Generering af assemblerkode ud fra data i parsetræet.

Der dannes en fil med output for hver fil med kildekode, der kan udføres. Kildefiler, der kun indeholder definitioner af konstanter og variabler resulterer ikke i en outputfil.

Kasserne er delprocesserne i oversættelsen. (pt fransk)

Resultatet af oversættelsen skal behandles af en en assembler og siden en linker før der er kommet et færdigt program ud af det.

Eksempel på oversættelse – Hello.java[redigér | redigér wikikode]

Herunder følger et eksempel på oversættelse af java programmet Hello.java.

public class Hello{
	public static void main(String[] args){
		for(int i=0; i<10; i++)
			System.out.println("Hallo");
	}
}

Med javac oversættes Hello.java til en såkaldt class-fil, der indeholder det oversatte program i såkaldt bytecode. Denne kode er instruktioner til en java-maskine (evt. en virtuel java-maskine, JVM).

Delen public class Hello extends java.lang.Object{ public Hello(); bliver eksempelvis til...

0:   aload_0
1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
4:   return

... og main-metoden bliver til...

0:   iconst_0
1:   istore_1
2:   iload_1
3:   bipush  10
5:   if_icmpge       22
8:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
11:  ldc     #3; //String Hallo
13:  invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
16:  iinc    1, 1
19:  goto    2
22:  return

...hvilket en JVM kan forstå og fortolke!

Se også[redigér | redigér wikikode]

Eksterne henvisninger[redigér | redigér wikikode]

Open source[redigér | redigér wikikode]

Hele compilere[redigér | redigér wikikode]

Compiler værktøjer[redigér | redigér wikikode]

Sproggrammatikker til compilere[redigér | redigér wikikode]