ΠΑΝΕΠΙΣΤΗΜΙΟ ΜΑΚΕΔΟΝΙΑΣ ΟΙΚΟΝΟΜΙΚΩΝ ΚΑΙ ΚΟΙΝΩΝΙΚΩΝ ΕΠΙΣΤΗΜΩΝ ΤΜΗΜΑ ΕΦΑΡΜΟΣΜΕΝΗΣ ΠΛΗΡΟΦΟΡΙΚΗΣ ΓΛΩΣΣΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ ΜΕΤΑΓΛΩΤΤΙΣΤΕΣ Τελικές Εξετάσεις Απαντήστε όλα τα θέματα του Μέρους Α και ένα θέμα από το Μέρος Β. Μέρος Α Παρασκευή 1η Φεβρουαρίου 2008 Διάρκεια Εξέτασης: 2 ώρες 15:00-17:00 Θέμα 1: Δώστε τις Κανονικές Εκφράσεις που παράγουν τις συμβολοσειρές που ακολουθούν. 1 α) Αριθμούς στο δεκαεξαδικό σύστημα (hex) οι οποίοι δεν ξεκινούν με 0 και περιέχουν τουλάχιστον ένα σύμβολο. πχ. 10, 1Β3, 1FA12 είναι αποδεκτές συμβολοσειρές ενώ η 010 και 1G34 είναι μη-αποδεκτές. [Α-F1-9][Α-F0-9]* β) Όρους (ονόματα) που ξεκινούν με ένα χαρακτήρα ακολουθούμενο από μηδέν ή περισσότερους χαρακτήρες ή ψηφία (αριθμούς) οι οποίοι έχουν είναι δυνατό να έχουν σαν επίθεμα μια ακολουθία από ένα ή περισσότερους χαρακτήρες μέσα σε παρενθέσεις. Πχ. αποδεκτές συμβολοσειρές είναι οι more12(less), father(john), john, a, b1, ενώ μη αποδεκτές οι 23more(we), father(12), 45. [a-za-z][a-za-z0-9]*( \( [a-za-z]+\) )? γ) Άρτιους αριθμούς. Το μηδέν δεν θεωρείται άρτιος και κανένας αριθμός δεν ξεκινά με 0. Πχ. 24, 36, 4, 2, 10, 0152 είναι αποδεκτές συμβολοσειρές, ενώ οι 0, 3, 9, 21, 27, 97 δεν είναι. [2468] ([1-9][0-9]*[02468]) 1 Στις ερωτήσεις ο όρος χαρακτήρας αναφέρεται στους ACII χαρακτήρες στους κεφαλαίους και πεζούς χαρακτήρες από a έως z και ο όρος ψηφίο στα αριθμητικά ψηφία 0 έως 9. 1/9
Θέμα 2: Έστω η γραμματική με T = {0,1,e,c} N = {, A,B} και P = {::=1A 0B, A::=1A cb e, B::=0B ca e}. α) Τι τύπου σύμφωνα με την ιεραρχία Chomsky είναι η γραμματική; Δικαιολογήστε την απάντηση σας. είναι τύπου 3, γιατί αποτελείται από κανόνες της μορφής Α::=αΒ, Α::=α, όπου α τερματικό σύμβολο και Α,Β μη-τερματικά. β) Τι συμβολοσειρές αναγνωρίζει η γραμματική; συμβολοσειρές της μορφής (1(c0*c 1)*(e c0*e)) (0(c1*c 0)*(e c1*e)) ή 1+e (0 1+c)(0 c1*c)*(e c1*e) (η απάντηση μπορούσε να δοθεί και περιγραφικά). γ) Δώστε το αντίστοιχο αυτόματο. 1 1 A e c c Qf 0 B e 0 2/9
Θέμα 3: Έστω η γραμματική με Block::="begin" ts "end" ts ::= ts ::= "repeat" Block "until" Exp "print" "id" "id" "+" Exp::= "id" "<" "num" "id" ">" "num" Δώστε τα συντακτικά δένδρα των ακόλουθων συμβολοσειρών α) id + Block id + β) begin id + print id end Block begin ts end ts print id id + γ) repeat begin id + print id end until id < num Block begin repeat Block ts until end id E < num ts print id id + 3/9
δ) Είναι η παραπάνω γραμματική LL; Δικαιολογήστε σύντομα την απάντηση σας. Η γραμματική δεν είναι LL καθώς είναι αριστερά αναδρομική ts ::= ts και υπάρχει κανόνας ο οποίος στο δεξιό μέλος ξεκινά με το ίδιο σύμβολο: Exp::= "id" < "num" "id" > "num" ε) Μετατρέψτε την παραπάνω γραμματική σε LL με κατάλληλους μετασχηματισμούς. Block::="begin" ts "end" ts ::= ts' ts'::= ts' ε (απαλοιφή αριστερής αναδρομής) ::= "repeat" Block "until" Exp "print" "id" "id" "+" Exp::= "id" Exp' Exp'::= "<" "num" ">" "num" (παραγοντοποίηση) 4/9
Θέμα 4: Έστω η γραμματική που ακολουθεί: ::="{"A"}" A :: "a""a" "b" A "c" ε α) Υπολογίστε τα σύνολα FIRT και FOLLOW για τα μη-τερματικά σύμβολα και Α. FIRT(A)={a,b,ε} FIRT() = { { } FOLLOW(A)={ },c} FOLLOW()={EOF}. β) Δώστε τον αλγόριθμο αναδρομικής κατάβασης (recursive descent) που αναγνωρίζει την παραπάνω γραμματική. Θεωρείστε ότι έχετε την συνάρτηση match(t) και nexttoken() καθώς και την συνάρτηση syntaxanalysis() (στην οποία πρέπει να συμπληρώσετε μια κλήση) όπως φαίνονται παρακάτω: void syntaxanalysis() token = nexttoken()... (); if token =\= EOF then syntax_error match(t : token) if lookahead = t then lookahead := nexttoken() else syntax_error void () if token = { then match({) call A() match(}) else syntax_error void A() if token = a then match(a) match(a) elseif token = b then match(b) call A() match(c) elseif token not_in { c,} } then syntax_error β) Τι είναι τα εγγραφήματα δραστηριοποίησης και τι πληροφορία περιέχουν; Γιατί είναι απαραίτητα; Η πληροφορία στην στοίβα οργανώνεται σε εγγραφήματα δραστηριοποίησης. (Activation records / frames). Η οργάνωση αυτή επιτρέπει το φώλιασμα δομικών μονάδων. Αποθήκευση πληροφορίας σχετικής με κλήση υποπρογραμμάτων. Παράμετροι Αποτελέσματα Σύνδεσμος προσπέλασης Διεύθυνση επιστροφής Προηγούμενη τιμή δείκτη πλαισίου Τοπικά δεδομένα/μεταβλητές Προσωρινές μεταβλητές Kατά την μεταγλώττιση δεν είναι γνωστή η ακριβής θέση μνήμης των πληροφορίων. α) Η τοποθέτηση των παραμέτρων και των μεταβλητών με τον τρόπο αυτό, επιτρέπει την προσπέλαση τους χρησιμοποιώντας σχετικές διευθύνσεις (με βάση την διεύθυνση του εγγραφήματος δραστηριοποίησης), που είναι γνωστές κατά την μεταγλώττιση. β) Επιτρέπει την αναδρομική εκτέλεση διαδικασιών. γ) Ανακτά τον διαθέσιμο χώρο στη μνήμη όταν η διαδικασία τελειώσει την εκτέλεση της. δ) Επιτρέπει στην καλούσα (callee) διαδικασία να έχει πρόσβαση στο αποτέλεσμα. 5/9
Μέρος Β (Επιλέξτε μόνο ένα θέμα (5 ή 6) από τα δύο που ακολουθούν) Θέμα 5: Έστω η επαυξημένη γραμματική που ακολουθεί: '::= (1) ::="{"A"}" (2) A :: "a""a" (3) A ::= "b" A "c" α) Υπολογίστε την αρχική κατάσταση Ι 0 και τις συναρτήσεις GOTO(I 0,) και GOTO(I 0,{ ) για την παραπάνω γραμματική κατά τη δημιουργία ενός LR πίνακα. Το στοιχείο Ι 0 δίνεται από Ι 0 =CLOURE('::= ) = { '::=, ::= {A} } H GOTO(I 0,) = CLOURE(::= ) = {::= } = I 1 H GOTO(I 0,{) = CLOURE(::= { A}) = {::= { A}, A :: "a""a" "b" A "c"} = I 2 β) Δεδομένου του LR πίνακα της γραμματικής που δίνεται παρακάτω, δείξτε τα βήματα που θα κάνει ένας LR συντακτικός αναλυτής για να αναλύσει την συμβολοσειρά {bbaacc} a b c { } EOF A 0 s2 1 1 acc 2 s4 s5 3 3 s6 4 s7 5 s4 s5 8 6 r1 7 r2 r2 8 s9 9 r3 r3 Στοίβα Είσοδος Ενέργεια 0 {bbaacc}eof s2 0{2 bbaacc}eof s5 0{2b5 baacc}eof s5 0{2b5b5 aacc}eof s4 0{2b5b5a4 acc}eof s7 0{2b5b5a4a7 cc}eof reduce με τον κανόνα 2 0{2b5b5Α8 cc}eof s9 0{2b5b5Α8c9 c}eof reduce με τον κανόνα 3 0{2b5A8 c}eof s9 0{2b5A8c9 }EOF reduce με τον κανόνα 3 0{2A3 }EOF s6 0{2A3}6 EOF reduce με τον κανόνα 1 01 EOF acc 6/9
γ) Για τη συγκεκριμένη γραμματική και LR πίνακα, αν η στοίβα περιέχει τα στοιχεία 0{2 (με το 2 στην κορυφή της στοίβας) και το επόμενο σύμβολο εισόδου είναι το Α σύμβολο της γραμματικής τότε ποια είναι η επόμενη κίνηση; Δεν είναι δυνατό η συμβολοσειρά εισόδου να περιέχει μη-τερματικά σύμβολα. Άρα η παραπάνω κατάσταση είναι αδύνατη. δ) Τι είναι ο ενδιάμεσος κώδικας και ποιοι οι λόγοι που οδηγούν στη δημιουργία του; Στην συνηθέστερη περίπτωση ο μεταγλωττιστής παράγει ενδιάμεσο κώδικα. Ενδιάμεσος κώδικας είναι εκφρασμένος σε μια γλώσσα χαμηλότερου επιπέδου από την αρχική, αλλά υψηλότερου επιπέδου από τη γλώσσα μηχανής. Λόγοι που οδηγούν στη δημιουργία του ενδιάμεσου κώδικα: 1. Διαχωρισμός εμπρόσθιου (front-end) και οπίσθιου μέρους (back-end) του μεταγλωττιστή, άρα διευκόλυνση υλοποίησης μεταγλωττιστών. 2. Επαναχρησιμοποίηση κώδικα. 3. Ευκολότερη μετάφραση. 4. Ευκολότερη βελτιστοποίηση κώδικα. 7/9
Θέμα 6: Έστω μέρος μιας γραμματικής η οποία παράγει ενδιάμεσο κώδικα. E ::= "id" {p = lookup(id.lexeme); if p!= nil then E.place = p else error} B ::= Ε 1 "<" Ε 2 {B.truelist := makelist(nextquad); genquad(<,ε 1.place,Ε 2.place,*) B.falselist := makelist(nextquad); genquad(jump,-,-,*);} B::=B 1 "and" { backpatch(b 1.truelist;nextQuad);} B 2 {B.truelist := B 2.truelist; B.falselist := merge(b 1.falselist,B 2.falselist) } α) Σε ποιο μέρος του μεταγλωττιστή αναφέρεται η συνάρτηση lookup; Η συνάρτηση αναφέρεται στον πίνακα συμβόλων. b) Τι κάνει η συνάρτηση backpatch και γιατί είναι αναγκαία η χρήση της; Εξηγήστε βάσει της παραπάνω γραμματικής. Όπως είναι φανερό από η Β1 μπορεί να χρειάζεται για τη μετάφραση της αυθαίρετα μεγάλο αριθμό τετράδων για τη μετάφραση της. Σε κάποιες από αυτές τις τετράδες, "βεβαιώνεται" ότι η τιμή της Β1 είναι true και πρέπει να γίνουν τα αντίστοιχα άλματα. Δεν είναι γνωστό κατά τη δημιουργία των τετράδων το που (τετράδα αμέσως μετά εκείνες της Β1)! backpatching: Ανατρέχει τις τιμές αποθηκευμένες στη λίστα (truelist/falselist) όταν είναι γνωστή η τιμή και θέτει τις ανάλογες τιμές (τετράδες jump) γ) Αν η αρχική συμβολοσειρά εισόδου είναι x < y and z < y δώστε τον κώδικα που παράγεται για το συγκεκριμένη συμβολοσειρά βάσει της παραπάνω γραμματικής, δίνοντας παράλληλα τα περιεχόμενα των Β1.truelist, B1.falselist, Β2.truelist, B2.falselist, Β.falselist, B.truelist και πιθανές εφαρμογές του backpatching. Θεωρείστε ότι η αρίθμηση ξεκινά από το 100. 100: <,x,y,* Β1.truelist = {100} 110: jump,-,-,* B1.falselist = {110} 120: <,z,y,* B2.truelist = {120} 130: jump,-,-,* B2.falselist = {130} B.truelist = B2.truelist ={120} B.falselist = merge(b 1.falselist,B 2.falselist) = {110,130} Εφαρμογή του backpatching: backpatch(b1.truelist) = 120 άρα ο τελικός κώδικας είναι 100: <,x,y,120 Β1.truelist = {100} 110: jump,-,-,* B1.falselist = {110} 120: <,z,y,* B2.truelist = {120} 130: jump,-,-,* B2.falselist = {130} B.truelist = B2.truelist ={120} B.falselist = merge(b 1.falselist,B 2.falselist) = {110,130} 8/9
δ) Αν έπρεπε να κατασκευάσετε μια γλώσσα για μια νέα υπολογιστική πλατφόρμα η οποία στερείται εργαλείων όπως το FLEX και BION, αλλά έχει ήδη μια γλώσσα προγραμματισμού τι είδους γραμματική και ποια προσέγγιση στη συντακτική ανάλυση θα επιλέγατε; Δικαιολογήστε την απάντησή σας. Η επιλογή θα ήταν LL και συντακτική ανάλυση από πάνω προς τα κάτω καθώς είναι εύκολη η υλοποίηση της με τον αλγόριθμο αναδρομικής κατάβασης. ε) Σε ποια φάση της μεταγλώττισης γίνεται ο έλεγχος τύπων; Τι είδους γραμματικές χρησιμοποιούνται; Ο έλεγχος τύπων γίνεται κατά την σημασιολογική ανάλυση. Οι γραμματικές που χρησιμοποιούνται είναι γραμματικές ιδιοτήτων, στις οποίες σε κάθε σύμβολο της γλώσσας ανατίθενται ιδιότητες. 9/9