HY340 : ΓΛΩΣΣΕΣ ΚΑΙ ΜΕΤΑΦΡΑΣΤΕΣ ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ, ΣΧΟΛΗ ΘΕΤΙΚΩΝ ΕΠΙΣΤΗΜΩΝ, ΤΜΗΜΑ ΕΠΙΣΤΗΜΗΣ ΥΠΟΛΟΓΙΣΤΩΝ ΔΙΔΑΣΚΩΝ Αντώνιος Σαββίδης
HY340 : ΓΛΩΣΣΕΣ ΚΑΙ ΜΕΤΑΦΡΑΣΤΕΣ Φροντιστήριο 4ο Παραγωγή Ενδιάμεσου Κώδικα HY340, 2009 Α. Σαββίδης Slide 2 / 143
Κώδικας τριών διευθύνσεων Περιγραφή ενός πολύπλοκου προγράμματος με μία ακολουθία απλών εντολών Περιγραφή ενός πολύπλοκου προγράμματος με μία ακολουθία απλών εντολών Οι εντολές είναι συνήθως λίγες Οι εντολές είναι συνήθως λίγες Έχουν πανομοιότυπη μορφή Έχουν πανομοιότυπη μορφή Εντολή, αποτέλεσμα, τελεστής 1, τελεστής 2 Είναι πολύ “κοντά” στην γλώσσα μηχανής Είναι πολύ “κοντά” στην γλώσσα μηχανής Σε πολλές από τις εντολές η αντιστοίχηση με τις τελικές εντολές μηχανής είναι 1 – 1 HY340, 2009 Α. Σαββίδης Slide 3 / 143
Απλός υπολογιστής Έστω ότι θέλουμε, στο calculator, αντί να υπολογίζουμε άμεσα το αποτέλεσμα, των πράξεών μας Έστω ότι θέλουμε, στο calculator, αντί να υπολογίζουμε άμεσα το αποτέλεσμα, των πράξεών μας Να παράγουμε σαν έξοδο ένα ισοδύναμο πρόγραμμα που θα περιγράφεται από μια ακολουθία εντολών κώδικα τριών διευθύνσεων Να παράγουμε σαν έξοδο ένα ισοδύναμο πρόγραμμα που θα περιγράφεται από μια ακολουθία εντολών κώδικα τριών διευθύνσεων Το πρόγραμμα εξόδου θα μπορεί να εκτελεστεί από ένα πολύ απλό πρόγραμμα (virtual machine) Θα μπορούμε να εκτελούμε το πρόγραμμα και να παίρνουμε αποτελέσματα πολύ πιο γρήγορα HY340, 2009 Α. Σαββίδης Slide 4 / 143
Εντολές (1/2) ADD $1, $2, $3 ADD $1, $2, $3 Προσθέτει το $2 με το $3 και αποθηκεύει το αποτέλεσμα στο $1 Προσθέτει το $2 με το $3 και αποθηκεύει το αποτέλεσμα στο $1 SUB $1, $2, $3 SUB $1, $2, $3 Αφαιρεί το $3 από το $2 και αποθηκεύει το αποτέλεσμα στο $1 Αφαιρεί το $3 από το $2 και αποθηκεύει το αποτέλεσμα στο $1 MUL $1, $2, $3 MUL $1, $2, $3 Πολλαπλασιάζει το $2 με το $3 και αποθηκεύει το αποτέλεσμα στο $1 Πολλαπλασιάζει το $2 με το $3 και αποθηκεύει το αποτέλεσμα στο $1 DIV $1, $2, $3 DIV $1, $2, $3 Διαιρεί το $3 από το $2 και αποθηκεύει το αποτέλεσμα στο $1 Διαιρεί το $3 από το $2 και αποθηκεύει το αποτέλεσμα στο $1 HY340, 2009 Α. Σαββίδης Slide 5 / 143
Εντολές (2/2) NEG $1 $2 NEG $1 $2 Αποθηκεύει στο $1 τον αντίθετο του $2 Αποθηκεύει στο $1 τον αντίθετο του $2 RES $1 RES $1 Τυπώνει το $1 στην οθόνη Τυπώνει το $1 στην οθόνη ASS $1 $2 ASS $1 $2 Αναθέτει την τιμή του $2 στο $1 Αναθέτει την τιμή του $2 στο $1 Επίσης Επίσης Οι τελεστές των εντολών, μπορούν να είναι Οι τελεστές των εντολών, μπορούν να είναι Μεταβλητές (που υπάρχουν στο symbol table του calculator) Σταθερές τιμές HY340, 2009 Α. Σαββίδης Slide 6 / 143
Μορφή ενδιάμεσου κώδικα (1/4) Όλες οι εντολές μας δέχονται το ΠΟΛΥ 2 τελεστές Όλες οι εντολές μας δέχονται το ΠΟΛΥ 2 τελεστές Επομένως θα πρέπει να τεμαχίζουμε τις εντολές της μορφής x = * 3 / 2 – 8 σε ακολουθίες των προηγούμενων εντολών οι οποίες θα παράγουν τελικά ακριβώς το ίδιο αποτέλεσμα Επομένως θα πρέπει να τεμαχίζουμε τις εντολές της μορφής x = * 3 / 2 – 8 σε ακολουθίες των προηγούμενων εντολών οι οποίες θα παράγουν τελικά ακριβώς το ίδιο αποτέλεσμα Θα πρέπει να αποθηκεύουμε κάπου τα “ενδιάμεσα” αποτελέσματα Θα πρέπει να αποθηκεύουμε κάπου τα “ενδιάμεσα” αποτελέσματα Θα πρέπει να εισάγουμε προσωρινές μεταβλητές για μπορούμε να περιγράψουμε την παραπάνω έκφραση με κώδικα τριών διευθύνσεων HY340, 2009 Α. Σαββίδης Slide 7 / 143
Μορφή ενδιάμεσου κώδικα (2/4) Παράδειγμα Παράδειγμα x = * 3 / 2 – 8 x = * 3 / 2 – 8 MULx, 4, 3 DIVx, x, 2 ADDx, x, 5 SUBx, x, 8 x = * 3 / 2 – 8 x = * 3 / 2 – 8 MULtmp1, 4, 3 DIVtmp1, tmp1, 2 ADDtmp1, tmp1, 5 SUBtmp1, tmp1, 8 ASSx, tmp1 ADD res, arg1, arg2 SUB res, arg1, arg2 MUL res, arg1, arg2 DIV res, arg1, arg2 NEG res, arg1 RES arg1 ASS res, arg1 HY340, 2009 Α. Σαββίδης Slide 8 / 143
Μορφή ενδιάμεσου κώδικα (3/4 ) Ή εάν δεν προσπαθήσουμε να ελαχιστοποιήσουμε τη χρήση προσωρινών μεταβλητών Ή εάν δεν προσπαθήσουμε να ελαχιστοποιήσουμε τη χρήση προσωρινών μεταβλητών x = * 3 / 2 – 8 x = * 3 / 2 – 8 MULtmp1, 4, 3 DIVtmp2, tmp1, 2 ADDtmp3, tmp2, 5 SUBtmp4, tmp3, 8 ASSx, tmp4 Στην πράξη δεν είναι εύκολο να ξέρουμε πότε μπορούμε optimally να επανα-χρησιμοποιήσουμε μία προσωρινή μεταβλητή Στην πράξη δεν είναι εύκολο να ξέρουμε πότε μπορούμε optimally να επανα-χρησιμοποιήσουμε μία προσωρινή μεταβλητή HY340, 2009 Α. Σαββίδης Slide 9 / 143
Μορφή ενδιάμεσου κώδικα (4/4) Είμαστε σίγουροι όμως ότι όταν τελειώσουμε τον υπολογισμό μιας συγκεκριμένης έκφρασης και αποθηκεύσουμε το αποτέλεσμα στην κατάλληλη μεταβλητή, οι προσωρινές μεταβλητές μπορούν να επανα-χρησιμοποιηθούν. Είμαστε σίγουροι όμως ότι όταν τελειώσουμε τον υπολογισμό μιας συγκεκριμένης έκφρασης και αποθηκεύσουμε το αποτέλεσμα στην κατάλληλη μεταβλητή, οι προσωρινές μεταβλητές μπορούν να επανα-χρησιμοποιηθούν. HY340, 2009 Α. Σαββίδης Slide 10 / 143
Βοηθητικές δομές HY340, 2009 Α. Σαββίδης Slide 11 / 143
Αλλαγές στο union του yacc HY340, 2009 Α. Σαββίδης Slide 12 / 143
Βοηθητικές συναρτήσεις (1/2) HY340, 2009 Α. Σαββίδης Slide 13 / 143
Βοηθητικές συναρτήσεις (2/2) HY340, 2009 Α. Σαββίδης Slide 14 / 143
Παράδειγμα σε κανόνες (1/4) HY340, 2009 Α. Σαββίδης Slide 15 / 143
Παράδειγμα σε κανόνες (2/4) a = * 2; a + 55; HY340, 2009 Α. Σαββίδης Slide 16 / 143
Παράδειγμα σε κανόνες (3/4) a = * 2; a + 55; HY340, 2009 Α. Σαββίδης Slide 17 / 143
Παράδειγμα σε κανόνες (4/4) a = * 2; a + 55; HY340, 2009 Α. Σαββίδης Slide 18 / 143
Runtime Checking (1/3) Η γλώσσα alpha είναι μια dynamically typed γλώσσα (ο τύπος μιας μεταβλητής αλλάζει ακολουθώντας τον τύπο της τιμής που κάθε φορά αποθηκεύεται σε αυτήν) επομένως δεν μπορούμε κατά την μεταγλώττιση να εφαρμόσουμε έλεγχο τύπων. Η γλώσσα alpha είναι μια dynamically typed γλώσσα (ο τύπος μιας μεταβλητής αλλάζει ακολουθώντας τον τύπο της τιμής που κάθε φορά αποθηκεύεται σε αυτήν) επομένως δεν μπορούμε κατά την μεταγλώττιση να εφαρμόσουμε έλεγχο τύπων. if (x > 12) a = false; else a = 3.33; b = (a and c);// ? x = input(); y = !x;// ? HY340, 2009 Α. Σαββίδης Slide 19 / 143
Runtime Checking (2/3) Δεν μπορούμε να υλοποιήσουμε πλήρη έλεγχο at compile time, για το λόγο αυτό ο έλεγχος θα γίνει at runtime. Δεν μπορούμε να υλοποιήσουμε πλήρη έλεγχο at compile time, για το λόγο αυτό ο έλεγχος θα γίνει at runtime. Στην περίπτωση των σταθερών εκφράσεων προαιρετικά ο έλεγχος μπορεί να γίνει at compile time. Στην περίπτωση των σταθερών εκφράσεων προαιρετικά ο έλεγχος μπορεί να γίνει at compile time. a = true + 12; // Boolean + Number Error a = true + 12; // Boolean + Number Error b = “str1” + false;// String + Boolean Error b = “str1” + false;// String + Boolean Error HY340, 2009 Α. Σαββίδης Slide 20 / 143
Runtime Checking (3/3) HY340, 2009 Α. Σαββίδης Slide 21 / 143
Alpha i-code (1/3) enum iopcode { assign, add, sub, mul, div, mod, not, if_eq, if_noteq, … }; struct quad { iopcodeop; expr*res;///< result temporary (e.g. add, sub, etc) expr*arg1;///< first operant (e.g. add, sub, etc) expr*arg2;///< second operant (e.g. add, sub, etc) unsignedlabel;///< target label (e.g. jump, if_eq, etc) unsignedline;}; struct quad quads[MAX_QUADS]; κάθε quad μπορεί να έχει label ίδιο με τη θέση του στον πίνακα κάθε quad μπορεί να έχει label ίδιο με τη θέση του στον πίνακα HY340, 2009 Α. Σαββίδης Slide 22 / 143
Alpha i-code (2/3) enum expr_t { var_e, tableitem_e, programfunc_e, libraryfunc_e, … }; struct expr { expr_ttype; symbol*sym; expr* index; doublenumConst; char* strConst; char boolConst; }; Σε ένα quad μπορούμε δώσουμε τις παρακάτω τιμές: -τιμή συνάρτησης βιβλιοθήκης (όνομα) - τιμή συνάρτησης προγράμματος (διεύθυνση) - κρυφή μεταβλητή - μεταβλητή προγράμματος - σταθερή τιμή (string, number, boolean) HY340, 2009 Α. Σαββίδης Slide 23 / 143
Alpha i-code (3/3) Ο πίνακας για τα quads είναι δυναμικός, επομένως δεν έχουμε δείκτες σε quads αλλά χρησιμοποιούμε το index του κάθε quad για να αναφερθούμε σε αυτό. Ο πίνακας για τα quads είναι δυναμικός, επομένως δεν έχουμε δείκτες σε quads αλλά χρησιμοποιούμε το index του κάθε quad για να αναφερθούμε σε αυτό. … if (a > b) c = true; else c = false; … indexOpResult / Label Arg1Arg2 … 10IF_GREATER13ab 11ASSIGNcfalse 12JUMP14 13ASSIGNctrue 14 … HY340, 2009 Α. Σαββίδης24/143
HY Γλώσσες και Μεταφραστές Φροντιστήριο Intermediate Code
if statement if (expr) stmt skip if go if HY340, 2009 Α. Σαββίδης Slide 26 / 143
if..else statement if (expr) stmt else stmt HY340, 2009 Α. Σαββίδης Slide 27 / 143
while statement while (expr) stmt break list continue list HY340, 2009 Α. Σαββίδης Slide 28 / 143
for statement for (elist1; expr; elist2) stmt break list continue list false true loop closure HY340, 2009 Α. Σαββίδης Slide 29 / 143
Ενδεικτικό παράδειγμα Ενδεικτικό παράδειγμα HY340, 2009 Α. Σαββίδης Slide 30 / 143