Hvad er et compilerdesign? Typer, konstruktionsværktøjer, eksempel
⚡ Smart opsummering
Compilerfaser beskriver de seks faser, der omdanner kildekode til maskinkode: leksikalsk analyse, syntaksanalyse, semantisk analyse, generering af mellemliggende kode, kodeoptimering og kodegenerering, understøttet af symboltabelstyring og fejlhåndtering.
Hvad er faserne af compilerdesign?
A compiler opererer i forskellige faser, og hver fase transformerer kildeprogrammet fra én repræsentation til en anden. Hver fase tager input fra sin forrige fase og sender sit output til den næste fase af compileren. Der er 6 faser i en compiler. Hver af disse faser hjælper med at konvertere sproget på højt niveau til maskinkode. Faserne i en compiler er:
- Leksikalsk analyse
- Syntaksanalyse
- Semantisk analyse
- Mellemkodegenerator
- Code optimering
- Code generator
Faser af compiler
Alle disse faser konverterer kildekoden ved at opdele den i tokens, oprette parsetræer og optimere kildekoden gennem forskellige faser.
Fase 1: Leksikalsk analyse
Leksikalsk analyse er den første fase, hvor compileren scanner kildekoden. Denne proces kan udføres fra venstre mod højre, tegn for tegn, og grupperer disse tegn i tokens.
Her grupperes tegnstrømmen fra kildeprogrammet i meningsfulde sekvenser ved at identificere tokens. Programmet foretager indtastningen af de tilsvarende tokens i symboltabellen og sender dette token videre til den næste fase.
De primære funktioner i denne fase er:
- Identificer de leksikalske enheder i kildekoden.
- Klassificer leksikalske enheder i klasser som konstanter og reserverede ord, og indtast dem i forskellige tabeller. Kommentarer i kildeprogrammet ignoreres.
- Identificer et token, der ikke er en del af sproget.
Eksempel: x = y + 10
| Polet | Type |
|---|---|
| X | identifikator |
| = | Tildelingsoperatør |
| Y | identifikator |
| + | Tilføjelsesoperatør |
| 10 | nummer |
Fase 2: Syntaksanalyse
Syntaksanalyse handler om at opdage struktur i kode. Den afgør, om en tekst følger det forventede format. Hovedformålet med denne fase er at sikre, at kildekoden, som programmøren har skrevet, er korrekt eller ej.
Syntaksanalyse er baseret på reglerne i det specifikke programmeringssprog ved at konstruere parsetræet ved hjælp af tokens. Den bestemmer også kildesprogets struktur og sprogets grammatik eller syntaks.
Her er en liste over opgaver, der udføres i denne fase:
- Hent tokens fra den leksikalske analysator.
- Tjek om udtrykket er syntaktisk korrekt eller ej.
- Rapportér alle syntaksfejl.
- Konstruer en hierarkisk struktur, der er kendt som et parsetræ.
Eksempel
Enhver identifikator/et tal er et udtryk. Hvis x er en identifikator og y+10 er et udtryk, så er x = y+10 en sætning. Betragt parsetræet for følgende eksempel:
(a+b)*c
I parse-træet:
- Indvendig node: post med et operatorfelt og to felter til underordnede.
- Blad: poster med 2 eller flere felter; et til tokenet og andre oplysninger om tokenet.
- Sørg for, at programmets komponenter passer meningsfuldt sammen.
- Indsamler typeinformation og kontrollerer typekompatibilitet.
- Kontroloperander er tilladt af kildesproget.
Fase 3: Semantisk analyse
Semantisk analyse kontrollerer kodens semantiske konsistens. Den bruger syntakstræet fra den foregående fase sammen med symboltabellen for at verificere, at den givne kildekode er semantisk konsistent. Den kontrollerer også, om koden formidler en passende betydning.
Den semantiske analysator vil kontrollere for typeuoverensstemmelser, inkompatible operander, en funktion kaldet med ukorrekte argumenter, en udeklareret variabel osv.
Funktionerne i den semantiske analysefase er:
- Hjælper dig med at gemme indsamlede typeoplysninger og gemme dem i symboltabellen eller syntakstræet.
- Giver dig mulighed for at udføre typekontrol.
- I tilfælde af en typeuoverensstemmelse, hvor der ikke er præcise typekorrektionsregler, der opfylder den ønskede operation, vises en semantisk fejl.
- Indsamler typeoplysninger og kontrollerer typekompatibilitet.
- Kontrollerer om kildesproget tillader operanderne eller ej.
Eksempel
float x = 20.2; float y = x*30;
I ovenstående kode vil den semantiske analysator typecaste heltallet 30 til at flyde 30.0 før multiplikation.
Fase 4: Mellemtrin Code Generation
Når den semantiske analysefase er overstået, genererer compileren mellemliggende kode til målmaskinen. Den repræsenterer et program for nogle abstract-maskine.
Mellemliggende kode ligger mellem sproget på højt niveau og maskinniveau. Denne mellemliggende kode skal genereres på en sådan måde, at den er nem at oversætte til den ønskede maskinkode.
Funktioner af mellemprodukt Code generation:
- Den skal genereres ud fra den semantiske repræsentation af kildeprogrammet.
- Indeholder de værdier, der blev beregnet under oversættelsesprocessen.
- Hjælper dig med at oversætte den mellemliggende kode til målsproget.
- Giver dig mulighed for at opretholde prioritetsrækkefølgen for kildesproget.
- Den indeholder det korrekte antal operander i instruktionen.
Eksempel
For eksempel:
total = count + rate * 5
Mellemkode ved hjælp af adressekodemetoden er:
t1 := int_to_float(5)
t2 := rate * t1
t3 := count + t2
total := t3
Fase 5: Code Optimering
Den næste fase er kodeoptimering af den mellemliggende kode. Denne fase fjerner unødvendige kodelinjer og arrangerer rækkefølgen af sætninger for at fremskynde programmets udførelse uden at spilde ressourcer. Hovedformålet med denne fase er at forbedre den mellemliggende kode for at generere en kode, der kører hurtigere og optager mindre plads.
De primære funktioner i denne fase er:
- Det hjælper dig med at etablere en afvejning mellem udførelses- og kompileringshastighed.
- Forbedrer målprogrammets køretid.
- Genererer strømlinet kode stadig i mellemrepræsentation.
- Fjernelse af utilgængelig kode og fjernelse af ubrugte variabler.
- Fjernelse af uændrede udsagn fra løkken.
Eksempel: Overvej følgende kode:
a = intofloat(10)
b = c * a
d = e + b
f = d
Kan blive:
b = c * 10.0
f = e + b
Fase 6: Code Generation
Code Generering er den sidste og afsluttende fase i en compiler. Den modtager input fra kodeoptimeringsfasen og producerer sidekoden eller objektkoden som et resultat. Formålet med denne fase er at allokere lagerplads og generere flytbar maskinkode.
Den allokerer også hukommelsespladser til variablerne. Instruktionerne i den mellemliggende kode konverteres til maskininstruktioner. Denne fase konverterer den optimerede eller mellemliggende kode til målsproget.
Målsproget er maskinkoden. Derfor vælges og allokeres alle hukommelsesplaceringer og registre også i denne fase. Koden genereret i denne fase udføres for at modtage input og generere forventede output.
Eksempel
a = b + 60.0 ville muligvis oversættes til registre som:
MOVF a, R1 MULF #60.0, R2 ADDF R1, R2
Symbol Tabel Management
En symboltabel indeholder en post for hver identifikator med felter til identifikatorens attributter. Denne komponent gør det nemmere for compileren at søge i identifikatorposten og hente den hurtigt. Symboltabellen hjælper dig også med omfangsstyring. Symboltabellen og fejlhåndteringen interagerer med alle faser, og symboltabellen opdateres tilsvarende.
Fejlhåndteringsrutine
I compilerdesignprocessen kan der opstå fejl i alle nedenstående faser:
- Leksikalsk analysator: Forkert stavede tokens.
- Syntaksanalysator: Manglende parentes.
- Mellemliggende kodegenerator: Uoverensstemmende operander for en operator.
- Code Optimizer: Når udsagnet ikke er tilgængeligt.
- Code Generator: Når hukommelsen er fuld, eller de korrekte registre ikke er allokeret.
- Symboltabeller: Fejl i flere deklarerede identifikatorer.
De mest almindelige fejl er ugyldige tegnsekvenser i scanning, ugyldige tokensekvenser i type, omfangsfejl og parsing i semantisk analyse.
Fejlen kan opstå i en hvilken som helst af ovenstående faser. Efter at have fundet fejl, skal fasen håndtere fejlene for at fortsætte kompileringsprocessen. Disse fejl skal rapporteres til fejlbehandleren, som håndterer fejlen for at udføre kompileringsprocessen. Generelt rapporteres fejlene i form af en besked.



