ΗΥ-340 Γλώσσες και Μεταφραστές Φροντιστήριο Syntax Directed Translation and alpha Language
alpha Language(1/5) Στην alpha δεν υπάρχει main() συνάρτηση, ο κώδικας ξεκινάει την εκτέλεση από την αρχή του αρχείου προς τα κάτω. Μία συνάρτηση μπορεί να καλεστεί με διαφορετικό αριθμό actual args από τον αριθμό των formal args της. Με την χρήση των library functions ‘totalarguments()’ και ‘arguments’ μπορούμε να δούμε όλα τα actual arguments με τα οποία καλέστηκε μία συνάρτηση.
Βασικό construct της γλώσσας είναι οι πίνακες (tables). Το library function ‘objecttotalmembers()’ επιστρέφει το πλήθος των στοιχείων ενός πίνακα. Οι πίνακας είναι μία associative δομή που συσχετίζει keys με data. By default τα keys είναι ακέραιοι 0 – Ν όπως και στην C/C++. Ωστόσο key σε ένα table μπορεί να είναι οποιοδήποτε στοιχείο της γλώσσας. alpha Language(2/5)
Ειδικά για τα members των associative tables με key_type string μπορούμε να τα κάνουμε access και με την χρήση του operator ‘.’ Η προσθήκη ενός νέου ζευγαριού {key,data} στο table γίνεται απλά με την αναφορά/χρήση αυτού. Κάνοντας assign την τιμή nil σε ένα member ενός table αυτό καταστρέφεται. Το key “()” έχει ειδική σημασία για τους tables στην alpha –όταν ένας table έχει αυτό το key και το data είναι ένα function τότε αν γίνει call του table θα κληθεί αυτή η συνάρτηση –επιπλέον σε αυτή την περίπτωση η συνάρτηση καλείται με ένα επιπλέον actual argument, το ίδιο το table, το οποίο είναι μάλιστα το πρώτο στην λίστα των arguments alpha Language(3/5)
Δεν υπάρχει η έννοια του class στην alpha, μπορούμε ωστόσο να προσομοιώσουμε την έννοια του object. Η έννοια του object είναι implicit στην γλώσσα και υποστηρίζονται με χρήση των tables. Τα αντικείμενα δημιουργούνται με βάση patterns πάνω στην γλώσσα όπως η δημιουργία generator functions οι οποίες επιστρέφουν αντίγραφα ενός αντικειμένου / προτύπου. alpha Language(4/5)
alpha Language(5/5)
ΗΥ – 340 Γλώσσες και Μεταφραστές Φροντιστήριο Παραγωγή ενδιάμεσου κώδικα
Κώδικας τριών διευθύνσεων Περιγραφή ενός πολύπλοκου προγράμματος με μία ακολουθία απλών εντολών –Οι εντολές είναι συνήθως λίγες –Έχουν πανομοιότυπη μορφή Εντολή, αποτέλεσμα, τελεστής 1, τελεστής 2 –Είναι πολύ “κοντά” στην γλώσσα μηχανής Σε πολλές από τις εντολές η αντιστοίχηση με τις τελικές εντολές μηχανής είναι 1 – 1
Απλός υπολογιστής Έστω ότι θέλουμε, στο calculator, αντί να υπολογίζουμε άμεσα το αποτέλεσμα, των πράξεών μας –Να παράγουμε σαν έξοδο ένα ισοδύναμο πρόγραμμα που θα περιγράφεται από μια ακολουθία εντολών κώδικα τριών διευθύνσεων Το πρόγραμμα εξόδου θα μπορεί να εκτελεστεί από ένα πολύ απλό πρόγραμμα (virtual machine) Θα μπορούμε να εκτελούμε το πρόγραμμα και να παίρνουμε αποτελέσματα πολύ πιο γρήγορα
Εντολές (1/2) ADD $1, $2, $3 –Προσθέτει το $2 με το $3 και αποθηκεύει το αποτέλεσμα στο $1 SUB $1, $2, $3 –Αφαιρεί το $3 από το $2 και αποθηκεύει το αποτέλεσμα στο $1 MUL $1, $2, $3 –Πολλαπλασιάζει το $2 με το $3 και αποθηκεύει το αποτέλεσμα στο $1 DIV $1, $2, $3 –Διαιρεί το $3 από το $2 και αποθηκεύει το αποτέλεσμα στο $1
Εντολές (2/2) NEG $1 $2 –Αποθηκεύει στο $1 τον αντίθετο του $2 RES $1 –Τυπώνει το $1 στην οθόνη ASS $1 $2 –Αναθέτει την τιμή του $2 στο $1 Επίσης –Οι τελεστές των εντολών, μπορούν να είναι Μεταβλητές (που υπάρχουν στο symbol table του calculator) Σταθερές τιμές
Μορφή ενδιάμεσου κώδικα (1/4) Όλες οι εντολές μας δέχονται το ΠΟΛΥ 2 τελεστές –Επομένως θα πρέπει να τεμαχίζουμε τις εντολές της μορφής x = * 3 / 2 – 8 σε ακολουθίες των προηγούμενων εντολών οι οποίες θα παράγουν τελικά ακριβώς το ίδιο αποτέλεσμα –Θα πρέπει να αποθηκεύουμε κάπου τα “ενδιάμεσα” αποτελέσματα Θα πρέπει να εισάγουμε προσωρινές μεταβλητές για μπορούμε να περιγράψουμε την παραπάνω έκφραση με κώδικα τριών διευθύνσεων
Μορφή ενδιάμεσου κώδικα (2/4) Παράδειγμα –x = * 3 / 2 – 8 MULx, 4, 3 DIVx, x, 2 ADDx, x, 5 SUBx, x, 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
Μορφή ενδιάμεσου κώδικα (3/4) Ή εάν δεν προσπαθήσουμε να ελαχιστοποιήσουμε τη χρήση προσωρινών μεταβλητών –x = * 3 / 2 – 8 MULtmp1, 4, 3 DIVtmp2, tmp1, 2 ADDtmp3, tmp2, 5 SUBtmp4, tmp3, 8 ASSx, tmp4 Στην πράξη δεν είναι εύκολο να ξέρουμε πότε μπορούμε optimally να επανα-χρησιμοποιήσουμε μία προσωρινή μεταβλητή
Μορφή ενδιάμεσου κώδικα (4/4) Είμαστε σίγουροι όμως ότι όταν τελειώσουμε τον υπολογισμό μιας συγκεκριμένης έκφρασης και αποθηκεύσουμε το αποτέλεσμα στην κατάλληλη μεταβλητή, οι προσωρινές μεταβλητές μπορούν να επανα-χρησιμοποιηθούν.
Βοηθητικές δομές
Αλλαγές στο union του yacc
Βοηθητικές συναρτήσεις (1/2)
Βοηθητικές συναρτήσεις (2/2)
Παράδειγμα σε κανόνες (1/4)
Παράδειγμα σε κανόνες (2/4) a = * 2; a + 4;
Παράδειγμα σε κανόνες (3/4) a = * 2; a + 4;
Παράδειγμα σε κανόνες (4/4) a = * 2; a + 4;
Runtime Checking (1/3) Η γλώσσα alpha είναι μια dynamically typed γλώσσα (ο τύπος μιας μεταβλητής αλλάζει ακολουθώντας τον τύπο της τιμής που κάθε φορά αποθηκεύεται σε αυτήν) επομένως δεν μπορούμε κατά την μεταγλώττιση να εφαρμόσουμε έλεγχο τύπων. if (x > 12) a = false; else a = 3.33; b = (a and c);// ? x = input(); y = !x;// ?
Runtime Checking (2/3) Δεν μπορούμε να υλοποιήσουμε πλήρη έλεγχο at compile time, για το λόγο αυτό ο έλεγχος θα γίνει at runtime. Στην περίπτωση των σταθερών εκφράσεων προαιρετικά ο έλεγχος μπορεί να γίνει at compile time. –a = true + 12; // Boolean + Number Error –b = “str1” + false;// String + Boolean Error
Runtime Checking (3/3) Run-time Warnings / Run-time Errors –l-value = r-value –+,-,*,%,++,--,- –&&, ||, ! –>,>=,<,<= –==, != –… –(see Lecture 9)
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];
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)
Alpha i-code (3/3) Ο πίνακας για τα quads είναι δυναμικός, επομένως δεν έχουμε δείκτες σε quads αλλά χρησιμοποιούμε το index του κάθε quad για να αναφερθούμε σε αυτό. … if (a > b) c = true; else c = false; … indexOpResult / Label Arg1Arg2 … 10IF_GREATER13ab 11ASSIGNcfalse 12JUMP14 13ASSIGNctrue 14 …
HY Γλώσσες και Μεταφραστές Φροντιστήριο Intermediate Code
if statement if (expr) stmt skip if go if
if..else statement if (expr) stmt else stmt
while statement while (expr) stmt break list continue list
for statement for (elist1; expr; elist2) stmt break list continue list false true loop closure
Ενδεικτικό παράδειγμα