Διδακτικά Βιβλία του Παιδαγωγικού Ινστιτούτου

Αναζήτηση

Βρες
Εμφάνιση

Δομή του μεταγλωττιστή

Ένας μεταγλωττιστής γενικά αποτελείται από δύο μέρη: το ένα τμήμα είναι αφιερωμένο στην αναγνώριση και ανάλυση του προγράμματος στη γλώσσα υψηλού επιπέδου και το άλλο αναλαμβάνει την παραγωγή της συμβολικής γλώσσας και της γλώσσας μηχανής. Το τμήμα που κάνει την αναγνώριση της γλώσσας προγραμματισμού δεν εξαρτάται από τον υπολογιστή στον οποίο θα εκτελεστεί αλλά μόνο από τη γλώσσα προγραμματισμού. Αντίστοιχα, το τμήμα που κάνει την παραγωγή της γλώσσας μηχανής δεν εξαρτάται από τη γλώσσα προγραμματισμού αλλά μόνο από το ρεπερτόριο εντολών μηχανής που παράγει. Αυτό δίνει τη δυνατότητα στους κατασκευαστές των μεταγλωττιστών να κατασκευάζουν ανεξάρτητα τα δύο τμήματα, και να τα συνδυάζουν όπως χρειάζεται.

Μία εταιρία λογισμικού που κατασκευάζει μεταγλωττιστές μπορεί να σχεδιάζει και να υλοποιεί τα τμήματα των μεταγλωττιστών ανεξάρτητα το ένα από το άλλο, και μετά να τα συνδυάζει. Αν οι γλώσσες με τις οποίες ασχολείται είναι η Pascal, η C++ και η Ada, ενώ οι αρχιτεκτονικές επεξεργαστών για τους οποίους παράγονται τα προγράμματα είναι ο Sparc της Sun, ο Pentium της Intel και ο Alpha της DEC, τότε μπορεί να κατασκευάσει τρία τμήματα για τις γλώσσες προγραμματισμού και άλλα τρία για τις αρχιτεκτονικές. Συνδυάζοντας τα έξι τμήματα αυτά μεταξύ τους έχει έτοιμους εννέα μεταγλωττιστές.

Το πρώτο τμήμα του μεταγλωττιστή εκτελεί τρεις λειτουργίες: τη λεκτική, τη συντακτική και τη σημασιολογική ανάλυση του προγράμματος. Από τις λειτουργίες αυτές προκύπτει μία αναπαράσταση του προγράμματος η οποία δεν εξαρτάται από τη γλώσσα προγραμματισμού. Την αναπαράσταση αυτή χρησιμοποιεί το δεύτερο μέρος του μεταγλωττιστή, που επιτελεί την παραγωγή κώδικα μηχανής (ή συμβολικής γλώσσας) και τη βελτιστοποίησή του.

Στη λεκτική ανάλυση (lexical analysis) του προγράμματος, ο μεταγλωττιστής το χωρίζει στις βασικές του μονάδες: τις λέξεις, τα σύμβολα, τους αριθμούς κλπ. Τα διαστήματα που διαχωρίζουν τις μονάδες του προγράμματος αφαιρούνται, και το αποτέλεσμα είναι μία σειρά από μονάδες του προγράμματος (tokens).

Σε ένα πρόγραμμα Pascal εμφανίζονται οι εντολές y: = 5; x:= y+15;

Ο λεκτικός αναλυτής θα χωρίσει αυτό το τμήμα του προγράμματος στην ακολουθία: «αναγνωριστικό όνομα y», «τελεστής ανάθεσης», «αριθμητική σταθερά 5», «ερωτηματικό», «αναγνωριστικό όνομα x», «τελεστής ανάθεσης», «αναγνωριστικό όνομα y», «τελεστής συν», «αριθμητική σταθερά 15», «ερωτηματικό».

Στη συντακτική ανάλυση (syntax analysis) του προγράμματος, ελέγχεται κατά πόσο αυτό ακολουθεί τους συντακτικούς κανόνες της γλώσσας προγραμματισμού, και μετασχηματίζεται σε κάποια ενδιάμεση αναπαράσταση, την ενδιάμεση γλώσσα (intermediate language), η οποία δεν εξαρτάται από τη γλώσσα προγραμματισμού.

Στη γλώσσα Pascal οι εντολές χωρίζονται μεταξύ τους με ερωτηματικό («;»). Ο συντακτικός αναλυτής θα διαπιστώσει το λάθος και θα ενημερώσει τον προγραμματιστή αν έχει κατά λάθος γράψει τις παραπάνω εντολές σαν: y:= 5 x:= y+15; όπου λείπει ένα ερωτηματικό μεταξύ των εντολών.

Παράλληλα με τη συντακτική, γίνεται και η σημασιολογική ανάλυση (semantic analysis).

Αν ο προγραμματιστής γράψει σε ένα πρόγραμμα Pascal: γ := 5 + "abcde"; ο σημασιολογικός αναλυτής θα διαπιστώσει την εσφαλμένη πρόσθεση μεταξύ ενός αριθμού και ενός κειμένου, και θα ενημερώσει τον προγραμματιστή για αυτό.

Στη συνέχεια ο μεταγλωττιστής παράγει τις εντολές σε γλώσσα μηχανής ή σε συμβολική γλώσσα οι οποίες αντιστοιχούν στο πρόγραμμα το οποίο μεταφράζει. Αυτό το στάδιο της μεταγλώττισης ονομάζεται παραγωγή κώδικα (code generation). Με βάση την ενδιάμεση μορφή του προγράμματος που έχει κατασκευάσει κατά τη συντακτική ανάλυση, ο μεταγλωττιστής αντικαθιστά κάθε εντολή του προγράμματος με τις κατάλληλες εντολές μηχανής. Στο στάδιο αυτό αποφασίζει για τις θέσεις της μνήμης όπου θα αποθηκευθούν τα δεδομένα του προγράμματος.

Για τις δύο εντολές Pascal που είδαμε, ένας μεταγλωττιστής για τον Άβακα πρέπει να αποφασίσει πού στη μνήμη θα κρατούνται οι δύο σταθερές 5 και 15 και οι δύο μεταβλητές χ και y. Αν οι σταθερές τοποθετούνται σε θέσεις μνήμης με συμβολικά ονόματα C5 και C15 αντίστοιχα, και οι δύο μεταβλητές τοποθετούνται σε θέσεις μνήμης με τα συμβολικά ονόματα Χ και Υ, τότε το πρόγραμμα σε συμβολική γλώσσα που θα παραγάγει ο μεταγλωττιστής είναι: [pic]

Οι πληροφορίες για τη θέση των μεταβλητών και των σταθερών κρατούνται από το μεταγλωττιστή στον πίνακα συμβόλων (symbol table).

Ο πίνακας συμβόλων για το παράδειγμά μας είναι:

Συμβολική διεύθυνση - Σχετική διεύθυνση - Αρχικό περιεχόμενο C5 - 0 - 0000000000000101 C15 - 1 - 0000000000001111 Υ - 2 - 0000000000000000 Χ - 3 - 0000000000000000

Το τελευταίο στάδιο στη μεταγλώττιση ενός προγράμματος είναι η βελτιστοποίηση του κώδικα (code optimization). Στη φάση αυτή, γίνονται μικρές μετατροπές στον κώδικα μηχανής, με τέτοιο τρόπο ώστε να επιτελεί τις ίδιες λειτουργίες αλλά να είναι πιο γρήγορος ή πιο μικρός σε μέγεθος.

Το πρόγραμμα του παραδείγματός μας, με τη δεύτερη εντολή του αποθηκεύει το περιεχόμενο του συσσωρευτή στη θέση μνήμης με ετικέτα Υ και αμέσως μετά αντιγράφει πάλι το περιεχόμενο της θέσης μνήμης Υ στο συσσωρευτή. Η δεύτερη αντιγραφή είναι περιττή, αφού η θέση μνήμης Υ και ο συσσωρευτής έχουν το ίδιο περιεχόμενο. Κατά τη βελτιστοποίηση του κώδικα, η δεύτερη εντολή θα παραλειφθεί, και το πρόγραμμα θα γίνει τελικά: [pic]

Αν ο μεταγλωττιστής παράγει συμβολική γλώσσα, τότε ο συμβολομεταφραστής θα επεξεργαστεί το πρόγραμμα και θα παραγάγει τις εντολές μηχανής που είναι έτοιμες για εκτέλεση από τον υπολογιστή.

Τελικά, το πρόγραμμα σε γλώσσα μηχανής είναι:

Διεύθυνση - Περιεχόμενο 000000000000 - 0001000000000101 000000000001 - 0010000000001000 000000000010 - 0011000000000110 000000000011 - 0010000000000111 000000000100 - 0000000000000000 000000000101 - 0000000000000101 000000000110 - 0000000000001111 000000000111 - 0000000000000000 000000001000 - 0000000000000000