Μεταγλωττιστές Εργαστήριο 9 Σημασιολογική Ανάλυση Διδάσκοντες: Δρ. Γεώργιος Δημητρίου Δρ. Άχμεντ Μάχντι 2016-2017
Σύνταξη και Σημασιολογία Σε οποιαδήποτε γλώσσα (προγραμματισμού ή μη) υπάρχουν δύο βασικές έννοιες: Σύνταξη: μορφή και δομή καλώς σχηματισμένων ακολουθιών συμβόλων (προγραμμάτων) Σημασιολογία: αφορά την ερμηνεία των ορθά σχηματισμένων ακολουθιών (προγραμμάτων). Στατική Σημασιολογία Εντοπισμός σημασιολογικών σφαλμάτων κατά τη διάρκεια της μεταγλώττισης Δυναμική Σημασιολογία Απόδοση ερμηνείας στα προγράμματα κατά την εκτέλεσή τους
Στατική Σημασιολογία Έλεγχος πέρα από τον συντακτικό έλεγχο για την ορθότητα ενός προγράμματος για τον εντοπισμό σημασιολογικών σφαλμάτων. Δήλωση μεταβλητής μια μόνο φορά σε μια εμβέλεια. Ορθή χρήση τελεστών σε σχέση με τον τύπο των ορισμάτων. Ύπαρξη μιας εντολής break εκτός κατάλληλου βρόγχου. κλπ.. Παράδειγμα While E do S boolean Statement
Δυναμική Σημασιολογία Απόδοση ερμηνείας σε προγράμματα που περιγράφει την συμπεριφορά τους. Τρόποι περιγραφής: Λειτουργική Σημασιολογία (operational semantics): περιγράφει συμπεριφορά σαν υπολογιστικά βήματα (π.χ., εντολή ανάθεσης). Δηλωτική Σημασιολογία (denotational semantics): περιγραφή με κάποιοα μαθηματική συνάρτηση (από το πεδίο των δεδομένων εισόδου στο πεδίο των αποτελεσμάτων). Αξιωματική Σημασιολογία (axiomatic semantics): η ερμηνεία καθορίζεται έμμεσα μέσω λογικών προτάσεων που περιγράφουν ιδιότητες του προγράμματος.
Έλεγχοι που διεξάγονται: Σημασιολογική Ανάλυση Έλεγχοι τύπων: τύποι μεταβλητών, συστήματα τύπων, κλπ. Οι τελεστές εφαρμόζονται σε κατάλληλα τελούμενα Έλεγχοι ύπαρξης ονομάτων: η χρήση μιας μεταβλητής επιτρέπεται μετά τη δήλωση της (πίνακας συμβόλων). Έλεγχοι μοναδικότητας: δύο ονόματα ετικετών, συναρτήσεων, κλπ δεν μπορούν να έχουν το ίδιο όνομα (πίνακας συμβόλων). οι σταθερές σε μια δομή case είναι μοναδικές (Pascal) Έλεγχοι συνέπειας: σε εντολές που ξεκινούν και τελειώνουν με το όνομα της δηλωθείσας δομής (begin XYZ end XYZ). Έλεγχοι ροής: π.χ., Όχι continue έξω από βρόχο (C) Οι μεταβλητές αρχικοποιούνται πριν τη χρήση τους (Java)
Υλοποίηση Σημασιολογικής Ανάλυσης Πώς γίνεται η σημασιολογική ανάλυση; Μεταγλωττιστής πολλαπλών περασμάτων: δημιουργία συντακτικού δένδρου και έπειτα έλεγχος. Μεταγλωττιστής απλού περάσματος: Η ανάλυση γίνεται σταδιακά παράλληλα με την συντακτική ανάλυση. Θεωρητικά υπάρχει η ανάγκη για υποστήριξη όλων των παραπάνω από κάποιου είδους γραμματικής.
Συστήματα Τύπων Σύστημα τύπων (type system): διαχείριση και έλεγχος τύπων. Βασικοί τύποι (basic types): πρωταρχικοί τύποι της γλώσσας. integer, boolean, real, char. Σύνθετοι τύποι (composite types): τύποι που προκύπτουν από "κατασκευαστές τύπων" με συνδυασμό άλλων τύπων: Πίνακες, Καρτεσιανά γινόμενα, εγγραφές, δείκτες, συναρτήσεις.
Συστήματα Τύπων Περιορισμοί στη κατασκευή τύπων: πχ. διάσταση πινάκων, επιστροφή τιμών από συναρτήσεις, κλπ. Οι τύποι που δεν υπόκεινται σε περιορισμούς ονομάζονται τύποι πρώτης τάξης (first class types). Τυποκρατική περιγραφή των συστημάτων τύπων περιλαμβάνει την έννοια περιβάλλοντα τύπων (type environments). Εξαγωγή τύπων βάσει κανόνων για εκφράσεις. var x,y : int { x integer, y real}
Τύποι και Έλεγχοι Δύο είδη μετατροπών: ρητή μετατροπή τύπου (type casting): ο προγραμματιστής δηλώνει ρητά την μετατροπή. έμμεση μετατροπή τύπου (type coersion): που η μετατροπή αποφασίζεται από το μεταγλωττιστή αν είναι επιτρεπτή. Υπερφόρτωση τελεστών: τελεστής διεξάγει δύο παρεμφερείς αλλά διαφορετικές πράξεις. Μεταγλωττιστής πρέπει να ελέγξει την σωστή χρήση υπερφόρτωσης. Παράδειγμα τελεστής "+"
Τύποι και Έλεγχοι Πολυμορφικοί τελεστές: υλοποιούν την ίδια πράξη αλλά με διαφορετικού τύπου ορίσματα. πχ. τελεστής αποδεικτοδότητησης (dereferencing) Αν Ε είναι δείκτης σε τύπο τ, τότε ^Ε είναι τύπου τ. Συνώνυμα τύπων Ισοδυναμία τύπων (χρήση χωρίς μετατροπή) Δομική ισοδυναμία (σχηματίζονται με τον ίδιο κατασκευαστή) Ονομαστική Ισοδυναμία Υποσύνολα τύπων πχ. var i : 1..100 (υποσύνολο τύπου integer)
Παραδείγματα: απλές εκφράσεις βασικοί έλεγχοι Σημασιολογική Ανάλυση στο bison Παράδειγμα: Υπολογισμός του πεδίου type %{typedef enum { TY_int, TY_real, TY_bool } Type;%} %union{char * n; Type t; struct { Type type; /* other fields */ } v; } %type<n> T_id %type<t> typename %type<v> expression expression : T_intconst { $$.type = TY_int; } expression : T_id T_realconst { $$.type = TY_real;} ( expression ) { $$.type = $2.type; } ; Έλεγχοι: 1- έχει δηλωθεί το T_id στον πίνακα συμβόλων? 2- τι τύπο έχει?
Παραδείγματα: Βασικοί έλεγχοι expression : T_id expression : T_id { Entry * id = lookup($1); if (id!= NULL && id->kind == K_variable) $$.type = id->type; else yyerror("identifier not found"); } ;
Παραδείγματα: Βασικοί έλεγχοι expression : expression "mod" expression { if ($1.type == TY_int && $3.type == TY_int) $$.type = TY_int; Έλεγχος συμβατότητας μεταβλητών else yyerror("type mismatch"); } ; statement : "while" expression "do" statement { if ($2.type!= TY_bool) } ; yyerror("condition type mismatch") Θα πρέπει το expression να είναι τύπου bool
Παραδείγματα: Μετατροπή τύπων /*Type casting */ expression : '(' typename ')' expression { if (iscastallowed($2, $4.type)) $$.type = $2; else yyerror("illegal type cast"); } ; Συνάρτηση ελέγχου
Παραδείγματα: Υπερφόρτωση Τελεστών Ε = Ε1 + Ε2 expression : expression '+' expression { if ($1.type == TY_int) if ($3.type == TY_int) $$.type = TY_int; else if ($3.type == TY_real) $$.type = TY_real; else yyerror("type mismatch"); else if ($1.type == TY_real) if ($3.type == TY_int) $$.type = TY_real; else if ($3.type == TY_real) $$.type = TY_real; else yyerror("type mismatch"); else yyerror("type mismatch"); } ;
Παράδειγμα: Αποδοτική υλοποίηση var x : int; var_decl: "var" T_id ':' T_type ';' {if (!addvar($2, $4)) { printf("variable:: %s on line %d. ",$2,line); yyerror("var already defined");} } ;/* addvar προσθέτει μια μεταβλητή στο πίνακα συμβόλων. */ expr: term { $$.type = $1.type; } expr '+' term {$$.type = typedefinition($1.type, $3.type);} ; term: factor { $$.type = $1.type; } term '*' factor { $$.type = typedefinition($1.type, $3.type);} ;
Εργαστηριακή Άσκηση 9 Γράψτε την συνάρτηση typedefinition η οποία ελέγχει τους τύπους των μεταβλητών στο αριστερό μέρος και επιστρέφει τον τύπο του δεξιού μέρος. Δίνεται η παρακάτω δήλωση τύπων των tokens ParType typedefinition(partype, ParType); %union { int i_val; double f_val; char * id; ParType tokentype; struct { int i_value; ParType type; } se; } Επίσης, πώς μπορεί να ενσωματωθεί η συντακτική ανάλυση έτσι ώστε να χρησιμοποιεί την δομή του Αφηρημένου Συντακτικού Δέντρου?