Γλώσσες Προγραμματισμού Μεταγλωττιστές Παραγωγή Ενδιάμεσου Κώδικα Πανεπιστήμιο Μακεδονίας Τμήμα Εφαρμοσμένης Πληροφορικής Ηλίας Σακελλαρίου
Δομή ▪Παραγωγή ενδιάμεσου κώδικα. ▪Ενδιάμεσες γλώσσες. Αφηρημένα συντακτικά δένδρα Προθεματικός και επιθεματικός κώδικας Κώδικας τριών διευθύνσεων ▫ Γλώσσα τριάδων και τετράδων. ▪Σχήματα οδηγούμενα από τη σύνταξη. Λογικές Εκφράσεις Backpatching Εντολές διακλάδωσης υπο συνθήκη Εντολή while-do
Φάσεις Μεταγλώττισης Συντακτική Ανάλυση Λεκτική Ανάλυση Σημασιολογική Ανάλυση Παραγωγή Ενδιάμεσου Κώδικα Βελτιστοποίηση Ενδιάμεσου Κώδικα Βελτιστοποίηση Τελικού Κώδικα Παραγωγή Τελικού Κώδικα Πίνακας Συμβόλω ν Χειριστής Σφαλμάτω ν Αρχικό Πρόγραμμα λεκτικές μονάδες συντακτικό δένδρο ενδιάμεσος κώδικας τελικός κώδικας Τελικό Πρόγραμμα
Παραγωγή Ενδιάμεσου Κώδικα ▪Στην συνηθέστερη περίπτωση ο μεταγλωττιστής παράγει ενδιάμεσο κώδικα. Ενδιάμεσος κώδικας είναι εκφρασμένος σε μια γλώσσα χαμηλότερου επιπέδου από την αρχική, αλλά υψηλότερου επιπέδου από τη γλώσσα μηχανής. ▪Λόγος Διαχωρισμός εμπρόσθιου (front-end) και οπίσθιου μέρους (back-end) του μεταγλωττιστή, άρα διευκόλυνση υλοποίησης μεταγλωττιστών. ▫ Επαναχρησιμοποίηση κώδικα. Ευκολότερη μετάφραση. Ευκολότερη βελτιστοποίηση κώδικα.
Ενδιάμεσες Γλώσσες ▪Η επιλογή της γλώσσας είναι ευθύνη του κατασκευαστή του μεταγλωττιστή. ▪Δεν υπάρχει συγκεκριμένο πρότυπο. ▪Απαιτείται μια γλώσσα που: Να προσφέρει εύκολη μετάφραση από την αρχική γλώσσα υψηλού επιπέδου. Εύκολη μετάφραση στη τελική γλώσσα μηχανής. Προσφέρει ευκολία στις βελτιστοποιήσεις. ▪Γλώσσες που έχουν προταθεί: Αφηρημένα συντακτικά δένδρα Προθεματικός και επιθεματικός κώδικας Τριάδες και τετράδες εντολών.
Αφηρημένα Συντακτικά Δένδρα ▪Παρόμοια με τα συντακτικά δένδρα, αλλά περισσότερο συμπαγή. ▪Τελεστές τοποθετούνται στους ενδιάμεσους κόμβους και τα τελούμενα στα φύλλα του δένδρου. πχ b*b-4*a*c ▪Δυνατότητα γραμμικής αναπαράστασης: -(*(b,b),*(*(4,a),c)) bb a c - ** * 4
Κατευθυνόμενοι Ακυκλικοί Γράφοι ▪Οι κατευθυνόμενοι ακυκλικοί γράφοι αποτελούν μια παραλλαγή των αφηρημένων συντακτικών δένδρων. Ενοποίηση κοινών υποδένδρων. ▪Είναι μια πρώτη μορφή βελτιστοποίησης. πχ. έκφραση a+a*(b-c)+(b-c)*d b a a c + * - * d +
Προθεματικός και Επιθεματικός Κώδικας ▪Στον προθεματικό κώδικα ο τελεστής εμφανίζεται πριν τα τελούμενα, ενώ στον επιθεματικό μετά. ▪Δεν χρησιμοποιείται συχνά, καθώς δεν διευκολύνει τη βελτιστοποίηση. πχ b*b-4*a*c Προθεματικός κώδικας -*bb**4ac Επιθεματικός κώδικας bb*4a*c*-
Κώδικας Τριών Διευθύνσεων ▪Ένας τελεστής σε κάθε εντολή. ▪Τρεις διευθύνσεις οι οποίες αντιπροσωπεύουν τα ορίσματα και το αποτέλεσμα του τελεστή. ▪Παράδειγμα: Έκφραση Κώδικας τριών διευθύνσεων: ▪Περιέχει δύο "κλάσεις" αντικειμένων: διευθύνσεις και εντολές addresses and instructions ▪Ο κώδικας "γράφεται" είτε με την μορφή τριάδων είτε με την μορφή τετράδων. w=x+y*z $1 = y * z w= x + $1
Γλώσσα των Τριάδων ▪Δεν προβλέπει μια μεταβλητή στην οποία ανατίθεται το αποτέλεσμα της πράξης αλλά το αποτέλεσμα αναφέρεται από την αριθμητική ετικέτα της εντολής. ▪Στο προηγούμενο παράδειγμα w=x+y*z 100: *,y,z 110: +,x,$1 120: =,w,(110)
Γλώσσα των Τετράδων ▪Κάθε εντολή αποτελείται από μια αριθμητική ετικέτα, το τελεστή op και τρία τελούμενα (ορίσματα του τελεστή) x,y,z, δηλαδή: n: op, x,y,z Για παράδειγμα η πρόσθεση w = x+$1 γίνεται: 100:+,x,$1,w Σε περίπτωση που ο τελεστής έχει λιγότερα από δύο ορίσματα, τότε τα αντίστοιχα πεδία της τετράδας παραμένουν κενά, πχ 110: -, s, -,w (w=-s). Το προηγούμενο παράδειγμα: w=x+y*z 100: *,y,z,$1 110: +,x,$1,w
Απλές και Σύνθετες Διευθύνσεις ▪Απλές διευθύνσεις είναι: Σταθερά Όνομα μεταβλητής, παραμέτρου ή υποπρογράμματος (δείκτης στην αντίστοιχη εγγραφή στον πίνακα συμβόλων) Προσωρινή μεταβλητή με τη μορφή $n, όπου n ακέραιος (αποθήκευση ενδιάμεσων αποτελεσμάτων). Αποτέλεσμα συνάρτησης, με τη μορφή $$. ▪Σύνθετες Διευθύνσεις Διεύθυνση: αν x είναι τύπου τ, τότε {x} αντικείμενο που "δείχνει" στο τ και είναι τύπου ^τ. Αποδεικτοδότηση: αν x τύπου ^τ τότε [x] είναι τύπου τ.
Άλλες Παράμετροι ▪Ετικέτα Τετράδας, που χρησιμοποιείται για την πραγματοποίηση άλματος ▪Ετικέτα εντολής, για πραγματοποίηση αλμάτων με εντολή GOTO. ▪Τρόπος περάσματος παραμέτρων, κατά αξία V ή κατά αναφορά R. ▪Άγνωστη ετικέτα τετράδας (*), που δηλώνει ότι η ετικέτα δεν είναι γνωστή ακόμη και θα συμπληρωθεί αργότερα με την διαδικασία bakcpatching.
Εντολές ▪unit,I,-,- και endu,I,-,- Έναρξη και τέλος δομικής μονάδας Ι ▪op,x,y,z όπου op είναι +,-,*,/,% και αντιστοιχεί στην εκτέλεση της πράξης op στα τελούμενα x,y και αποθήκευση αποτελέσματος στο z. ▪-,x,-,z Υλοποίηση αρνητικού προσήμου (z =-x) ▪:=,x,-,z Εντολή ανάθεσης το z παίρνει τη τιμή του x. ▪array,x,y,z Επιστρέφει στο z ένα δείκτη στο y-ιοστό στοιχείο του πίνακα x.
Παράδειγμα ▪v=x + y*z + w : *,y,z,$1 110: +,x,$1,$2 120: +,$2,w,$3 130: +,$3,3,$4 140: :=,$4,-,v ▪v = -r : -,r,-,$1 110: +,$1,18,$2 120: :=,$2,-,v
Εντολές Άλματος ▪jump,-,-,z Η εντολή πραγματοποιεί άλμα στην τετράδα με ετικέτα z (αριθμητική ετικέτα) ▪label,l,-,- Ορίζει μια ετικέτα εντολής με το όνομα l. ▪jumpl,-,-,l Η εντολή πραγματοποιεί άλμα στην τετράδα με ετικέτα εντολής l (που πρέπει να ορίζεται όπως παραπάνω)
Εντολές Άλματος (ii) ▪op,x,y,z όπου op,=, =. Η εντολή πραγματοποιεί άλμα (υπό συνθήκη) στην τετράδα με ετικέτα z, αν αληθεύει το x op y. ▪ifb,x,-,z Αν αληθεύει η bolean x τότε γίνεται άλμα στην ετικέτα z.
Παράδειγμα Εντολών Άλματος ▪if x < 3 then y=18 else y = 5;....; 100: <,x,3, : jump,-,-, : :=,18,-,y 130: jump,-,-, : :=,5,-,y 150:.... ▪v = true; if v then x = 1; : :=,true,-,v 110: ifb,v,-, : jump,-,-, : :=,1,-,x 140:...
Παράδειγμα Εντολών Άλματος ▪if x < 3 then y=18; x=y; else y = 5;....; 100: <,x,3, : jumpl,-,-,LFalse 120: :=,18,-,y 130: :=,y,-,x 140: jumpl,-,-,IfEnd 150: label,-,-,LFalse 160: =,5,-,y 170: label,-,-,IfEnd
Εντολές υποπρογραμμάτων ▪call,-,-,I κλήση του υποπρογράμματος Ι ▪par,x,V,- (κατά αξία) par,x,R,-(κατά αναφορά) par,x,RET,- (θέση στην οποία επιστρέφεται αποτέλεσμα) Εντολές δήλωσης παραμέτρων, που πρέπει να υπάρχουν πριν από την εντολή call,-,-,I. ▪ret,-,-,- εντολή επιστροφής από την συνάρτηση πρίν ο έλεγχος φτάσει στη τριάδα endu.
Παράδειγμα ▪int f(x) { if x = 0 return 0; z = 100 mod x; return 2*z; }... z=8; y=12*f(z) 100: unit,-,-,f 110: =,0,x, : jump,-,-, : :=,0,-,$$ 130: ret,-,-,- 140: %,100,x,$1 150: *,2,$1,$$ 160: endu,-,-,f : :=,8,-,z 510: par,z,V,- 520: par,$10,RET,- 530: call,f,-,- 540: *,12,$10,y
Μετάφραση Οδηγούμενη από την Σύνταξη για την Παραγωγή Ενδιάμεσου Κώδικα
Παραγωγή Ενδιάμεσου Κώδικα ▪Η παραγωγή του ενδιάμεσου κώδικα γίνεται με την τεχνική της μετάφρασης οδηγούμενης από τη σύνταξη. Διευρυμένη γραμματική χωρίς συμφραζόμενα με ιδιότητες και σημασιολογικές ρουτίνες. ▪Η συντακτική ανάλυση και η παραγωγή ενδιάμεσου κώδικα γίνονται ταυτόχρονα. Στους LR συντακτικούς αναλυτές οι σημασιολογικές ρουτίνες πρέπει να είναι στο τέλος του κανόνα. S ::= A {SR1} B {SR2} γίνεται: S::=A P1 B {SR2} P1 ::={SR1}
Παράδειγμα Μετάφρασης Εντολής Ανάθεσης S ::= "id" ":=" E ;{p = lookup(id.lexeme); if p != nil then genQuad('=',E.place,-,p) else error} E ::= E 1 "+" E 2 {E.place = newTemp(E.type) genQuad('+',E 1.place, E 2.place, E.place) } E ::= E 1 "*" E 2 {E.place = newTemp(E.type); genQuad('*',E 1.place, E 2.place, E.place)} E ::= "-" E 1 {E.place = newTemp(E.type); genQuad('-',E 1.place,-,E.place) } E ::= "(" E 1 ")" {E.place = E 1.place} E ::= "id" {p = lookup(id.lexeme); if p != nil then E.place = p else error}
Σχόλια ▪Για την συγκεκριμένη υλοποίηση υπάρχουν οι ακόλουθες ιδιότητες: place: περιέχει τη θέση του αντικειμένου στην οποία βρίσκεται μια τιμή. Είναι δηλαδή η διεύθυνση της μεταβλητής. type: ο τύπος στον οποίο ανήκει μια τιμή. ▪Οι συναρτήσεις που χρησιμοποιούνται είναι οι ακόλουθες: genQuad: παράγει μια νέα τετράδα εντολής με τα τέσσερα ορίσματα. newTemp: Δημιουργεί μια νέα μεταβλητή συγκεκριμένου τύπου.
Μετάφραση Σύνθετων Εντολών block::= " begin " stmts " end " { block.nextlist = smts.nextlist; } stmts::= stmt ' ; ' { stmts.nextlist = stmt.nextlist; } stmts::= stmt ' ; ' { backpatch(stmt.nextlist, nextQuad); } stmts 2 { stmts.nextlist = stmts 2.nextlist; } ▪Η S.nextlist θα χρησιμοποιηθεί σε εντολή backpatching όταν γίνει γνωστή η επόμενη τετράδα που ακολουθεί.
Μετάφραση Λογικών Εκφράσεων (i) ▪Λογικές εκφράσεις έχουν δύο ρόλους: περιγράφουν μια λογική τιμή η οποία μπορεί να ανατεθεί σε μια μεταβλητή τύπου boolean. ▫ Στην περίπτωση αυτή οι τιμές μπορεί να είναι true/false. ▫ πχ. s = a and b or c αποτελούν συνθήκες σε εντολές αλλαγής ροής ελέγχου (διακλάδωσης). ▫ πχ. if a and b or c then S ▪Υπολογισμός τιμής λογικών εκφράσεων: Αποδίδεται στην έκφραση η τιμή 0 (false) ή 1 (true) και οι πράξεις γίνονται όπως οι αριθμητικές πράξεις. ▫ Χρησιμοποιείται όταν το αποτέλεσμα αποθηκεύεται σε μια μεταβλητή.
Μετάφραση Λογικών Εκφράσεων (ii) ▪Κάθε λογική έκφραση συνδέεται με αντίστοιχες μεταβάσεις που δηλώνουν που θα μεταφερθεί ο έλεγχος αν η έκφραση είναι αληθής ή ψευδής. Ο αριθμός της τετράδας για μετάβαση στην περίπτωση true αποδίδεται ως τιμή στις αντίστοιχες εντολές άλματος του μεταφρασμένου κώδικα. Οι θέσεις των εντολών αυτών αποθηκεύονται σε αντίστοιχη (ομώνυμη) μεταβλητή του συμβόλου (truelist) για χρήση με την διαδικασία backpatching. Με παρόμοιο τρόπο ορίζεται ο κώδικας στη περίπτωση false. Οι μεταβάσεις αποθηκεύονται στη μεταβλητή falselist.
Μετάφραση Λογικών Εκφράσεων (iii)... 07: jump,-,-, : jump,-,-, : jump,-,-, : jump,-,-, : jump,-,-, : jump,-,-,51... truelist = {7,20,26,33} := 51 falselist = {7,20,26,33} :=42 42:... 51:...
Παράδειγμα Γραμματικής Λογική Διάζευξη ▪Η τεχνική λέγεται short-circuit. ▪ B::=B 1 " or " { backpatch(B 1.falselist;nextQuad); } B 2 { B.truelist := merge(B 1.truelist;B 2.truelist); B.falselist := B 2.falselist } Β1Β1 Β2Β2 falselist truelist falselist truelist falselist
Backpatching ▪Όπως είναι φανερό από το προηγούμενο παράδειγμα η Β 1 μπορεί να χρειάζεται για τη μετάφραση της αυθαίρετα μεγάλο αριθμό τετράδων. Σε κάποιες από αυτές τις τετράδες, "βεβαιώνεται" ότι η τιμή της Β 1 είναι false και πρέπει να γίνουν τα αντίστοιχα άλματα. Δεν είναι γνωστό κατά τη δημιουργία των τετράδων το που (τετράδα αμέσως μετά εκείνες της Β 1 )! backpatching: Ανατρέχει τις τιμές αποθηκευμένες στη λίστα (truelist/falselist) όταν είναι γνωστή η τιμή και θέτει τις ανάλογες τιμές (τετράδες jump)
Παράδειγμα Γραμματικής Λογική Σύζευξη ▪ B::=B 1 " and " { backpatch(B 1.truelist;nextQuad); } B 2 { B.truelist := B 2.truelist; B.falselist := merge(B 1.falselist,B 2.falselist } Β1Β1 Β2Β2 falselist truelist falselist truelist falselist
Παράδειγμα Γραμματικής Λογική Άρνηση ▪ B::=" not " B 1 { B.truelist := B 1.falselist; B.falselist := B 1.truelist; } Β1Β1 falselist truelist falselist
Λογικές Σχέσεις ▪Λογικές σχέσεις αφορούν τη μετάφραση τελεστών ">"," " κλπ. B ::= "Ε 1 " relop "Ε 2 " { B.truelist := makelist(nextQuad); genQuad(relop.name,Ε 1.place,Ε 2.place,*) B.falselist := makelist(nextquad); genQuad(jump,-,-,*); } E1E1 falselist truelist E2E2 Relop,E1,E2,* jump,-,-,*
Σχόλια ▪Η nextQuad επιστρέφει τον αριθμό ετικέτας της επόμενης τετράδας που θα παραχθεί. Υποθέτουμε ότι η genQuad αυξάνει τον αριθμό αυτό κατάλληλα. ▪Η name είναι κατάλληλη συνθετική μεταβλητή για το σύμβολο relop, όπου αποθηκεύεται το όνομα του συμβόλου. ▪πχ. relop ::= ">" {relop.name = ">"}
Παράδειγμα ▪Έστω η λογική έκφραση (i>=30) and (i < 40) or (i=10) ▪Η μετάφραση της θα είναι: 10: >,i,30,* 20: jump,-,-,* 10: >,i,30,30 20: jump,-,-,* 30: <,i,40,* ( backpatching ) 10: >,i,30,30 20: jump,-,-,50 30: <,i,40,100 40: jump,-,-,50 50: =,i,10,100 60: jump,-,-, :... (true) 140:... (false)
Μετάφραση των True/False και Παρενθέσεων ▪Kανόνας Μετάφρασης για την σταθερά true B::=" true " {B.truelist := makelist(nextQuad); B:falselist := emptyList(); genQuad(jump,-,-,*)} ▪Kανόνας Μετάφρασης για την σταθερά false B::=" false " {B.falselist := makelist(nextQuad); B.truelist := emptyList(); genQuad(jump,-,-,*)} Β::=" ( " Β 1 " ) " {B.falselist = B 1.falselist B.truelist = B 1.truelist}
Μετάφραση τελεστών σε Δομές Διακλάδωσης ▪H εντολή διακλάδωσης if-then S::= " if " B " then " { backpatch(B.truelist,nextQuad) } S 1 { S.nextlist = mergelists(B.falselist,S 1.nextlist) } Β S1S1 nextlist truelist falselist nextlist
Σχόλια ▪H mergelists ενώνει τις δύο λίστες ετικετών τετράδων. ▪Η S.nextlist θα χρησιμοποιηθεί σε εντολή backpatching όταν γίνει γνωστή η επόμενη τετράδα και θα πάρουν τιμές οι αντίστοιχες εντολές jump.
Παράδειγμα ▪Έστω if (i>=30) and (i < 40) or (i=10) then i:=i+1 10: >,i,30,30 20: jump,-,-,50 30: <,i,40,* (truelist) 40: jump,-,-,50 50: =,i,10,* (truelist) 60: jump,-,-,* (falselist) 10: >,i,30,30 20: jump,-,-,50 30: <,i,40, 70 (truelist) 40: jump,-,-,50 50: =,i,10, 70 (truelist) 60: jump,-,-,* (falselist) 70: +,i,1,$1 80: =,i,-,$1 90:
Εντολή Διακλάδωσης if-then-else S::= " if " B " then " { backpatch(B.truelist,nextQuad) } S 1 { L 1 =nextQuad; genQuad(jump,-,-,*) } " else " { backpatch(B.falselist,nextQuad); } S 2 { S.nextlist=mergelists(L 1,S 1.nextlist,S 2.nextlist); } Β S1S1 nextlist truelist falselist nextlist S2S2 jump,-,-,* nextlist
Εντολή if B then S1 else S2 B.cod e to B.truelist to B.falselist B.truelist: B.falselist: S1.cod e jump,-,-, S2.cod e S.next:
Εντολή while-do ▪Η εντολή while έχει την μορφή: S::= " while " { L=nextQuad; } B " do " { backpatch(B.truelist,nextQuad); } S 1 { backpatch(S 1.nextlist,L); genQuad(jump,-,-,L); S.nextlist=B.falselist; } Β S1S1 nextlist truelist falselist nextlist jump,-,-,*
Παράδειγμα ▪while i<n do p := p + 1; 100: <,i,n,* 110: jump,-,-,* 120: +,p,1,$1 130: =,p,-,$1 140: jump,-,-,* 150: 100: <,i,n, : jump,-,-,* 120: +,p,1,$1 130: =,p,-,$1 140: jump,-,-, :
Κλήση Συναρτήσεων ▪Κλήση συναρτήσεων χωρίς να ληφθεί υπόψη μετατροπή τύπων και τύποι παραμέτρων. Call::= " id " " ( " P " ) " { Call.place = newTemp(id.type); genQuad("par",RET,Call.place,-); genQuad(call,-,-,id.place) } P::=ε P::=E { genQuad("par",E.place,-,-); } D D::=ε D::=", " E { genQuad("par".E.place,-,-) } D
Εντολές goto break ▪Η μετάφραση των εντολών αυτών γίνεται με τις μεθόδους που έχουν ήδη αναφερθεί. ▪Για την εντολή goto μπορεί να διατηρηθεί μια λίστα και έπειτα να γίνει backpatching όταν οι ετικέτες των labels γίνουν γνωστές. ▪Η εντολή break σε ένα while-do μπορεί να υλοποιηθεί με δημιουργία αντίστοιχου άλματος και τοποθέτηση του στη λίστα nextlist της εντολής. Αργότερα παίρνει τιμή με backpatching.
Σύνοψη ▪Παραγωγή ενδιάμεσου κώδικα. ▪Ενδιάμεσες γλώσσες. Αφηρημένα συντακτικά δένδρα Προθεματικός και επιθεματικός κώδικας Κώδικας τριών διευθύνσεων ▫ Γλώσσα τριάδων και τετράδων. ▪Σχήματα οδηγούμενα από τη σύνταξη. Λογικές Εκφράσεις Backpatching Εντολές διακλάδωσης υπο συνθήκη Εντολή while-do