Γλώσσες Προγραμματισμού Μεταγλωττιστές Πανεπιστήμιο Μακεδονίας Τμήμα Εφαρμοσμένης Πληροφορικής Ηλίας Σακελλαρίου
Δομή Γλώσσες Προγραμματισμού Εισαγωγικά Γλώσσα Μηχανής Γλώσσες υψηλού επιπέδου Μεταγλωττιστές Δομή Φάσεις ενός μεταγλωττιστή Απαιτήσεις Οργάνωση σε περάσματα
Γλώσσες Προγραμματισμού
Γλώσσες Προγραμματισμού Γλώσσα προγραμματισμού: Συμβολική περιγραφή υπολογισμών (computations). Προδιαγραφή, οργάνωση και συλλογιστική υπολογισμών. Πρόγραμμα = συμβολική περιγραφή ενός υπολογισμού σε κάποια γλώσσα. Μια γλώσσα προγραμματισμού έχει σαν στόχο να επιτρέπει την εύκολη περιγραφή των υπολογισμών, να εκμεταλλεύεται αποδοτικά την υπολογιστική ισχύ των μηχανών. Ευκολία προέχει της απόδοσης!
Η Υπολογιστική Μηχανή Αποτελέσματα ALU CU Μνήμη Εντολές και δεδομένα Εντολές και δεδομένα Σύγχρονοι υπολογιστές βασίζονται στην αρχιτεκτονική von Neumann. Η προσέγγιση στους υπολογισμούς βασίζεται στην έννοια των μεταβλητών που μεταφέρονται από την μνήμη στην μονάδα.
Γλώσσα Μηχανής H Γλώσσα Μηχανής (machine language) είναι άμεσα εκτελέσιμη από την υπολογιστική μηχανή. Πχ. Αλλά είναι πλήρως μη-αναγνώσιμη από (συνηθισμένους) ανθρώπους. 00000010101111001010 00000010111111001000 00000011001110101000 Τι κάνει ο παραπάνω κώδικας?
Γλώσσα Assembly Ουσιαστικά αποτελεί αντικατάσταση των κωδικών με συμβολικά ονόματα (συμβολομεταφραστές-assemblers). Σημαντική βελτίωση της αναγνωσιμότητας. Όμως Περίπλοκος κώδικας Δεμένος με την συγκεκριμένη υπολογιστική μηχανή
Παράδειγμα memory 1: Μ[0]:=0 2: read(m[1]) 3: if M[1] >= 0 then goto 5 4: goto 7 5: M[3]:=M[0] M[1] 6: if M[3] >= 0 goto 16 7: writeln(m[1]) 8: read(m[2]) 9: M[3]:=M[2]-M[1] 10: if M[3]>=0 goto 12 11: goto 14 12: M[3]:=M[1]-M[2] 13: if M[3]>=0 goto 8 14: M[1]:=M[2]-M[0] 15: goto 3 16: halt input output
Εξέλιξη Γλωσσών Προγραμματισμού Ανάγκη για υποστήριξη όλο και πολυπλοκότερων υπολογισμών. Βασική εργαλείο χειρισμού πολυπλοκότητας είναι η αφαίρεση: Ικανότητα ορισμού και χρήσης πολύπλοκων δομών και εργασιών ώστε να αποκρύπτεται πλήθος λεπτομερειών (Sebesta 2002).
Γλώσσα Προγραμματισμού Μια γλώσσα προγραμματισμού είναι ένας μηχανισμός αφαίρεσης. Επιτρέπει σε ένα προγραμματιστή να προδιαγράψει έναν υπολογισμό (computation) σε ένα επίπεδο αφαίρεσης, και να αφήσει σε ένα πρόγραμμα (μεταγλωττιστή, διερμηνευτή, κλπ) να υλοποιήσει τις συγκεκριμένες προδιαγραφές στην λεπτομερή μορφή που απαιτείται για την εκτέλεση από ένα υπολογιστή'' (Ben-Ari).
Επίπεδα Αφαίρεσης (1/3) Αφαίρεση διαδικασιών (procedural abstraction) Η χρήση υπο-προγραμμάτων(sub-programs) για την κατασκευή μεγαλύτερων προγραμμάτων Γλώσσες προστακτικού (imperative) ή δομημένου/διαδικαστικού (structured/procedural) Αφαίρεση δεδομένων (data abstraction) Νεώτερες αντικειμενοστραφείς γλώσσες προγραμματισμού. Στενή Σύνδεση με το μοντέλο von Neuman. Αυστηρή ακολουθία εντολών για τον εκάστοτε υπολογισμό.
Επίπεδα Αφαίρεσης (2/3) Μη-προστακτικές (non-imperative) γλώσσες Μαθηματική έκφραση προδιαγραφών υπολογισμού Λογική (logic) Λογικός Προγραμματισμός (Logic Programming), πχ Prolog Μαθηματικές συναρτήσεις (functions). Συναρτησιακός Προγραμματισμός (Functional programming) πχ LISP
Επίπεδα Αφαίρεσης (3/3) Εκτέλεση ενός μη-προστακτικού προγράμματος είναι η επίλυση του μαθηματικού προβλήματος που περιγράφεται από το αυτό. Η διαδικασία επίλυσης όμως δεν ορίζεται από τον χρήστη αλλά αποτελεί μέρος του μηχανισμού εκτέλεσης της γλώσσας. Δηλωτικός προγραμματισμός: Ο προγραμματιστής δεν περιγράφει το πώς θα επιλυθεί, αλλά το ποιο είναι το προς επίλυση πρόβλημα.
Γλώσσες Προγραμματισμού Πρώτης Γενιάς - Γλώσσα Μηχανής Δεύτερης Γενιάς - Γλώσσες assembly (χρήση συμβόλων, μετατροπή σε κώδικα από ειδικά εργαλεία ) Τρίτης Γενιάς - Διαδικαστικές και Αντικειμενοστραφείς Γλώσσες C, Pascal, C++, JAVA Τέταρτης Γενιάς - Γλώσσες κοντά στη φυσική γλώσσα, προσπέλαση δεδομένων πχ. SQL, Πέμπτης Γενιάς - Κυρίως γλώσσες δηλωτικές που αφορούν την Τεχνητή Νοημοσύνη, πχ.prolog, Lisp
Εκτέλεση υπολογισμών προδιαγεγραμμένων σε ΓΠΥΕ Οι γλώσσες προγραμματισμού υψηλού επιπέδου (ΓΠΥΕ) δεν είναι άμεσα εκτελέσιμες στις σημερινές μηχανές. Προσπάθειες για εξειδικευμένο υλικό δεν απέδωσαν (LISP machines, Prolog Machines) Τρεις προσεγγίσεις στην εκτέλεση: Μεταγλωττιστές (Compilers), Διερμηνευτές (Interpreters). Μεταγλώττιση σε εικονικές Μηχανές (Virtual Machines)
Μεταγλωττιστές Μεταγλωττιστής είναι το λογισμικό, που ως σκοπό έχει τη μετάφραση ενός προγράμματος από μία γλώσσα σε μία άλλη. Αν το τελικό πρόγραμμα είναι εκτελέσιμο από την μηχανή τότε ισχύει το ακόλουθο σχήμα: Δεδομένα Αρχικό Πρόγραμμα Μεταγλωττιστής (Compiler) Τελικό Πρόγραμμα Αποτέλεσμα Σφάλματα
Διερμηνευτές Διευρμηνευτής είναι το λογισμικό, που φαίνεται να μπορεί να εκτελέσει απευθείας τη γλώσσα υψηλού επιπέδου. Αρχικό Πρόγραμμα Δεδομένα Διερμηνευτής (Interpreter) Αποτέλεσμα Σφάλματα
Εικονικές Μηχανές Συνδυάζουν τις τεχνικές των μεταγλωττιστών και των διερμηνευτών. Αρχικό Πρόγραμμα Μεταφραστής (Translator) Σφάλματα Ενδιάμεσο Πρόγραμμα Αποτέλεσμα Εικονική Μηχανή (Virtual Machine) Δεδομένα
Μεταγλωττιστές
Μεταγλωττιστές Τα τρία ακόλουθα χαρακτηρίζουν πλήρως ένα μεταγλωττιστή: Αρχική Γλώσσα L A (source language) Τελική Γλώσσα L T (target language) A Y T Γλώσσα Υλοποίησης L Y (implementation language) Αρχικό Πρόγραμμα Μεταγλωττιστής (Compiler) Τελικό Πρόγραμμα
Είδη Μεταγλωττιστών Απλοί Αρχική Γλώσσα μια γλώσσα υψηλού επιπέδου και τελική (συνήθως) μια γλώσσα μηχανής. Αντίστροφοι (decompilers) Γλώσσα μηχανής σε μια γλώσσα υψηλού επιπέδου. Μετα-μεταγλωττιστές (meta-compilers) Υλοποίηση μεταγλωττιστών. Προσαρμοζόμενοι μεταγλωττιστές Μετα-μεταγλωττιστές γεννήτορες
Ειδικές Περιπτώσεις Προεπεξεργαστές Υψηλού επιπέδου αρχική και τελική γλώσσα Συμβολομεταφραστές Αρχική γλώσσα assembly τελική γλώσσα γλώσσα μηχανής Γεννήτορες Προγραμμάτων Προδιαγραφές σε μια τυποκρατική γλώσσα και τελική γλώσσα μια γλώσσα υψηλού επιπέδου.
Πλήρης Υλοποίηση μιας Γλώσσας Υψηλού Επιπέδου Συνήθως υπάρχει ένα πλήθος εργαλείων τα οποία συνεργάζονται με τον μεταγλωττιστή για την ΠΛΗΡΗ υλοποίηση μιας γλώσσας υψηλού επιπέδου. Προπεξεργαστής, συμβολομεταφραστής Βιβλιοθήκες χρόνου εκτέλεσης (run-time libraries) Συνδετές (linkers) Φορτωτές (loaders) Εκδότες Προγραμμάτων (program editors) Εντοπιστές σφαλμάτων (debuggers) Στατιστικοί Αναλυτές (profilers)
Λειτουργία Μεταγλωττιστή ΓΠΥΕ Πηγαίο Πρόγραμμα Προεπεξεργαστής (Preprocessor) Τροποποιημένο Πηγαίο Πρόγραμμα Συμβολομεταφραστής (Assembler) Πρόγραμμα σε Συμβολική Μορφή Μεταγλωττιστής (Compiler) Ασύνδετο Πρόγραμμα σε γλώσσα Μηχανής Συνδετής (Linker) Συνδεδεμένο Εκτελέσιμο Πρόγραμμα
Δομή ενός μεταγλωττιστή Εμπρόσθιο Μέρος (front-end) Ανάλυση. Εξάγονται τα στοιχεία του αρχικού προγράμματος. Συντακτικός και σημασιολογικός έλεγχος. Παραγωγή ενδιάμεσου κώδικα. Οπίσθιο Μέρος (back-end) Σύνθεση. Εξαγωγή τελικού κώδικα από τον ενδιάμεσο κώδικα. Διευκόλυνση κατασκευής μεταγλωττιστών για πολλές αρχικές και πολλές τελικές γλώσσες.
Φάσεις Μεταγλώττισης Αρχικό Πρόγραμμα Λεκτική Ανάλυση λεκτικές μονάδες Πίνακας Συμβόλων Τελικό Πρόγραμμα Συντακτική Ανάλυση συντακτικό δένδρο Σημασιολογική Ανάλυση συντακτικό δένδρο Παραγωγή Ενδιάμεσου Κώδικα ενδιάμεσος κώδικας Βελτιστοποίηση Ενδιάμεσου Κώδικα ενδιάμεσος κώδικας Παραγωγή Τελικού Κώδικα τελικός κώδικας Βελτιστοποίηση Τελικού Κώδικα Χειριστής Σφαλμάτων
Λεκτική Ανάλυση Εύρεση λεκτικών μονάδων (lexemes) από την ακολουθία χαρακτήρων του προγράμματος. Για κάθε λεκτική μονάδα παράγεται (συνήθως) μια δυάδα της μορφής <όνομα, τιμή-ιδιότητας> Ενημέρωση πίνακα συμβόλων (όχι πάντα) Παράδειγμα position = initial + rate * 60 <id,1> <=> <id,2> <+> <id,3> <*> <60>
Συντακτική Ανάλυση Ομαδοποίηση λεκτικών μονάδων βάση σύνταξης της γλώσσας. Εισαγωγή λεκτικών στον πίνακα συμβόλων Παραγωγή δένδρου σύνταξης (syntax tree) Μετέπειτα παραγωγή ενδιάμεσου κώδικα. <id,1> <=> <+> <id,2> <*> <id,3> <60>
Σημασιολογική Ανάλυση Έλεγχος σημασιολογικών σφαλμάτων. Έλεγχος τύπων (type checking) Μετατροπή τύπων Παραγωγή τροποποιημένου δένδρου <id,1> <=> <id,2> <+> <*> Αποθήκευση πληροφορίας στον <id,3> inttofloat Πίνακα Συμβόλων. <60>
Παραγωγή Ενδιάμεσου Κώδικα Ενδιάμεσος κώδικας Χαμηλού επιπέδου Καθαρός διαχωρισμός μεταξύ εμπρόσθιου και οπίσθιου μέρους Βελτιστοποίηση Ενδιάμεσες Γλώσσες Τετράδες της μορφής op arg1, arg2, arg3 + 2 3 z Επιθεματικός Κώδικας (postfix code) z23+= Αφηρημένα συντακτικά δένδρα
Παραγωγή Ενδιάμεσου Κώδικα inttofloat,60,_,t1 *,id3,t1,t2 +,id2, t2,t3 =,t3,_,id1 <id,1> <=> <+> <id,2> <*> <id,3> inttofloat <60>
Βελτιστοποίηση Εφαρμογή μετασχηματισμών για παραγωγή περισσότερο αποδοτικού κώδικα. Ανεξάρτητες από την υπολογιστική μηχανή Εξαρτώμενες από την υπολογιστική μηχανή. Δύο φάσεις βελτιστοποίησης Ενδιάμεσου Κώδικα Τελικού Κώδικα
Παράδειγμα inttofloat,60,_,t1 *,id3,t1,t2 +,id2, t2,t3 =,t3,_,id1 *,id3, 60.0, t2 +,id2, t2,t3 =,t3,_,id1 *,id3, 60.0, t2 +,id2, t2,id1
Παραγωγή Τελικού Κώδικα Παραγωγή Τελικού Κώδικα από τον Ενδιάμεσο. Επιλογή θέσεων μνήμης ή καταχωρητών για τις μεταβλητές. Επιλογή καταχωρητών για τις πράξεις Μετάφραση εντολών στην τελική γλώσσα *,id3, 60.0, t2 +,id2, t2,id1 LDF R2, id3 MUL R2,R2,#60 LDF R1, id2 ADDF R1, R1, R2 STF id1, R1
Σφάλματα Λεκτικά Σφάλματα Συντακτικά Σφάλματα Σημασιολογικά Σφάλματα Σφάλματα Εκτέλεσης Λογικά Σφάλματα
Απαιτήσεις Σωστή μετάφραση προγράμματος Απόλυτη συμμόρφωση με τις προδιαγραφές της αρχικής και τελικής γλώσσας Μετάφραση αυθαίρετου μεγέθους προγραμμάτων Δευτερεύουσες Απαιτήσεις Αποδοτικός Κώδικας Μικρός χρόνος μεταγλώττισης Διαγνωστικά μηνύματα Μεταφερσιμότητα
Οργάνωση σε Περάσματα Πέρασμα = ομαδοποίηση μιας ή περισσότερων φάσεων. Μεταγλωττιστές ανάλογα με την αρχική ή τελική γλώσσα υλοποιούνται σε ένα ή περισσότερα περάσματα.
Υλοποίηση Μεταγλωττιστών Αρχικοί μεταγλωττιστές υλοποιήθηκαν σε γλώσσα μηχανής. Γλώσσες υλοποίησης οποιαδήποτε γλώσσα υψηλού επιπέδου (Pascal, C, C++, JAVA) Προγράμματα γεννήτορες για μεταγλωττιστές, λεκτικούς αναλυτές, συντακτικούς αναλυτές. Συνήθως χρησιμοποιείται συνδυασμός μεθόδων. Λεκτική-Συντακτική ανάλυση με την χρήση προγραμμάτων γεννητόρων. Παραγωγή κώδικα με πρόγραμμα σε γλώσσα υψηλού επιπέδου.
Δομή Γλώσσες Προγραμματισμού Εισαγωγικά Γλώσσα Μηχανής Γλώσσες υψηλού επιπέδου Μεταγλωττιστές Δομή Φάσεις ενός μεταγλωττιστή Απαιτήσεις Οργάνωση σε περάσματα