ΣΑ από κάτω-προς-τα-πάνω ΣΑ από κάτω-προς-τα-πάνω : αναζήτηση συμβολοσειρών που υπάρχουν στο δεξί μέρος ενός κανόνα παραγωγής και αντικατάστασή τους από το αντίστοιχο μη-τερματικό σύμβολο. Από πάνω προς τα κάτω Από κάτω προς τα πάνω ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Ηandles Handles : τμήματα (substrings) μίας συμβολοσειράς τα οποία μπορούν να αντικατασταθούν από τα αριστερά μέρη κανόνων παραγωγής, αντιστρέφοντας έτσι την παραγωγή που την δημιούργησε από το αρχικό σύμβολο S. Όλες οι συμβολοσειρές που είναι δυνατό να αντικατασταθούν δεν είναι handles. Π.χ.: έστω η γραμματική: S = “a”, A, “c”, B, “e”; A = A, “b”| “b”; B = “d”; ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Ηandles (συνέχεια) Δεξιά προτασιακή μορφή (right sentential form) ονομάζεται μία συμβολοσειρά γ, αν υπάρχει δεξιότερη παραγωγή S γ. Handle μίας δεξιάς προτασιακής μορφής γ, ονομάζεται ο κανόνας Α=β και η θέση που το β συναντάται στο γ, έτσι ώστε αν το Α αντικαταστήσει το β στην γ παίρνουμε τη δεξιά προτασιακή μορφή που προηγήθηκε στη δεξιότερη παραγωγή της γ από το S. Έτσι, εάν S α, A, w α, β, w τότε ο κανόνας Α=β και η θέση που ακολουθεί το a, αποτελούν ένα handle της συμβολοσειράς a, β, w, όπου το w περιέχει μόνο τερματικά σύμβολα. Αντίστοιχα ορίζεται και το handle μίας αριστερής προτ. μορφής. * R R R * ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Ηandle pruning Κάθε handle ισοδυναμεί με ένα εσωτερικό κόμβο του συντακτικού δένδρου. Έτσι, η αντιστροφή μίας δεξιότερης παραγωγής μπορεί να επιτευχθεί με το «κλάδεμα» (pruning) των handles της δεξιάς προτασιακής μορφής. Π.χ. Ε = Ε,“+”,E | Ε,“*”,E | “(”,E, “)” | id; ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών ΣΑ ολίσθησε-ελάττωσε Βασικό πρόβλημα της από κάτω-προς-τα-πάνω προσέγγισης είναι η επιλογή των handles: Εύρεση της κατάλληλης συμβολοσειράς Επιλογή του κατάλληλου κανόνα για αντικατάσταση της συμβολοσειράς. Συντ. Αναλυτής ολίσθησης-ελάττωσης (shift-reduce parser): χρησιμοποιεί μία στοίβα στην οποία τοποθετούνται τα σύμβολα εισόδου μέχρι να σχηματιστεί στην κορυφή της στοίβας ένα handle. Τότε, τα σύμβολα που αποτελούν το δεξί μέλος του handle αντικαθίστανται στη κορυφή της στοίβας από το αριστερό μέλος. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΣΑ ολίσθησε-ελάττωσε (συνέχεια) Ενέργειες ΣΑ “ολίσθησης-ελάττωσης”: 1. Ολίσθηση (shift) : τοποθέτηση των συμβόλων εισόδου στη στοίβα μέχρι το σχηματισμό ενός handle. 2. Ελάττωση (reduce) : αντικατάσταση του r.h.s. από το l.h.s του handle στη κορυφή της στοίβας (δεν επηρεάζει την είσοδο). 3. Αποδοχή (accept) : επιτυχής ολοκλήρωση της ΣΑ. Η συμβολοσειρά εισόδου αναγνωρίζεται όταν με την ανάγνωση του τέλους της $, η στοίβα περιέχει μόνο το αρχικό σύμβολο της γραμματικής. 4. Σφάλμα (error). Αρχικά η στοίβα περιέχει μόνο το σύμβολο $ σε αντίθεση με την προσέγγιση LL(1) όπου η στοίβα περιέχει τα $ S . ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Παράδειγμα Διφορούμενη γραμματική συγκρούσεις (conficts) ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Συγκρούσεις Συμβαίνουν όταν ο ΣΑ μπορεί να επιλέξει ανάμεσα σε μία ποικιλία ενεργειών για την συνέχιση της ανάλυσης. Οι συγκρούσεις μπορούν να λυθούν είτε αλλάζοντας την γραμματική, είτε παίρνοντας αποφάσεις κατά την ανάλυση. Διακρίνουμε δύο ειδών συγκρούσεις: Σύγκρουση ολίσθησης-ελάττωσης (shift-reduce conflict). Π.χ stmt = “if”,E,“then”,stmt | “if”,E,“then”,stmt,“else”,stmt |… Σύγκρουση ελάττωσης-ελάττωσης (reduce-reduce conflict) ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Συγκρούσεις (συνέχεια) Π.χ. Έστω η γραμματική stmt = id, “(”, param_list, “)” | expr, “:=”, expr ; param_list = {param_list}, “,”, parameter ; parameter = id ; expr = id, “(”, expr_list, “)” | id ; expr_list = {expr_list}, “,” , expr ; Πώς θα ερμηνευτεί μία πρόταση της μορφής Α(i,j); Λύσεις; ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Συντακτικοί αναλυτές LR(k) L : ανάγνωση της εισόδου από αριστερά προς τα δεξιά (left to right scanning) R : δεξιότερη παραγωγή (rightmost derivation) (k): k σύμβολα εισόδου χρησιμοποιούνται για την επιλογή της επόμενης ενέργειας του ΣΑ (look-ahead symbols). Όταν παραλείπεται εννοείται ότι k=1. Πώς συμβιβάζονται η ανίχνευση της εισόδου από αριστερά προς τα δεξιά, με τη δεξιότερη παραγωγή; Shift-reduce : μία απλή μορφή LR. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Χαρακτηριστικά των ΣΑ LR(k) Οι γραμματικές που μπορούν να αναγνωριστούν με LR είναι κανονικό υπερσύνολο αυτών που μπορούν να αναγνωριστούν από LL. Η ΣΑ με LR είναι η πιο γενική προσέγγιση που υπάρχει χωρίς οπισθοδρόμηση, ενώ ταυτόχρονα μπορεί να υλοποιηθεί πολύ αποδοτικά. Οι αναλυτές LR είναι πολύ δύσκολο να κατασκευαστούν «χειρονακτικά». Οι αναλυτές LR μπορούν να ανιχνεύσουν ένα συντακτικό λάθος το συντομότερο δυνατό με δεδομένη την από δεξιά-προς-τα-αριστερά σάρωση της εισόδου. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Yλοποίηση αναλυτή LR H στοίβα περιέχει μία συμβολοσειρά της μορφής : s0, X0, …, Xm, sm όπου Χi είναι σύμβολα της γραμματικής και si είναι καταστάσεις (states) που κωδικοποιούν την πληροφορία που βρίσκεται από κάτω τους στη στοίβα. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Yλοποίηση αναλυτή LR (συνέχεια) H κατάσταση (configuration) του αναλυτή χαρακτηρίζεται πλήρως από το ζεύγος (s0 X1 s1…. Xm sm , ai ai+1 …. an $) που αντιστοιχεί στη δεξιά προτασιακή μορφή Χ1, … Χm, ai, ... an H επόμενη ενέργεια του αναλυτή καθορίζεται από το στοιχείο του πίνακα action[sm, ai]: 1. action[sm, ai] = shift s, όπου s κατάσταση, τότε ο αναλυτής πάει στην κατάσταση (s0 X1 s1…. Xm sm ai s, ai+1 …. an $) ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Yλοποίηση αναλυτή LR (συνέχεια) 2. action[sm, ai] = reduce A=β , o αναλυτής πάει στην κατάσταση (s0 X1 s1…. Xm-r sm-r A s, ai ai+1 …. an $) όπου r=|β| και β= Xm-r+1 …. Xm Επίσης, s = goto[sm-r ,A] όπου βέβαια Α είναι μη τερματικό. 3. action[sm, ai] = accept 4. action[sm, ai] = error Σύμφωνα με τα παραπάνω, ο πίνακας action έχει μία στήλη για κάθε τερματικό σύμβολο, και ο πίνακας goto μία στήλη για κάθε μη-τερματικό σύμβολο ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Ψευδοκώδικας υλοποίησης αναλυτή LR a = yylex() // first input symbol while (1) { let s state on top of the stack if action[s,a] = shift s’ then { push a; push s’ a = yylex() } else if action[s,a] = reduce A = β then { pop 2*|β| symbols let s’ state on top of the stack push A push goto[s’,A] output A = β } else if action[s,a] = accept then return else error() } ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Παράδειγμα Έστω η γραμματική: (1) Ε = Ε, “+”, Τ; (2) Ε = Τ; (3) Τ = Τ, “*”, F; (4) T = F; (5) F = “(”, E, “)”; (6) F = id; acc = accept blank =error si: shift state #i ri : reduce by rule #i ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Παράδειγμα (συνέχεια) Αναγνώριση της συμβολοσειράς id*id+id ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Βιώσιμα Προθέματα (viable prefixes) Βιώσιμa πρoθέματα είναι το σύνολο των προθεμάτων των δεξιών προτασιακών μορφών τα οποία μπορούν να εμφανιστούν στη στοίβα ενός αναλυτή ολίσθησης-ελάττωσης. Εάν είναι δυνατό να γίνει αναγνώριση ενός handle με ανάγνωση των συμβόλων που βρίσκονται στη στοίβα, τότε υπάρχει ένα ΜΠΑ το οποίο μπορεί διαβάζοντας αυτά τα σύμβολα να προσδιορίσει εάν και ποιό handle υπάρχει. Η κατάσταση που αποθηκεύεται στην κορυφή της στοίβας αντιστοιχεί στην κατάσταση στην οποία θα βρισκόταν το ΜΠΑ εάν είχε διαβάσει τα σύμβολα της στοίβας. Ο πίνακας* goto είναι ένα ΝΠΑ που αναγνωρίζει τα βιώσιμα προθέματα. Στη πραγματικότητα η συνάρτηση goto και όχι ο πίνακας είναι η συνάρτηση μετάβασης ενός ΝΠΑ αναγνώρισης των βιώσιμων προθεμάτων. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Items LR(0) item μίας γραμματικής G είναι ένα κανόνας της με το σύμβολο • (dot) σε κάποια θέση στο δεξί του μέλος. Π.χ. Για το κανόνα Α=Χ,Υ,Ζ υπάρχουν 4 items: A = •, X, Y, Z A = X, •, Y, Z A = X, Y, •, Z A = X, Y, Z, • Ένα item μπορεί να αναπαρασταθεί από τον αριθμό του κανόνα και τη θέση της τελείας. Ότι προηγείται της τελείας σε ένα item αντιπροσωπεύει το πρόθεμα του δεξιού μέλους ενός κανόνα το οποίο έχει εμφανιστεί στη στοίβα. Ότι ακολουθεί την τελεία αντιπροσωπεύει ότι περιμένουμε να εμφανιστεί. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Συντακτικός αναλυτής LR(0) Κατασκευή ενός ΜΠΑ που αναγνωρίζει τα βιώσιμα προθέματα και κάθε κατάστασή του οποίου αντιστοιχεί σε ένα item της γραμματικής: 1. Αν S το αρχικό σύμβολο της γραμματικής G δημιουργούμε την επαυξημένη γραμματική G’ με τον πρόσθετο κανόνα S’ = S. 2. Δημιουργούμε για κάθε item της γραμματικής μία κατάσταση του αυτόματου. 3. Για κάθε item της μορφής A = Χ, •, Y δημιουργούμε μία ε-μετάβαση στα item της μορφής Y = •, Z ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Συντακτικός αναλυτής LR(0) (συνέχεια) 4. Για κάθε item της μορφής A = Χ, •, Y, Z δημιουργούμε μία μετάβαση με το σύμβολο Υ στο item A = Χ, Y, •, Z όπου Υ μπορεί να είναι τερματικό ή μη-τερματικό. 5. Η $-μετάβαση από το item S’ = S, • αναγνωρίζει την είσοδο. Μετατρέποντας το ΜΠΑ σε ΝΠΑ: η συνάρτηση Closure(I): Closure(I) repeat for any item A = Χ, •, Y, Z in I for any production Y = •, W I = I {Y = •, W} until I does not change return I ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Παράδειγμα της συνάρτησης Closure Έστω η γραμματική S’ = S ; S = “(”, L, “)” | id ; L = S | L, “,” , S ; closure( {S’ = •, S}) = {S’ = •, S , S = •,“(”, L, “)” , S = •, id } closure( {S = “(”, •,L, “)” }) = {S = “(”, •,L, “)” , L = •, S , L = •, L , “,” , S , S = •, id } ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Συνάρτηση Goto H συνάρτηση Goto(I, X):, όπου Ι σύνολο από items και Χ σύμβολο της γραμματικής: Goto(I,X) let J = for all items A = Y, •, X, Z in I J = J {A = Y, X, •, Z} return closure(J) Π.χ. Goto({S’ = •, S , S = •,“(”, L, “)” , S = •, id}, “(”)= = closure(S = “(”, •, L, “)” ) = = {S = “(”, •,L, “)” , L = •, S ,L = •, L , “,” , S , S = •,“(”, L, “)” , S = •, id } ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Aλγόριθμος κατασκευής ΝΠΑ, ΣΑ LR(0) Έστω Τ το σύνολο των καταστάσεων του ΝΠΑ και Ε το σύνολο των μεταβάσεων. Let T = Closure( S’= •, S ) Let E = {} repeat for each state I in T for each item A = a, •, X, b in I let J = goto(I, X) T = T J E = E {I J} until T and E don’t change ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Κατασκευή πινάκων action, goto 1. Για κάθε Χ-μετάβαση ΙJ, όπου Χ είναι τερματικό θέσε action[I, X] = shift J. Aν το Χ είναι μη-τερματικό τότε goto[I,X]=J. 2. Aν μία κατάσταση Ι περιέχει το item S’=S, • τότε action[I,$]=accept. Δηλ., η $-μετάβαση από το item S’ = S, • αναγνωρίζει την είσοδο. 3. Aν μία κατάσταση Ι περιέχει το item Α = X, • τότε για κάθε τερματικό σύμβολο x θέσε action[I, x] = reduce A=X 4. Kάθε κενό κελί των πινάκων action και goto ισοδυναμεί με σφάλμα. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Παράδειγμα ΝΠΑ για τη γραμματική των λιστών 8 2 L L , . S S . ( L ) S . id 9 1 id id S S ’ . S S . ( L ) S . id S id . L L , S . id ( 3 S ( . L ) L . S L . L , S S . ( L ) S . id , ( 5 L S ( L . ) L L . , S S ) ( S 6 S ( L ) . 4 7 S ’ S . L S . ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Πίνακες action και goto (0) S’ = S; (1) S = “(”, L, “)”; (2) S = id; (3) L = S; (4) L = L, “,” , S; ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Περιορισμοί της προσέγγισης LR(0) Περισσότερο περίπλοκες γραμματικές προκαλούν συγκρούσεις ok shift / reduce reduce / reduce L = L , S, • S = S, • , L L = S , L, • L = L, • L = L , S, • Λύση : η χρήση χαρακτήρων της εισόδου (look-ahead) για την επίλυση των συγκρούσεων. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Συντακτικός αναλυτής SLR(1) SLR (Simple LR) : διαφέρει από τον LR(0) στην κατασκευή του πίνακα action από το ΝΠΑ. Συγκεκριμένα, ο μοναδικός κανόνας που διαφέρει είναι αυτός που αφορά τις ελαττώσεις: . . . 3. Aν μία κατάσταση Ι περιέχει το item Α = X, • τότε για κάθε τερματικό σύμβολο x που ανήκει στο σύνολο FOLLOW(Α), θέσε action[I, x] = reduce A=X ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Παράδειγμα κατασκευής συντ. πίνακα SLR Έστω η γραμματική: S = A, B ; A= “x”, A, “y” | ε ; B = “y”, B | “y” ; Πρώτο βήμα η επαύξηση της γραμματικής : (1) S’ = S ; (2) S = A, B ; (3) A= “x”, A, “y” ; (4) A = ε ; (5) B = “y”, B ; (6) B = “y” ; ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Παράδειγμα συντ. πίνακα SLR (συνέχεια) Κατασκευή του αυτόματου που αναγνωρίζει τα βιώσιμα προθέματα: ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Παράδειγμα συντ. πιν. SLR (συνέχεια 2) (1) FOLLOW(S’) = {$} (1) FOLLOW(S’) FOLLOW(S) FOLLOW(S) ={$} (2) FOLLOW(S) FOLLOW(B) FOLLOW(B) ={$} (3), (2) FOLLOW(A)={“y”} (FIRST(B) -{ε}) FOLLOW(A) = {“y”} Συμπλήρωμα των πινάκων action & goto: ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Παράδειγμα συντ. πιν. SLR (συνέχεια 3) Συντ. ανάλυση της συμβολοσειράς “xxyyyy”: ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Είδη αναλυτών LR LR(0)/ SLR : εύκολη υλοποίηση, λιγότερη ισχυρή προσέγγιση (μικροί πίνακες). Μπορεί μία γραμματική να μην είναι διφορούμενη αλλά να μην είναι δυνατό να κατασκευαστεί SLR που να την αναλύει. Κανονικός LR (canonical LR) : δύσκολη υλοποίηση, πιο ισχυρή προσέγγιση (μεγάλοι πίνακες) LALR (Look Ahead LR) : δυσκολία υλοποίησης και ικανότητες ανάμεσα στους SLR και κανονικό LR. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Τα προβλήματα της ΣΑ SLR(1) Έστω η γραμματική S = L, “=”, R ; S = R ; L = “*”, R ; L = id ; R = L ; Mία από τις καταστάσεις του ΝΠΑ που αναγνωρίζει τα βιώσιμα προθέματα είναι η I2 = {S = L,•, “=”, R , R = L,•} Καθώς “=” FOLLOW(L) , η ύπαρξη στη στοίβα της συμβολοσειράς L οδηγεί στην ελάττωση R = L Η συμβολοσειρά R, “=”… όμως δεν ανήκει στη γλώσσα. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών LR(1) Items LR(1) item μίας γραμματικής ονομάζεται ο συνδυασμός ενός LR(0) item της γραμματικής με ένα τερματικό σύμβολο ή το σύμβολο $, το οποίο μπορεί να ακολουθεί το δεξί μέλος του κανόνα, π.χ.: [Α= Χ, Υ, •,Ζ , α] όπου βέβαια α FOLLOW(Α). H προσθήκη του συμβόλου σαν δεύτερη συνιστώσα, επηρεάζει μόνο τα items της μορφής [A = X, • , α] διότι για να είναι δυνατή η ελάττωση κατά τον κανόνα Α=Χ πρέπει το επόμενο σύμβολο εισόδου να είναι το α. Ποιά είναι όμως η διαφορά από τα items LR(0) και τη χρήση τους με έναν πίνακα SLR(1) ; Με ποιό τρόπο μπορούμε να περιορίσουμε τα τερματικά σύμβολα για τα οποία έχουμε LR(1) items; ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Έγκυρα LR(1) items Το LR(1) item [Α= Χ, •, Υ , α] ονομάζεται έγκυρο (valid) για το βιώσιμο πρόθεμα W, αν υπάρχει μία δεξιότερη παραγωγή: S B, A, C B, X, Y, C όπου W=B, X και, είτε α FIRST(C), είτε ε FIRST(C) και το α είναι $ . Π.χ. για την γραμματική S = B, B ; B = “a”, B | “b” ; το item [Β= “a”, •, B , “a”] είναι έγκυρο για το πρόθεμα “aa” της συμβολοσειράς “aabab”, καθώς υπάρχει δεξιότερη παραγωγή S “a”, B, “ab” “aa”, B, “ab” ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Κατασκευή ΝΠΑ για ΣΑ LR(1) Η συνάρτηση Closure(I) για LR(1): Closure(I) repeat for any item [A = Χ, •, Y, Z, a] in I for any production Y = •, W and any terminal b FIRST(Z,a) I = I { [Y = •, W ,b] } until I does not change return I Τι διαφορετικό προσφέρει η closure στη μορφή αυτή σε σχέση με την αντίστοιχη συνάρτηση του ΣΑ SLR(1)/LR(0) ; ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Κατασκευή ΝΠΑ για ΣΑ LR(1) (συνέχεια) Goto(I, X) let J = for all items [A = Y, •, X, Z , a] in I J = J {[A = Y, X, •, Z, a] } return closure(J) Items(G’) Let T = Closure( [S’= •, S ,$] ) repeat for each state I in T for each item [A = a, •, X, b ,c] in I T = T Goto(I, X) until T don’t change ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Παράδειγμα κατασ. ΝΠΑ αναλυτή LR(1) Έστω η γραμματική S’ = S ; S = C, C ; C = “c”, C | “d” ; closure( [S’ = •, S ,$] ) = [S’ = •, S ,$] [S = •, C, C ,$] * [C = •, “c”, C , “c”] [C = •, “c”, C , “d”] ** [C = •, “d”, “c”] [C = •, “d”, “d”] * αν αντικαταστήσουμε όπου Α=S’, Χ=ε, Υ=S, Z=ε και α=$ καθώς FIRST($) = $ ** αν αντικαταστήσουμε όπου Α=S, Χ=ε, Υ=C, Z=C και α=$ καθώς FIRST(C,$) = {“c”, “d”} ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Παράδειγμα αναλυτή LR(1) (συνέχ.) ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Κατασκευή πινάκων action, goto 1. Για κάθε Χ-μετάβαση ΙJ, όπου Χ είναι τερματικό θέσε action[I, X] = shift J. Aν το Χ είναι μη-τερματικό τότε goto[I,X]=J. 2. Aν μία κατάσταση Ι περιέχει το item [S’=S, •, $] τότε action[I,$]=accept. 3. Aν μία κατάσταση Ι περιέχει το item [Α = X, • , a] τότε action[I, a] = reduce A=X 4. Kάθε κενό κελί των πινάκων action και goto ισοδυναμεί με σφάλμα. Πίνακας ΣΑ για το προηγούμενο παράδειγμα ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Συντακτική ανάλυση LALR(1) Για μία γλώσσα σαν την Pascal, ένας ΣΑ SLR κατασκευάζει ένα πίνακα μερικών εκατοντάδων γραμμών. Αντίστοιχα, ένας ΣΑ LR(1) κατασκευάζει πίνακα μερικών χιλιάδων γραμμών. LALR (lookahead LR) : περιορισμένες συγκρούσεις σε σχέση με τον SLR, διατηρώντας ταυτόχρονα ένα αναλόγου μεγέθους πίνακα με αυτόν. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Κατασκευή LALR Κατά την κατασκευή του ΝΠΑ για την αναγνώριση των βιώσιμων προθεμάτων ενός LR(1) παρατηρούνται καταστάσεις που έχουν το ίδιο πυρήνα (core), δηλ. αποτελούνται από τα ίδια LR(0) items και διαφέρουν μόνο στο προβλεπόμενο (lookahead) σύμβολο. Π.χ. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Κατασκευή LALR (συνέχεια) Η κατασκευή του LALR βασίζεται στην ενοποίηση των καταστάσεων του αναλυτή LR(1) που έχουν τον ίδιο πυρήνα. Η ενοποίηση αυτή δεν μπορεί να προκαλέσει τη δημιουργία συγκρούσεων ολίσθησης-ελάττωσης. Π.χ. αν στον LALR έχουμε τα items: [A=X,• ,a] και [Β=Υ,•,a,Z ,b] τότε στον αρχικό αναλυτή LR(1) θα είχαμε επίσης items της μορφής: [A=X,• ,a] και [Β=Υ,•,a,Z ,c] δεδομένου ότι η ενοποίηση πραγματοποιείται στην βάση των πυρήνων, δηλ. των LR(0) items. Άρα θα υπήρχε σύγκρουση και στον αρχικό αναλυτή. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Κατασκευή LALR (συνέχεια2) Η ενοποίηση των καταστάσεων του αρχικού LR(1) δεν δημιουργεί πρόβλημα στις μεταβάσεις των νέων καταστάσεων. Έστω, μία νέα κατάσταση J=I1 … In . Καθώς τα I1,…, In έχουν τον ίδιο πυρήνα, οι μεταβάσεις από αυτά με κάποια σύμβολο Χ οδηγεί σε καταστάσεις goto(Ι1,X), …, goto(In,X) που έχουν και αυτές τον ίδιο πυρήνα. Άρα κατά την ενοποίηση των καταστάσεων θα ενοποιηθούν και αυτές. To συμπλήρωμα των πινάκων action & goto γίνεται με τον ίδιο ακριβώς τρόπο. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Παράδειγμα LR(1) - LALR ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Κατηγοριοποίηση των γραμματικών LR(1) LALR(1) SLR LL(1) LR(0) ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Xρησιμοποιώντας ασαφείς γραμματικές Οι ασαφείς γραμματικές προσφέρουν ένα εύκολο και σύντομο τρόπο για την περιγραφή προγραμματιστικών δομών. Π.χ. Ε = Ε, “+”, Ε | Ε, “*”, Ε | “(”, Ε, “)” | id ; Μία μη-διφορούμενη γραμματική που γεννά την ίδια γλώσσα είναι: Ε = Ε, “+”, Τ | T ; Τ = Τ, “*”, F | F ; F = “(”, E, “)” | id ; Xαρακτηριστικά: + χαμηλότερη προτεραιότητα από * ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Άρση της ασάφειας κατά την ΣΑ Χρήση κανόνων άρσης της ασάφειας: 1. Στην περίπτωση μίας σύγκρουσης ολίσθησης/ ελάττωσης, κάνουμε ολίσθηση. 2. Στην περίπτωση μίας σύγκρουσης ελάττωσης/ ελάττωσης εφαρμόζουμε τον κανόνα με την μεγαλύτερη προτεραιότητα. Συσχέτιση & προτεραιότητα τελεστών (associativity & precedence) για επίλυση συγκρούσεων ολίσθησης/ελάττωσης. Π.χ. Associativity: …+ id +… left-associativity …= id = … right-associativity ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Άρση ασάφειας στο YACC Για κάθε τερματικό και κανόνα αντιστοιχεί ένας βαθμός προτεραιότητας και κάποια συσχέτιση: %left TOKEN %right TOKEN H προτεραιότητα αυξάνεται από πάνω προς τα κάτω. Σε περίπτωση σύγκρουσης ολίσθησης-ελάττωσης ακολουθείται η ελάττωση μόνο εάν η προτεραιότητα του κανόνα είναι μεγαλύτερη, ή στην περίπτωση ίδιας προτεραιότητας, η συσχέτιση του συμβόλου εισόδου είναι αριστερή. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Αποφυγή συγκρ. ολίσθησης-ελάττωσης def: param_spec return_spec ',‘ ; param_spec: type | name_list ':' type ; return_spec: type | name ':' type ; type: ID ; name: ID ; name_list: name | name ',' name_list ; ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Αποφυγή συγκρ. ολίσθησης-ελάττωσης (2) Εισάγοντας εναλλακτικούς κανόνες που δεν πρόκειται να ελαττωθούν ποτέ, αναγκάζουμε το YACC να μην οδηγήσει σε ενοποίηση καταστάσεων του αυτόματου για το ΣΑ LR(1). Π.χ.: %token BOGUS %% return_spec: type | name ':' type | ID BOGUS ; Άλλος τρόπος είναι η διαφοροποίηση των κανόνων, π.χ. με αλλαγή των συμβόλων που χρησιμοποιούνται. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Χρήση αναδρομικών κανόνων Η χρήση της προσέγγισης LALR από το YACC εξασφαλίζει τη δυνατότητα χρήσης αναδρομικών κανόνων. Η δεξιά αναδρομή έχει μεγάλες απαιτήσεις από τη στοίβα. Π.χ. μπορεί να απαιτήσει την ανάγνωση όλης της εισόδου πριν κάνει έστω και μία ελάττωση. Δεξιά αναδρομή list = elem, list | elem; Αριστερή αναδρομή list = list, elem | elem; ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Ανάνηψη από λάθη στους αναλυτές LR Οι αναλυτές SLR και LALR είναι δυνατό να κάνουν αρκετές ελαττώσεις πριν τον εντοπισμό ενός λάθους αλλά ποτέ δεν θα ολισθήσουν ένα λανθασμένο σύμβολο στη στοίβα. Οι αναλυτές LR δεν κάνουν ούτε μία ελάττωση πριν εντοπίσουν ένα λάθος. Τα λάθη εντοπίζονται μόνο από τον πίνακα action και όχι από τον goto. Ανάνηψη σε λειτουργία πανικού: αναζητούμε στη στοίβα μία κατάσταση s με μετάβαση για ένα συγκεκριμένο μη-τερματικό Α, αφαιρώντας ταυτόχρονα τις καταστάσεις που ακολουθούν. Αφαιρούμε από τη συμβολοσειρά εισόδου όλα τα σύμβολα μέχρι να εντοπίσουμε ένα το οποίο μπορεί να ακολουθεί το Α. Εισάγουμε στη στοίβα την κατάσταση goto[s, A] και συνεχίζουμε την ανάλυση. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Ανάνηψη από λάθη στο YACC Στο YACC η ανάνηψη επιτυγχάνεται με τη βοήθεια μίας μορφής παραγωγών λάθους (error productions). Π.χ.: smt : error ‘;’ ; Οι κανόνες που περιέχουν τη λέξη error προσδιορίζουν τα μη-τερματικά με τα οποία επιχειρεί να κάνει συγχρονισμό ο YACC σε περίπτωση λάθους. Συγκεκριμένα, ο YACC αφαιρεί από τη στοίβα σύμβολα μέχρι να βρει μη-τερματικό το οποίο να έχει ανάλογη παραγωγή. Τότε εισάγει το σύμβολο error στη στοίβα και επιχειρεί να «ταιριάξει» τον αντίστοιχο κανόνα αφαιρώντας αν χρειαστεί σύμβολα εισόδου. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Ανάνηψη από λάθη στο YACC (συν.) Η λέξη error μπορεί να περιέχεται σε οποιοδήποτε σημείο ενός κανόνα. Στο κανόνα όπου τοποθετείται, διαχωρίζει ότι έχει ήδη ανιχνευθεί (και άρα είναι στη στοίβα) και ότι θα αφαιρέσει ο ΣΑ από την είσοδο για να είναι δυνατή η ανάνηψη. Η εμφάνιση μηνυμάτων λάθους επιτυγχάνεται με την βοήθεια: της συνάρτησης yyerror(char *) που ορίζει ο χρήστης των σημασιολογικών ενεργειών που συνοδεύουν τον κανόνα. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Έλεγχος σφαλμάτων στο YACC Ο έλεγχος της λειτουργίας του ΣΑ μπορεί να επιτευχθεί με τη χρήση του διακόπτη: -DYYDEBUG=1 κατά τη μεταγλώττιση του ΣΑ που έχει δημιουργήσει ο YACC. H τοποθέτηση οποιασδήποτε μη μηδενικής τιμής στη μεταβλητή yydebug (π.χ. πριν την κλήση της yyparse από τη main) προκαλεί την έξοδο μηνυμάτων όπως Τι λεκτικές μονάδες επιστρέφει ο ΛΑ Τι καταστάσεις περιέχει η στοίβα του ΣΑ στη τυπική έξοδο λάθους (stderr). ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών Παράδειγμα LR(1) - LALR (Aho 4.40) Αποδείξτε ότιη γραμματική S = A, “a” | “b”, A, “c” | B, “c” | “b”, B, “a”; A = “d”; B = “d”; είναι LR(1) αλλά όχι LALR(1). Λύση Επαύξηση της γραμματικής: (1) S’ = S ; (5) S = “b”, B, “a” ; (2) S = A, “a” ; (6) A = “d” ; (3) S = “b”, A, “c” ; (7) B = “d” ; (4) S = B, “c” ; Kατασκευή του αυτόματου : ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Παράδειγμα LR(1) - LALR (συνέχεια) ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών
Παράδειγμα LR(1) - LALR (συνέχεια 2) Συντακτικός πίνακας: Κατά την μετατροπή σε LALR γίνεται ένωση των καταστάσεων 12 και 13 που μοιράζονται τον πυρήνα Α = “d”, • B = “d”, • H νέα κατάσταση που προκύπτει έχει σύγκρουση ελάττωσης-ελάττωσης για το σύμβολο εισόδου “c”. ΕΠΛ223 Θεωρία και Πρακτική Μεταγλωττιστών