ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-1 Στατικός Έλεγχος Με τον όρο στατικός έλεγχος (static checking) χαρακτηρίζεται ο έλεγχος της συντακτικής και σημασιολογικής ορθότητας ενός προγράμματος, ο οποίος συντελείται κατά τη φάση της μεταγλώττισης (compile- time). Παραδείγματα στατικών ελέγχων: –Έλεγχοι Τύπων (type checking) : ελέγχουν την συμβατότητα των τελεστών και των ορισμάτων τους. Π.χ.: int x, y[10]; int f(char *name)… x + y x = f(y)
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-2 Παραδείγματα Στατικών Ελέγχων - Έλεγχοι Ροής (flow-of-control checks) : ελέγχουν την ορθότητα των μεταβάσεων στη ροή του προγράμματος από αντίστοιχες δομές ελέγχου ή σχετικές εντολές. Π.χ. for i=0 to 100 for j=0 to 200 … next i next j - Έλεγχοι Μοναδικότητας (uniqueness checks) : Π.χ. περιορισμός της εμφάνισης αναγνωριστικών μία μόνο φορά σε δηλώσεις, της ύπαρξης διαφορετικών τιμών σε μία εντολή switch-case, κ.α..
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-3 Παραδείγματα Στατικών Ελέγχων (2) - Έλεγχοι Ονομάτων (name-related checks): σε ορισμένες περιπτώσεις η γλώσσα υποχρεώνει την εμφάνιση ενός ονόματος σε δύο ή περισσότερα σημεία του προγράμματος (π.χ. Ada). Κατά κανόνα, η υλοποίηση των προηγούμενων ελέγχων μπορεί να πραγματοποιηθεί σε συνδυασμό με κάποια από τις αρχικές φάσεις μεταγλώττισης. Συνήθως, πραγματοποιούνται κατά την συντακτική ανάλυση σε συνδυασμό με κατάλληλα σχέδια μετάφρασης (translation schemes). Οι έλεγχοι μοναδικότητας μπορούν επίσης να πραγματοποιηθούν με κατάλληλη διαχείριση του πίνακα συμβόλων. Τυπικά, πραγματοποιούνται ανάμεσα στη ΣΑ και στη παραγωγή ενδιάμεσου κώδικα.
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-4 Δυναμικός Έλεγχος Με τον όρο δυναμικός έλεγχος (dynamic checking) αποδίδεται ο έλεγχος που εκτελείται κατά την διάρκεια της εκτέλεσης ενός προγράμματος (run-time). Ορισμένα είδη ελέγχων μπορούν να πραγματοποιηθούν μόνο δυναμικά, π.χ.: int table[255]; int i; Κατά την χρήση του i ως δείκτη για την προσπέλαση του πίνακα table, ο έλεγχος της τιμής του i ώστε i<256, δεν μπορεί να γίνει στατικά κατά κανόνα.
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-5 Έλεγχος Τύπων Ένας ελεγκτής τύπων (type checker) επιβεβαιώνει ότι ο τύπος μίας δομής της γλώσσας είναι ο αναμενόμενος σύμφωνα με τα συμφραζόμενα. Οι πληροφορίες που συλλέγονται από ένα ελεγκτή τύπων μπορούν να χρησιμοποιηθούν κατά την παραγωγή του ενδιάμεσου κώδικα ή ακόμα και κατά την βελτιστοποίηση. Π.χ. real f[100]; for(i=0;i<100; i++) f[i]=1; Τύποι μεταβλητών/δομών μίας γλώσσας: –Βασικοί τύποι (basic types), π.χ. στην C: int, float, double, char, long. –Δομημένοι τύποι (constructed types) : οι τύποι που προκύπτουν από το συνδυασμό των βασικών ή άλλων δομημένων τύπων (π.χ. δομές, πίνακες, δείκτες, κ.α.)
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-6 Εκφράσεις Τύπων Εκφράσεις τύπων (type expressions) : είναι ο φορμαλι- σμός που χρησιμοποιείται για να εκφράσει τον τύπο των δομών μίας γλώσσας. Ορίζεται με βάση τις ακόλουθες συμβάσεις: 1. Ένας βασικός τύπος αποτελεί έκφραση τύπου. 2. To όνομα ενός τύπου, π.χ. struct point {…}, αποτελεί έκφραση τύπου. Δηλ. η έκφραση τύπου για το προηγούμενο παράδειγμα είναι point. 3. Για την διευκόλυνση του ελέγχου χρησιμοποιούνται οι ακόλουθες εκφράσεις τύπων που αντιστοιχούν σε βασικούς τύπους: –type_error : για να δηλώσει την ύπαρξη λάθους –void : για να δηλώσει την απουσία τύπου
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-7 Εκφράσεις Τύπων - Συμβάσεις 4. Με τον όρο κατασκευαστής τύπου (type constructor) εννοούμε την αναπαράσταση με την οποία συνδέουμε τις εκφράσεις τύπων των συνιστωσών μίας δομής για να πάρουμε την έκφραση τύπου της. Έχουμε: –Δείκτες : εάν Τ είναι έκφραση τύπου, τότε pointer(T) είναι έκφραση τύπου που δηλώνει δείκτη σε αντικείμενο με τύπο Τ. –Πίνακες (arrays) : εάν Τ είναι έκφραση τύπου, τότε array(I,T) είναι έκφραση τύπου που αναφέρεται σε πίνακα αντικειμένων τύπου Τ, ο οποίος δεικτοδοτείται από το σύνολο Ι. Π.χ. η δήλωση int x[100]; αντιστοιχεί στο αναγνωριστικό x την έκφραση τύπου array(0..100, int)
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-8 Εκφράσεις Τύπων - Συμβάσεις (2) –Καρτεσιανά γινόμενα (products): εάν Τ 1 και Τ 2 είναι εκφράσεις τύπου, τότε Τ 1 x Τ 2 είναι η έκφραση τύπου της λίστας που προκύπτει από δύο αντικείμενα τύπου Τ 1 και Τ 2 αντίστοιχα. –Δομές (records) : αν f 1, f 2, …,f n είναι τα ονόματα των πεδίων μίας δομής με εκφράσεις τύπων T 1, T 2, …, T n, τότε η έκφραση τύπου της δομής είναι: record((f 1,T 1 ), (f 2,T 2 ), …,(f n, T n )) –Συναρτήσεις : η έκφραση τύπου μίας συνάρτησης που επιστρέφει αντικείμενο με έκφραση τύπου R, και δέχεται ορίσματα με εκφράσεις τύπων T 1, T 2, …, T n, είναι T 1 x T 2 x T n R Tί αντικείμενο έχει έκφραση τύπου (int int) x real int;
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-9 Συστήματα Τύπων Σύστημα τύπων ονομάζονται οι κανόνες που χρησιμοποιεί ένας μεταγλωττιστής για να αναθέσει μία έκφραση τύπου στα διάφορα κομμάτια ενός προγράμματος. Π.χ.: res = i + j * f; while(test > 0) { … } Στα παραπάνω παραδείγματα υπονοείται ότι οι εκφράσεις τύπων αποδίδονται όχι μόνο σε μεταβλητές ή δομές της γλώσσας αλλά και σε τμήματα του προγράμματος.
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-10 Έλεγχος τύπου εκφράσεων Υλοποίηση μέσω σχεδίου μετάφρασης: E = num,{E.type = integer} E = char,{E.type = char} E = id,{E.type = lookup(id.entry) } όπου η συνάρτηση lookup επιστρέφει τον τύπο που είναι αποθηκευμένος στο πίνακα συμβόλων E = “&”, E 1,{ E.type = pointer(E 1.type) } Ε = Ε 1, “mod”, E 2,{ E.type = ((E 1.type == integer) & (E 2.type == integer)) ? integer : type_error} Ε = Ε 1, “[”, Ε 2, “]”,{E.type = (E 2.type == integer) ? array(E 2.value, E 1.type) : type_error}
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-11 Έλεγχος τύπου προτάσεων S = id, “:=”, E{ S.type = (id.type == E.type) ? void : type_error } S = “if”, E, “then”, S 1 {S.type = (E.type == boolean) ? S 1.type : type_error } S = “while”, E, “do”, S {S.type = (E.type == boolean) ? S 1.type : type_error } S = S 1, “;”, S 2 { S.type = ( (S 1.type==void) & (S 2.type == void)) ? void : type_error}
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-12 Έλεγχος Τύπου Συναρτήσεων Ε = E 1, “(”, E 2, “)”{if (E 2.type == s) AND (E 1.type == s t) then Ε.type = t else Ε.type = type_error }
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-13 Mετατροπές τύπων Coersion: η μετατροπή του τύπου μίας έκφρασης που γίνεται αυτόματα από το μεταγλωττιστή (implicit - explicit). E = num,{E.type = integer} E = num, “.”, num,{E.type = real} E = id,{E.type = lookup(id.entry) } E = Ε 1, op, E 2, {if E 1.type == integer) & (E 2.type == integer) then E.type =integer elseif E 1.type == integer) & (E 2.type == real) then E.type = real... elseE.type = type_error}
ΕΠΛ223 - Θεωρία και Πρακτική Μεταγλωττιστών9-14 Υπερφόρτωση & Πολυμορφισμός Ένας τελεστής ονομάζεται υπερφορτωμένος (overloaded) όταν η σημασία του εξαρτάται από τα συμφραζόμενα: 2+5 “Hello ” + “world” Ο προσδιορισμός της πράξης που πρέπει να τελεστεί κάθε φορά ονομάζεται αναγνώριση τελεστή (operator identification). Μία διαδικασία ονομάζεται πολυμορφική όταν μπορεί να εφαρμοστεί σε διαφορετικούς τύπους ορισμάτων. Π.χ. templates της C++: template T max( T a, T b) { return( (a>b) ? a : b);} Ο ίδιος όρος μπορεί να εφαρμοστεί και σε τελεστές. Π.χ. ο τελεστής & της C.