Εισαγωγή
Διομήδης Σπινέλλης
Τμήμα Διοικητικής Επιστήμης και Τεχνολογίας
Οικονομικό Πανεπιστήμιο Αθηνών
dds@aueb.gr
Καλώς ήρθατε
Υλικό και Λογισμικό Ι
Τι περιλαμβάνει το μάθημα
- Εισαγωγή
- Προγραμματισμός σε επίπεδο μηχανής
- Αυτόματα
- Γραμματικές
- Λεκτική ανάλυση
- Το μεταεργαλείο lex
- Συντακτική ανάλυση
- Το μεταεργαλείο yacc
- Πίνακες συμβόλων
- Διερμηνευτές
- Σημασιολογική ανάλυση
- Παραγωγή ενδιάμεσου κώδικα
- Βελτιστοποίηση κώδικα
- Παραγωγή τελικού κώδικα
Οι σημειώσεις
Το χάσμα υλικού και λογισμικού
Οι δυνατότητες που προσφέρει το υλικό και το λογισμικό έρχονται συχνά
σε αντίθεση ή αλληλοσυμπληρώνονται.
Μερικά καθοριστικά χαρακτηριστικά είναι τα παρακάτω:
- ευκαμψία (flexibility)
Το λογισμικό είναι πιο εύκαμπτο και εύπλαστο από το υλικό.
- απόδοση (performance)
Ένας αλγόριθμος υλοποιημένος σε υλικό μπορεί να είναι ταχύτερος από τον
αντίστοιχο υλοποιημένο σε λογισμικό.
- κόστος (cost)
Το οριακό κόστος αναπαραγωγής του λογισμικού είναι, σε αντίθεση με αυτό του
υλικού, μηδενικό.
Από την άλλη πλευρά σε διαμορφωμένα εμπορικά συστήματα το κόστος του
λογισμικού μπορεί να υπερβαίνει αυτό του υλικού.
Οι γλώσσες προγραμματισμού και τα λειτουργικά συστήματα είναι δύο τεχνολογίες
που επιτρέπουν τη βέλτιστη συνύπαρξη του υλικού με το λογισμικό.
Υλοποίηση γλωσσών προγραμματισμού
Μια γλώσσα προγραμματισμού μπορεί - ανάλογα με τη γλώσσα -
να υλοποιηθεί με τους παρακάτω τρόπους:
- από υλικό
(π.χ. επεξεργαστές που προγραμματίζονται κατευθείαν στη γλώσσα FORTH)
- με ένα συμβολομεταφραστή (assembler)
(προγραμματισμός σε συμβολικές γλώσσες)
- με ένα διερμηνευτή (interpreter)
(συνήθως σε συνδυασμό με κάποια στάδια μεταγλώττισης για γλώσσες
πολύ υψηλού επιπέδου όπως Prolog, Lisp, Haskell, ML, Basic, Perl, Python,
TCL, sh, csh, awk)
- με ένα μεταγλωττιστή (compiler)
(τυπικά για γλώσσες τρίτης γενιάς όπως Pascal, FORTRAN, Ada, C, C++)
καθώς και με συνδυασμούς τους.
Ο ορισμός ενός μεταγλωττιστή
Ένας μεταγλωττιστής ορίζεται από:
- την αρχική γλώσσα (Α)
- την τελική γλώσσα (Τ)
- τη γλώσσα υλοποίησης (Υ)
Ο συνδυασμός αυτός παριστάνεται από ένα διάγραμμα Τ (T diagram)
όπως το παρακάτω:
Ο ίδιος συνδυασμός για ένα μεταγλωττιστή Μ συμβολίζεται και ως
MATY.
Τελικός κώδικας
Ο τελικός κώδικας που παράγεται από έναν μεταγλωττιστή μπορεί να είναι:
- συμβολική γλώσσα ενός συγκεκριμένου επεξεργαστή
- γλώσσα μηχανής ενός συγκεκριμένου επεξεργαστή
- γλώσσα μιας ιδεατής μηχανής (virtual machine)
- μια άλλη γλώσσα χαμηλότερου επιπέδου (π.χ. C για ένα μεταγλωττιστή C++)
- μια δομή δεδομένων η οποία θα εκτελεστεί από ένα διερμηνευτή
Παραδείγματα
Τα παρακάτω παραδείγματα έχουν ως είσοδο το πρόγραμμα που τυπώνει "hello, world".
Συμβολική γλώσσα Linux Intel 386
.file "hello.c"
.version "01.01"
gcc2_compiled.:
.section .rodata
.LC0:
.string "hello, world\n"
.text
.align 4
.globl main
.type main,@function
main:
pushl %ebp
movl %esp,%ebp
pushl $.LC0
call printf
addl $4,%esp
.L1:
leave
ret
.Lfe1:
.size main,.Lfe1-main
.ident "GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)"
Γλώσσα μηχανής από δυαδικό αρχείο Linux Intel 386 σε μορφή δεκαεξαδική και ASCII
hello.o: file format elf32-i386
Contents of section .text:
0000 5589e568 00000000 e8fcffff ff83c404 U..h............
0010 c9c3 ..
Contents of section .data:
Contents of section .note:
0000 08000000 00000000 01000000 30312e30 ............01.0
0010 31000000 1...
Contents of section .rodata:
0000 68656c6c 6f2c2077 6f726c64 0a00 hello, world..
Contents of section .comment:
0000 00474343 3a202847 4e552920 65676373 .GCC: (GNU) egcs
0010 2d322e39 312e3636 20313939 39303331 -2.91.66 1999031
0020 342f4c69 6e757820 28656763 732d312e 4/Linux (egcs-1.
0030 312e3220 72656c65 61736529 00 1.2 release).
Συμβολική γλώσσα της ιδεατής μηχανής Java Virtual Machine
Compiled from hello.java
class hello extends java.lang.Object {
hello();
public static void main(java.lang.String[]);
}
Method hello()
0 aload_0
1 invokespecial #9 <Method java.lang.Object()>
4 return
Method void main(java.lang.String[])
0 getstatic #12 <Field java.io.PrintStream out>
3 ldc #2 <String "Hello ">
5 invokevirtual #13 <Method void print(java.lang.String)>
8 getstatic #12 <Field java.io.PrintStream out>
11 new #7 <Class java.lang.StringBuffer>
14 dup
15 aload_0
16 iconst_0
17 aaload
18 invokestatic #16 <Method java.lang.String valueOf(java.lang.Object)>
21 invokespecial #10 <Method java.lang.StringBuffer(java.lang.String)>
24 ldc #1 <String " ">
26 invokevirtual #11 <Method java.lang.StringBuffer append(java.lang.String)>
29 aload_0
30 iconst_1
31 aaload
32 invokevirtual #11 <Method java.lang.StringBuffer append(java.lang.String)>
35 invokevirtual #15 <Method java.lang.String toString()>
38 invokevirtual #14 <Method void println(java.lang.String)>
41 return
Απαιτήσεις
Ο σχεδιασμός και η υλοποίηση ενός μεταγλωττιστή ή ενός διερμηνευτή
(και συχνά και μιας γλώσσας προγραμματισμού)
έχουν ως στόχο να ικανοποιήσουν τις παρακάτω,
συχνά αντικρουόμενες, απαιτήσεις:
- αποδοτικότητα του παραγόμενου κώδικα σε ταχύτητα και οικονομία στη μνήμη
που καταλαμβάνει
- ταχύτητα εκτέλεσης
- διαγνωστικά μηνύματα
- ανάνηψη από λάθη
- αξιοπιστία
- μεταφερσιμότητα ως προς την αρχική και τελική γλώσσα καθώς και ως προς
το περιβάλλον υλοποίησης
- σύνδεση με ολοκληρωμένα περιβάλλοντα ανάπτυξης
Σχεδίαση
Η διεργασία της μεταγλώττισης μπορεί να διαχωριστεί στις παρακάτω
ξεχωριστές λειτουργίες οι οποίες εκτελούνται σε διαδοχικές φάσεις:
Επιπλέον, οι παρακάτω δύο λειτουργίες υποστηρίζουν όλες τις φάσεις της
διεργασίας:
Βιβλιογραφία
Γενική βιβλιογραφία
- Harold Abelson,
Gerald Jay Sussman, and Jullie Sussman.
Structure and Interpretation of Computer Programs.
MIT Press, 1990.
- Alfred V. Aho, Ravi Sethi,
and Jeffrey D. Ullman.
Compilers, Principles, Techniques, and Tools.
Addison-Wesley, 1985.
- Keith Clarke.
One-pass code generation using continuations.
Software: Practice & Experience, 19(12):1175–1192, December
1989.
- Jack W. Davidson
and David B. Whalley.
Quick compilers using peephole optimization.
Software: Practice & Experience, 19(1):79–97, January 1989.
- John M. Dedourek,
Uday G. Gujar, and Marion E. McIntyre.
Scanner design.
Software: Practice & Experience, 10:959–972, 1980.
- H. Dobler and
K. Pirklbauer.
Coco-2: A new compiler compiler.
ACM SIGPLAN Notices, 25(5):82–90, May 1990.
- Charles N. Fischer
and Richard J. Jr. Leblanc.
Crafting a Compiler With C.
Addison-Wesley, 1991.
- Robert W. Gray, Vincent P.
Heuring, Steven P. Levi, Anthony M. Sloane, and William M. Waite.
Eli: A complete, flexible compiler construction system.
Communications of the ACM, 35(2):121–131, February 1992.
- J. Grosch and
H. Emmelmann.
A tool box for compiler construction.
In D. Hammer, editor, Compiler Compilers : Third International Workshop,
CC '90, pages 106–116, Schwerin, Germany, October 1991.
Springer-Verlag.
Lecture Notes in Computer Science 477.
- J. Grosh.
Ast — a generator for abstract syntax trees.
Compiler Generation Report 15, GMD Forshungsstelle an der Universität
Karlsruhe, Germany, August 1989.
(Revised Version).
- Stephen C. Johnson.
Yacc — yet another compiler-compiler.
Computer Science Technical Report 32, Bell Laboratories, Murray Hill, NJ, USA,
July 1975.
- Stephen C. Johnson.
A tour through the portable C compiler.
Bell Telephone Laboratories, Murray Hill, NJ, USA (also available online
http://plan9.bell-labs.com/7thEdMan/), seventh edition, 1979.
- Brian W. Kernighan
and Rob Pike.
The
UNIX Programming Environment.
Prentice-Hall, 1984.
- Michael E. Lesk.
Lex — a lexical analyzer generator.
Computer Science Technical Report 39, Bell Laboratories, Murray Hill, NJ, USA,
October 1975.
- B. J. McKenzie.
Fast peephole optimization techniques.
Software: Practice & Experience, 19(12):1151–1162, December
1989.
- Frank G. Pagan.
Converting interpreters into compilers.
Software: Practice & Experience, 18(6):509–527, June 1988.
- Dennis M. Ritchie.
A tour through the UNIX C compiler.
In UNIX Programmer's Manual. Volume 2 — Supplementary
Documents.
- Peter H. Salus, editor.
Handbook of Programming Languages, volume III: Little Languages and
Tools.
Macmillan Technical Publishing, 1998.
- Ravi Sethi.
Programming Languages: Convepts and Constructs.
Addison-Wesley, 1989.
- Andrew S. Tanenbaum,
M. Frans Kaashoek, Koen G. Langendoen, and Ceriel J. H. Jacobs.
The design of very fast portable compilers.
ACM SIGPLAN Notices, 24(11):125–131, November 1989.
- Ken Thompson.
A new C compiler.
In Proceedings of the Summer 1990 UKUUG Conference, pages
41–51, London, UK, July 1990. UKUUG.
- David H. D. Warren.
Logic programming and compiler writing.
Software: Practice & Experience, 10:97–125, 1980.
Ασκήσεις
Άσκηση 1 (προαιρετική)
- Αναλύστε πως διαφορετικές τεχνικές υλοποίησης γλωσσών προγραμματισμού επηρεάζουν
της απαιτήσεις που έχουμε από τα αντίστοιχα εργαλεία.
Παράδειγμα:
Η υλοποίηση μιας γλώσσας με μεταγλωττιστή επηρεάζει ... την αποδοτικότητα
του παραγώμενου κώδικα σε ταχύτητα διότι ...