Τι είναι το yacc. Δομή ενός αρχείου yacc. Πρόλογος. ΗΥ 340 Γλώσσες και Μεταφραστές Φροντιστήριο. Ο yacc είναι ένας γενικού σκοπού parser generator.

Σχετικά έγγραφα
HY340, 2010 Α. Σαββίδης. Slide 3 / 43. Slide 4 / 43

Θα χρησιμοποιήσουμε το bison, μια βελτιωμένη έκδοση του yacc. Φροντιστήριο 2ο Εισαγωγή στο YACC. Yacc. Δομή Προγράμματος Yacc

Γλώσσες Προγραμματισμού Μεταγλωττιστές. Συντακτική Ανάλυση με το Εργαλείο BISON

Μεταγλωττιστές. Εργαστήριο 5. Εισαγωγή στο BISON. Γεννήτρια Συντακτικών Αναλυτών. 2 η Φάση Μεταγλώττισης Συντακτική Ανάλυση

Εισαγωγή στο Bison. Μεταγλωττιστές, Χειμερινό εξάμηνο

Εισαγωγή στο Bison. Μεταγλωττιστές, Χειμερινό εξάμηνο

Μεταγλωττιστές. Δημήτρης Μιχαήλ. Ακ. Έτος Ανοδικές Μέθοδοι Συντακτικής Ανάλυσης. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Εργαστήριο 08 Εισαγωγή στo Yacc

Παρουσίαση του εργαλείου BISON

Φροντιστήριο 1ο Εισαγωγή στο FLEX. Flex. Regular Expressions (1/4)

Υλοποίηση ΣΑ με το bison

Παρουσίαση του εργαλείου BISON

Μεταγλωττιστές. Γιώργος Δημητρίου. Μάθημα 8 ο. Πανεπιστήμιο Θεσσαλίας - Τμήμα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών

Υλοποίηση ΣΑ με το bison

Εργαστήριο 08 Δημιουργία 1 ου Συντακτικού Αναλυτή

HY340, 2009 Α. Σαββίδης Slide 2 / 26. HY340, 2009 Α. Σαββίδης Slide 3 / 26. HY340, 2009 Α. Σαββίδης Slide 4 / 26

ΜΕΤΑΓΛΩΤΤΙΣΤΕΣ. Στην εξοικείωση με τη διαδικασία κατασκευής ενός Λεξικού Αναλυτή κάνοντας χρήση του lex.

Μεταγλωττιστές. Ενότητα 6: Λεκτική ανάλυση (Μέρος 2 ο ) Αγγελική Σγώρα Τμήμα Μηχανικών Πληροφορικής ΤΕ

Εισαγωγή στο Flex. Μεταγλωττιστές, Χειμερινό εξάμηνο

Γλώσσες Προγραμματισμού Μεταγλωττιστές. Συντακτική Ανάλυση II

HY340, 2009 Α. Σαββίδης Slide 2 / 143. HY340, 2009 Α. Σαββίδης Slide 3 / 143. HY340, 2009 Α. Σαββίδης Slide 4 / 143

Εισαγωγή στην γλώσσα προγραμματισμού C

Προγραμματισμός Η/Υ (ΤΛ2007 )

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Κεφάλαιο 2: Τυπικές γλώσσες

alpha Language age (3/5) alpha Language Φροντιστήριο Syntax Directed Translation and

Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών: Εργαστηριακή Άσκηση

ΜΕΤΑΓΛΩΤΤΙΣΤΕΣ. Στις βασικές έννοιες που σχετίζονται με τη λεξική ανάλυση. Στη δήλωση ορισμό κανονικών εκφράσεων

ΤΕΜ-101 Εισαγωγή στους Η/Υ Εξεταστική Ιανουαρίου 2011 Θέματα Β

3 ο Εργαστήριο Μεταβλητές, Τελεστές

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

Λεκτικός Αναλυτής. Διαλέξεις στο μάθημα: Μεταφραστές Γιώργος Μανής

Πανεπιστήμιο Θεσσαλίας Τμήμα Πληροφορικής

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Η/Υ (ΤΛ2007 )

Τμήμα Πληροφορικής & Επικοινωνιών Δρ. Θεόδωρος Γ. Λάντζος

Εισαγωγή στη γλώσσα προγραμματισμού C++

Ανάπτυξη Μεγάλων Εφαρµογών στη Γλώσσα C (2)

5 ΕΙΣΑΓΩΓΗ ΣΤΗ ΘΕΩΡΙΑ ΑΛΓΟΡΙΘΜΩΝ

Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών: Εργαστηριακή Άσκηση

Εισαγωγή στον Προγραµµατισµό. Διάλεξη 2 η : Βασικές Έννοιες της γλώσσας προγραµµατισµού C Χειµερινό Εξάµηνο 2011

Δομημένος Προγραμματισμός (ΤΛ1006)

Η πρώτη παράμετρος είναι ένα αλφαριθμητικό μορφοποίησης

Ανάπτυξη και Σχεδίαση Λογισμικού

Βαθμός Σχόλια. lab5 PASS PASS PASS PASS PASS. Οριακά PASS - Καλή δουλειά

Μεταγλωττιστές. Γιώργος Δημητρίου. Μάθημα 1 ο. Πανεπιστήμιο Θεσσαλίας - Τμήμα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ ΤΜΗΜΑ ΕΠΙΣΤΗΜΗΣ ΥΠΟΛΟΓΙΣΤΩΝ ΓΛΩΣΣΕΣ ΚΑΙ ΜΕΤΑΦΡΑΣΤΕΣ ΗΥ340

Προγραμματισμός Ι. Προεπεξεργαστής. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Η βασική συνάρτηση προγράμματος main()

ΕΡΓΑΣΤΗΡΙΟ 6: Συναρτήσεις και Αναδρομή

Μεταγλωττιστές. Δημήτρης Μιχαήλ. Ακ. Έτος Συντακτική Ανάλυση. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

ΚΕΦΑΛΑΙΟ 9 ΒΑΣΙΚΕΣ ΕΝΤΟΛΕΣ

Διαδικασιακός Προγραμματισμός

Εισαγωγή στον Προγραμματισμό

Μεταγλωττιστές. Γιώργος Δημητρίου. Μάθημα 5 ο. Πανεπιστήμιο Θεσσαλίας - Τμήμα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Προγραμματισμός Η/Υ (ΤΛ2007 )

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

Μεταγλωττιστές. Ενότητα 8: Συντακτική ανάλυση (Μέρος 2 ο ) Αγγελική Σγώρα Τμήμα Μηχανικών Πληροφορικής ΤΕ

Εφαρμοσμένη Πληροφορική ΙΙ (Θ) Είσοδος/Έξοδος Μεταβλητές Τύποι Μεταβλητών Τελεστές και Προτεραιότητα Μετατροπές Μεταξύ Τύπων

Ηβασικήσυνάρτηση προγράμματος main()

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΡΗΤΗΣ ΤΜΗΜΑ ΕΠΙΣΤΗΜΗΣ ΥΠΟΛΟΓΙΣΤΩΝ ΓΛΩΣΣΕΣ ΚΑΙ ΜΕΤΑΦΡΑΣΤΕΣ ΗΥ340

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΔΕΔΟΜΕΝΩΝ

Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών

ΠΑΝΕΠΙΣΤΗΜΙΟ ΙΩΑΝΝΙΝΩΝ ΑΝΟΙΚΤΑ ΑΚΑΔΗΜΑΪΚΑ ΜΑΘΗΜΑΤΑ

Προγραμματισμό για ΗΜΥ

Δομημένος Προγραμματισμός (ΤΛ1006)

ΓΛΩΣΣΑ ΑΛΦΑΒΗΤΟ ΤΥΠΟΙ ΔΕΔΟΜΕΝΩΝ ΣΤΑΘΕΡΕΣ ΜΕΤΑΒΛΗΤΕΣ

Δομημένος Προγραμματισμός (ΤΛ1006)

Το μεταεργαλείο yacc. Διαδικασία χρήσης. Αρχείο εισόδου

Ψευδοκώδικας. November 7, 2011

Στόχοι και αντικείμενο ενότητας. Εκφράσεις. Η έννοια του τελεστή. #2.. Εισαγωγή στη C (Μέρος Δεύτερο) Η έννοια του Τελεστή

ΚΕΦΑΛΑΙΟ 6: Γλώσσες. 6.1 Ιστορική εξέλιξη 6.4 Υλοποίηση γλώσσας. Κεφάλαιο 6: «Γλώσσες Προγραµµατισµού»

Εισαγωγή στον Προγραμματισμό

Μεταγλώττιση και σύνδεση πολλαπλών αρχείων κώδικα. Προγραμματισμός II 1

Παρουσίαση του εργαλείου FLEX

Προεπεξεργαστής C. Προγραμματισμός Ι 1

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #4

Εισαγωγή στη γλώσσα προγραμματισμού Fortran 95

Προγραμματισμός Η/Υ (ΤΛ2007 )

Pascal. 15 Νοεμβρίου 2011

3.1 Αριθμητικοί και Λογικοί Τελεστές, Μετατροπές Τύπου (Casting)

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Βασικές Αρχές Προγραμματισμού

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

Ανάπτυξη και Σχεδίαση Λογισμικού

Κεφάλαιο 4 Σημασιολογία μιας Απλής Προστακτικής Γλώσσας

Προγραμματισμός Ι. Πολλαπλά Αρχεία. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

Βασικοί τύποι δεδομένων (Pascal) ΕΠΑ.Λ Αλίμου Γ Πληροφορική Δομημένος Προγραμματισμός (Ε) Σχολ. Ετος Κων/νος Φλώρος

Έστω συμβολοσειρά Το σύνολο FIRST περιέχει τα τερματικά σύμβολα από τα οποία αρχίζουν οι συμβολοσειρές που παράγονται από την

Εισαγωγή στον Προγραμματισμό

S, (5, -3, 34, -23, 7) ( *, _

Διαδικασιακός Προγραμματισμός

Μέρος 2 Κατασκευή Συντακτικού Αναλυτή

Master Mind εφαρμογή στη γλώσσα προγραμματισμού C

Προγραμματισμός Η/Υ (ΤΛ2007 )

Διαδικασιακός Προγραμματισμός

Σχεδίαση Γλωσσών Προγραμματισμού Συντακτική Ανάλυση VIΙ. Εαρινό Εξάμηνο Lec 15 09/04/2019 Διδάσκων: Γεώργιος Χρ. Μακρής

Transcript:

ΗΥ 340 Γλώσσες και Μεταφραστές Φροντιστήριο Yacc slide 1/52 Τι είναι το yacc Ο yacc είναι ένας γενικού σκοπού parser generator. μετατρέπει την περιγραφή ργρ φήμίας contt- free γραμματικής σε C/C++ πρόγραμμα. είναι optimized για τις LALR (Look-Ahead, Left-to-right parse, Rightmost-derivation) γραμματικές. Εσείς θα χρησιμοποιήσετε τον bison μία βελτιωμένη έκδοση του yacc. slide 2/52 Δομή ενός αρχείου yacc %{ Πρόλογος %} Δηλώσεις yacc %% Περιγραφή γραμματικής %% Επίλογος slide 3/52 Πρόλογος Ο πρόλογος (ologue) περιέχει δηλώσεις macro, μεταβλητών και συναρτήσεων. ρή %{ #include <stdio.h> #include def.h void int_token_value (FILE *, int, YYSTYPE) int lineno %} slide 4/52

Δηλώσεις yacc Σε αυτό το τμήμα δηλώνονται τα σύμβολα που απαρτίζουν την γραμματική καθώς και κάποια χαρακτηριστικά αυτών. Δήλωση τερματικών και μη τερματικών συμβόλων. Δήλωση αρχικού συμβόλου. Καθορισμός προτεραιότητας. Περιγραφή γραμματικής Η περιγραφή μίας contt-free γραμματικής γίνεται μέσω γραμματικών κανόνων. : NUM + - * / ( ) slide 5/52 slide 6/52 Επίλογος Στον επίλογο (epilogue), γίνεται η υλοποίηση των συναρτήσεων που δηλώθηκαν στον πρόλογο καθώς και η υλοποίηση της συνάρτησης main. %% int main() { yyparse() } L & Yacc Στον πρόλογο δηλώνεται η συνάρτηση yyl (η συνάρτηση που είναι υπεύθυνη για την λεξικογραφική ανάλυση) Στο l αρχείο γίνεται include το header file που παράγεται από τον yacc Το header file ονομάζεται y.tab.h και περιέχει τα tokens που αναγνωρίζονται ρζ από τον λεξικογραφικό αναλυτή, τα οποία ειναι τα τερματικά σύμβολα της γραμματικής. Αφαιρείται η συνάρτηση main από το fl αρχείο slide 7/52 slide 8/52

Διφορούμενη Ανάλυση (1/2) Όταν μπορούμε να παράγουμε μια έκφραση με δύο ή περισσότερους διαφορετικούς τρόπους. : ADD SUB MUL DIV INTCONST Διφορούμενη Ανάλυση (2/2) 3*1-4 (3*1)-4 3*(1-4) * INTCON ST - INTCON ST INTCON ST 4 INTCON ST 3 * - INTCON ST INTCON ST 3 1 1 4 slide 9/52 slide 10/52 Προτεραιότητα Τελεστών (1/4) %left - %right - %nonassoc %ec Τοποθετούνται στο τμήμα των ορισμών (εκτός του %ec) Επιβάλουν προτεραιότητες στα token τα οποία συνοδεύουν και τα οποία πρέπει να βρίσκονται στην ίδια γραμμή Αυξανόμενη προτεραιότητα από πάνω προς τα κάτω slide 11/52 Προτεραιότητα Τελεστών (2/4) %left - %right π.χ. %left ADD, SUB %left MUL, DIV %right EXP /* ^ */ Τα τερματικά σύμβολα ADD και SUB έχουν την ίδια προτεραιότητα μεταξύ τους Αν υπάρχουν δύο ή περισσότερες προσθέσεις ή αφαιρέσεις σε μια έκφραση τότε μεγαλύτερη προτεραιότητα έχει η πιο αριστερή πράξη Τα ADD και SUB έχουν μικρότερη ρη προτεραιότητα ρ από τα MUL και DIV 2^2^3 υπολογίζεται ως 2^(2^3) = 2^8 = 256 slide 12/52

Προτεραιότητα Τελεστών (3/4) Προτεραιότητα Τελεστών (4/4) %ec Ορίζει εκ νέου την προτεραιότητα του κανόνα στον οποίο εμφανίζεται και του δίνει την προτεραιότητα του τερματικού συμβόλου που το συνοδεύει %nonassoc Χρησιμοποιείται για την περιγραφή τελεστών που δεν μπορούν να συνδυαστούν μεταξύ τους π.χ. τελεστής.lt. (Less than) της Fortran A.LT. B.LT. C (illegal ession) %right EQ /* = */ %left ADD SUB /* +,- */ %left MUL DIV /* *,/ */ %left UMINUS /* unary minus */ %% : EQ ADD SUB MUL DIV SUB %ec UMINUS ID a = b = c*d - e - f* -g a = ( b = ( ((c*d)-e) - (f*(-g)) ) ) slide 13/52 slide 14/52 Παράδειγμα Γραμματική για έναν απλό υπολογιστή αριθμητικών εκφράσεων Υποστηρίζει: Ανάθεση μίας αριθμητικής έκφρασης σε μία μεταβλητή Παράθεση αριθμητικών εκφράσεων που χωρίζονται με χαρακτήρες τέλους γραμμής Λεξικογραφικός Αναλυτής (1/2) Θέλουμε να αναγνωρίζουμε τα σύμβολα +, -, *, /, (, ) = \n ακεραίους αναγνωριστικά μεταβλητών slide 15/52 slide 16/52

Λεξικογραφικός Αναλυτής (2/2) το header αυτό δημιουργήται από τον yacc. Συντακτικός αναλυτής (1/3) Δηλώσεις καλείται από τον yacc με ένα μήνυμα όταν ανακαλύψει κάποιο λάθος μετατρέπει πολλαπλά \n \t σε ένα οι τιμές των συμβολικών ονομάτων INTEGER, ID είναι ορισμένες στο header parser.h αρχικό σύμβολο δήλωση των τερματικών συμβόλων που χρησιμοποιούνται από τον yacc και τον fl slide 17/52 slide 18/52 Κανόνες Συντακτικός αναλυτής (2/3) Συναρτήσεις Συντακτικός αναλυτής (3/3) ε κανόνας παράγεται από τον yacc slide 19/52 slide 20/52

Παραγωγή τελικού εκτελέσιμου Προγράμματα (1/3) Έγκυρο πρόγραμμα parser.y yacc/bison parser.c parser.h Compiler scanner.l l/fl scanner.c c calc slide 21/52 slide 22/52 Μη έγκυρο πρόγραμματα Προγράμματα (2/3) Είναι έγκυρα προγράμματα Προγράμματα (3/3) slide 23/52 το δεν έχει \n στο τέλος slide 24/52

Ασάφειες στη γραμματική (1/3) Η περιγραφή μιας γραμματικής μπορεί να παράγει μία συγκεκριμένη ακολουθία συμβόλων με δύο ή περισσότερους τρόπους πχ. η έκφραση () 1+2*3 μπορεί να παραχθεί ως : '+' '*' -> '+' NUMBER -> ep'+' ep '*' ep -> NUMBER '+' NUMBER '*' NUMBER -> 1+2*3 -> '*' -> '+' '*' -> NUMBER '+' NUMBER '*' NUMBER -> 1+2*3 slide 25/52 Ασάφειες στη γραμματική (2/3) Αυτή η αμφισημία στις γραμματικές δεν είναι επιθυμητή επειδή μπορούμε να καταλήξουμε σε λάθος συμπεράσματα (βλ. actions) Απαλοιφή ασάφειας με τη χρήση προτεραιοτήτων τελεστών όπως είδαμε πριν με την προσθήκη επιπλέον κανόνων slide 26/52 Ασάφειες στη γραμματική (3/3) Έτσι το προηγούμενο παράδειγμα παράγεται με μοναδικό τρόπο : '+' 1 1 1: 1 '*' NUMBER NUMBER -> '+' 1 -> 1 '+' 1 -> 1 '+' 1 '*' NUMBER -> 1'+' NUMBER '*' NUMBER -> NUMBER '+' NUMBER '*' NUMBER -> 1+2*3 slide 27/52 Inside Look Yacc (1/6) Στην πραγματικότητα το parsing μίας ακολουθίας εισόδου γίνεται από κάτω προς τα πάνω (bottomup parsing) π.χ η έκφραση 3*4*(3+2) ανάγεται σε ως εξής: 3*4*(3+2) -> NUMBER '*' 4 '*' '(' 3 '+' 2 ') -> '*' 4 '*' '(' 3 '+'' 2 ') -> '*' NUMBER '*' '(' 3 '+' 2 ') -> '*' '*' '(' 3 '+' 2 ') : '+' -> '*' '(' 3 '+' 2 ') '*' -> '*' '(' NUMBER '+' 2 ') '(' ')' -> '*' '(' '+' 2 ') -> '*' '(' '+' NUMBER ') NUMBER -> '*' '(' '+' ') -> '*' '(' ') -> '*' -> slide 28/52

Inside Look Yacc (2/6) Inside Look Yacc (3/6) Για την υλοποίηση μίας από κάτω προς τα πάνω συντακτικής ανάλυσης θα χρησιμοποιήσουμε Μία στοίβα στην οποία θα αποθηκεύονται τα σύμβολα που αποτελούν τη γλώσσα Μία ενέργεια shift η οποία θα τοποθετεί ένα σύμβολο από την είσοδο στη στοίβα Μία ενέργεια reduce η οποία θα αντικαθιστά ένα σύμβολο ή μία ακολουθία συμβόλων που εμφανίζονται στο δεξιό μέρος ενός κανόνα με το σύμβολο που εμφανίζεται στο αριστερό μέρος του κανόνα slide 29/52 Μία ενέργεια accept που εφαρμόζεται όταν διαβαστεί ολόκληρη η είσοδος και έχει αναγνωριστεί το αρχικό σύμβολο Σηματοδοτεί την εγκυρότητα της ακολουθίας εισόδου σύμφωνα με την γραμματική Μία ενέργεια error που εφαρμόζεται όταν δεν μπορεί να εφαρμοστεί καμία ενέργεια reduce πάνω στη στοίβα, δηλαδή τα σύμβολα που υπάρχουν σε αυτήν δεν υπάρχουν στο δεξί μέρος κανενός κανόνα Σηματοδοτεί την αδυναμία της γραμματικής να περιγράψει την ακολουθία εισόδου slide 30/52 Inside Look Yacc (4/6) Inside Look Yacc (5/6) Έτσι ο αλγόριθμος που εφαρμόζεται για την συντακτική ανάλυση της ακολουθίας εισόδου, είναι ο εξής Παράδειγμα Ανάλογα με την κατάσταση στην οποία βρίσκεται, ο συντακτικός αναλυτής, αποφασίζει εάν χρειάζεται το επόμενο σύμβολο από την είσοδο (lookahead token) για να επιλέξει την επόμενη ενέργεια Ανάλογα με την τρέχουσα κατάσταση και το επόμενο σύμβολο (εάν χρειάζεται) αποφασίζει να εκτελέσει μία από τις ενέργειες shift, reduce, accept ή error slide 31/52 Στοίβα Είσοδος Ενέργεια 3*4*(3+2) shift 3 *4*(3+2) reduce *4*(3+2) shift * 4*(3+2) shift * 4 *(3+2) reduce * *(3+2) reduce *(3+2) shift * (3+2) shift * ( 3+2) shift * ( 3 +2) reduce * ( +2) shift * ( + 2) shift * ( + 2 ) reduce *( + ) reduce * ( ) shift * ( ) reduce * epxr reduce e accept : '+' '*' '(' ')' NUMBER slide 32/52

Inside Look Yacc (6/6) Παράδειγμα Στοίβα Είσοδος Ενέργεια 3**4*(3+2) shift 3 **4*(3+2) reduce **4*(3+2) shift * *4*(3+2) shift * * 4*(3+2) error : '+' '*' '(' ')' NUMBER Yacc και αμφισημία (1/4) Συμπεριφορά του yacc όταν για μία παραγωγή υπάρχουν δύο ή περισσότεροι δρόμοι Ουσιαστικά όταν υπάρχουν δύο ή παραπάνω διαφορετικές παραγωγές για μία ακολουθία εισόδου, ο yacc σε κάποιο σημείο θα βρεθεί στο δίλημμα να κάνει reduce με τον κατάλληλο λ κανόνα ή να κάνει shift και να κάνει reduce με έναν επόμενο κανόνα (ο οποίος περιέχει και όλα τα σύμβολα του πρώτου κανόνα) Αυτό το δίλημμα λέγεται shift/reduce conflict slide 33/52 slide 34/52 Yacc και αμφισημία (2/4) Παράδειγμα Στοίβα Είσοδος Ενέργεια IF (4) IF (5) 5 ELSE 6 shift IF (4) IF (5) 5 ELSE 6 shift IF ( 4) IF (5) 5 ELSE 6 shift IF ( 4 ) IF (5) 5 ELSE 6 shift IF ( 4 ) IF (5) 5 ELSE 6 shift...... shift... IF ( 4 ) IF (5) 5 ELSE 6 shift ή reduce : ifelse NUMBER ifelse: IF '(' NUMBER ')' else else: ELSE /* empty */ slide 35/52 Yacc και αμφισημία (3/4) Επίσης, όταν υπάρχουν δύο διαφορετικοί κανόνες με πανομοιότυπο δεξιό μέρος, όταν βρεθεί, ο yacc, σε θέση να κάνει reduce την ακολουθία συμβόλων που περιγράφεται από αυτό, δεν θα ξέρει ποιον κανόνα να χρησιμοποιήσει για να κάνει το reduce Αυτό το δίλημμα λέγεται reduce/reduce conflict slide 36/52

Yacc και αμφισημία (4/4) Ο yacc παράγει συντακτικούς αναλυτές, ακόμα κι αν η γραμματική περιέχει shift/reduce ή reduce/reduce conflicts Κατά τη διάρκεια shift/reduce conflict ο yacc κάνει εξ' ορισμού shift Κατά τη δά διάρκεια reduce/reduce d conflict ο yacc κάνει reduce με τον κανόνα που βρίσκεται πιο κοντά στην αρχή του αρχείου.y Εάν τρέξουμε τον yacc (ή bison) με την παράμετρο -v, ο τελευταίος δημιουργεί ένα αρχείο με κατάληξη.output output στο οποίο επισημαίνει τα σημεία των κανόνων που οδηγούν σε conflicts slide 37/52 Actions (1/10) Μπορούμε να παρεμβάλλουμε ανάμεσα στα σύμβολα των δεξιών μερών των κανόνων κάποια actions, δηλαδή c, c++ κώδικα μέσα σε { } Εκτελούνται κάθε φορά που ενεργοποιείται η συγκεκριμένη παραγωγή Παράδειγμα : ID { intf( Found ID\n ) } '+' { int a = 3 } { int b } /* empty */ { intf( empty\n ) } slide 38/52 Actions (2/10) Επίσης μπορούμε να αναθέσουμε έναν τύπο στα τερματικά και τα μη τερματικά σύμβολα πού εμφανίζονται στη γραμματική και να τους αναθέτουμε τιμές Καταρχήν θα πρέπει να ορίσουμε ένα union το οποίο θα περιλαμβάνει όλους τους imitive iti τύπους που θα ανατεθούν στα τερματικά και μη τερματικά σύμβολα %union { char* int double ConfigToken* } stringv intv realv tokenv slide 39/52 Actions (3/10) Για να αναθέσουμε έναν από τους διαθέσιμους τύπους του union στα τερματικά σύμβολα της γραμματικής, αρκεί να παρεμβάλλουμε στην αρχή της δήλωσης %token, το όνομα του τύπου του union πού θέλουμε να αντιστοιχίσουμε στο τερματικό σύμβολο %token <stringv> CONF_ID CONF_TYPE_STRING %token <intv> CONF_TYPE_INT %token <realv> CONF_TYPE_REAL slide 40/52

Actions (4/10) Για να αντιστοιχίσουμε έναν τύπο στα μη τερματικά σύμβολα της γραμματικής, αρκεί να δηλώσουμε τα ονόματά τους δεξιά μιας οδηγίας %type με τον τύπο να ακολουθεί %type <tokenv> %type <stringv> list_elements hash_decl slide 41/52 Actions (5/10) Τέλος όλα τα σύμβολα που παραλείπουμε, δεν έχουν κανένα τύπο και έτσι δεν μπορούμε να αναφερθούμε σε αυτά Μπορούμε μέσα από τα actions να αναφερθούμε σε όλα τα σύμβολα που έχουμε δηλώσει τον τύπο τους Στο αριστερό μέρος ενός κανόνα αντιστοιχεί το σύμβολο $$ Κάθε δεξιό σύμβολο ενός κανόνα, μπορεί να αναφερθεί μέσω του συμβολικού ονόματος $N (N = 1, 2,...) ανάλογα με την σχετική του θέση slide 42/52 Actions (6/10) Παράδειγμα Actions (7/10) Η σειρά αρίθμησης των συμβόλων λαμβάνει υπόψιν της και τα blocks κώδικα non_terminal: FOO { g_var = $1 } BAR { g_var2 = $3 } $1, $FOO Βρίσκεται στην 3η θέση $BAR slide 43/52 slide 44/52

Actions (8/10) Actions (9/10) Οι τιμές στα τερματικά σύμβολα δίνονται από τον λεξικογραφικό αναλυτή Ο yacc δηλώνει μία καθολική μεταβλητή, στιγμιότυπο του union που έχουμε ορίσει, με το όνομα yylval Κάθε φορά που αναγνωρίζουμε ένα σύμβολο στον l/fl, πριν επιστρέψουμε τον κωδικό του, αποθηκεύουμε στο κατάλληλο μέλος του union την τιμή του slide 45/52 slide 46/52 Actions (10/10) Επαναφορά μετά από συντακτικό λάθος (1/5) Ο yacc εξ' ορισμού, όταν δεν μπορεί να αναγνωρίσει την ακολουθία συμβόλων εισόδου, καλεί την συνάρτηση yyerror και τερματίζει την λειτουργία του Πολλές φορές δε θέλουμε να τερματίζουμε τη λειτουργία του προγράμματος μας στο πρώτο συντακτικό λάθος Ειδικά σε interactive προγράμματα όπως το bc του UNIX slide 47/52 slide 48/52

Επαναφορά μετά από συντακτικό λάθος (2/5) Η επαναφορά της λειτουργίας του συντακτικού αναλυτή μετά από συντακτικό λάθος (error recovery) είναι πολύ δύσκολη διαδικασία, επειδή πρέπει να μαντέψουμε που τελειώνει το κομμάτι που δεν συμφωνεί με την γραμματική... και που ξεκινάει το κομμάτι που είναι εν δυνάμει σωστό Ο yacc προσφέρει ένα σύμβολο με το όνομα error το οποίο καταναλώνει τα περιεχόμενα της στοίβας και τα επόμενα σύμβολα εισόδου, μέχρι να ανακαλύψει τουλάχιστον τρία σύμβολα που ξεκινούν ένα άλλο κανόνα n_term: FOO error slide 49/52 Επαναφορά μετά από συντακτικό λάθος (3/5) Μπορούμε επίσης να κατευθύνουμε την διαδικασία επαναφοράς προσθέτοντας σύμβολα στην παραγωγή που περιέχει το σύμβολο error και προσθέτοντας actions Παράδειγμα όταν συμβεί λάθος ο συντακτικός αναλυτής αγνοεί όλα τα σύμβολα μέχρι να συναντήσει '' slide 50/52 Επαναφορά μετά από συντακτικό λάθος (4/5) Ο yacc προσφέρει τα εξής macros που μπορούν να χρησιμοποιηθούν σε κανόνες yyerrok εξαναγκάζει τον συντακτικό αναλυτή να θεωρήσει ότι βγήκε από την κατάσταση επαναφοράς μετά από λάθος και έτσι να αρχίσει κατευθείαν θί να ειδοποιεί για καινούρια λάθη yyclearin καθαρίζει το lookahead Επαναφορά μετά από συντακτικό λάθος (5/5) Ο bison (και όχι ο yacc), προσφέρει μία ειδική εντολή που εκτελείται όταν ο τελευταίος καθαρίζει τη στοίβα μετά από error κώδικας που εκτελείται όταν καθαρίζεται από σύνολο τερματικών ή μη την στοίβα ένα σύμβολο ID τερματικών συμβόλων που χωρίζονται με κενό slide 51/52 slide 52/52