PROGRAMOVACÍ JAZYKY A PŘEKLADAČE STRUKTURA PŘEKLADAČE 2011 Jan Janoušek BI-PJP Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti
Základní informace Přednášky: doc. Ing. Jan Janoušek, Ph.D. Office: MK 226 Email: Jan.Janousek@fit.cvut.cz Stránka předmětu: http://edux.fit.cvut.cz/courses/bi-pjp/start Cvičení: Ing. Martin Plicka
Doporučená literatura Muller, K.: Programovací jazyky a překladače. Skripta ČVUT. Další, pokročilejší knihy (pro zájemce): Aho, Lam, Sethi, Ullman: Compiler: Principles, Techniques and Tools (2nd ed.), 2010. Melichar, Češka, Ježek, Richta: Konstrukce překladačů, ČVUT, 2006. Allen, Kennedy: Optimizing Compilers for Modern Architectures, 2002. Fischer, LeBlanc: Crafting a Compiler, 1995. Grune, Bal, Jacobs, Langendoen: Modern Compiler Design, 2000. Muchnick: Advanced compiler design and implementation, Morgan Kaufman Publishers, 2009.
Hodnocení Podmínky zápočtu a zkoušky Semestrální práce max. 20 b. Dva zápočtové testy max. 30 b. Zkouška 50 b. (povinná ústní zkouška s právem veta +/- 5 b.) Výsledná známka se řídí Klasifikačním řádem ČVUT.
Souvislosti s ostatními předměty Návaznost předmětů na FIT ČVUT: BI-AAG: obecná teorie formálních jazyků, gramatik a automatů BI-PJP: úvodní kurs do teorie syntaktické analýzy, překladu a tvorby překladačů (jednoduchý frontend řízený LL analyzátorem, jednoduchý backend (přímé generování cílového kódu průchodem AST)) MI-SYP: pokročilé techniky syntaktické analýzy a překladu (LR syntaktická analýza, paralelní syntaktická analýza) MI-GEN: pokročilejší techniky tvorby překladačů (vnitřní formy, frontend: generování vnitřních forem, backend: optimalizace, generování kódu, run-time prostředí)
Použití překladače USE CASE
CPU rozumí pouze binárním kódu 01010000 01110100 11010111 10010110 00100010 10110001
1940... programování ve strojovém kódu 01010000 01110100 11010111 10010110 00100010 10110001
1940... programování ve strojovém kódu 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 01010000 01110100 11010111 10010110 00100010 10110001
1940... programování ve strojovém kódu 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 01010000 01110100 11010111 10010110 00100010 10110001
1950... assembler 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 01010000 01110100 11010111 10010110 00100010 10110001 PRINT NOGEN BEGIN BEGIN REGS SR R2,R2 SR R3,R3 LOOP AR R2,R3 LA R3,1(R0,R3) C R3,=F'10' BNE LOOP CVD R2,DBL ED RESULT,DBL+6 WTO RESULT RETURN LTORG RESULT DC '40202120' DBL DC D'0' END BEGIN assembler
1950... operační systém 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader PRINT NOGEN BEGIN BEGIN REGS SR R2,R2 SR R3,R3 LOOP AR R2,R3 LA R3,1(R0,R3) C R3,=F'10' BNE LOOP CVD R2,DBL ED RESULT,DBL+6 WTO RESULT RETURN LTORG RESULT DC '40202120' DBL DC D'0' END BEGIN assembler
1950... operační systém 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader PRINT NOGEN BEGIN BEGIN REGS SR R2,R2 SR R3,R3 LOOP AR R2,R3 LA R3,1(R0,R3) C R3,=F'10' BNE LOOP CVD R2,DBL ED RESULT,DBL+6 WTO RESULT RETURN LTORG RESULT DC '40202120' DBL DC D'0' END BEGIN assembler myprog.exe
1950... překladač 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader READ INPUT TAPE 5, 501, IA, IB, IC 501 FORMAT (3I5) IF (IA) 777, 777, 701 701 IF (IB) 777, 777, 702 702 IF (IC) 777, 777, 703 703 IF (IA+IB-IC) 777,777,704 704 IF (IA+IC-IB) 777,777,705 705 IF (IB+IC-IA) 777,777,799 777 STOP 1 799 S = FLOATF (IA + IB + IC) / 2.0 AREA = SQRT( S * (S - FLOATF(IA)) * (S - FLOATF(IB)) * + (S - FLOATF(IC))) WRITE OUTPUT TAPE 6, 601, IA, IB, IC, AREA STOP END překladač Fortran myprog.exe
1970... překladač C 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader Hello, world! #include <stdio.h> int main(int,char**) { printf( "Hello, world!\n"); } překladač C myprog.exe
1980... překladač C++ 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader Hello, world! #include <iostream> int main(int,char**) { std::cout << "Hello, world!\n"; } překladač C++ myprog.exe
1960... interpret(er) 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 10 INPUT "What is your name: ", U$ 20 PRINT "Hello "; U$ 30 INPUT "How do you want: ", N 40 S$ = "" 50 FOR I = 1 TO N 60 S$ = S$ + "*" 70 NET I 80 PRINT S$ 90 INPUT "Do you want? ", A$ 100 IF LEN(A$) = 0 THEN 90 110 A$ = LEFT$(A$, 1) 120 IF A$ = "Y" THEN 30 130 PRINT "Goodbye ";U$ 140 END interpret operační systém
Interpretace s mezikódem 10 INPUT "What is your name: ", U$ 20 PRINT "Hello "; U$ 30 INPUT "How do you want: ", N 40 S$ = "" 50 FOR I = 1 TO N 60 S$ = S$ + "*" 70 NET I 80 PRINT S$ 90 INPUT "Do you want? ", A$ 100 IF LEN(A$) = 0 THEN 90 110 A$ = LEFT$(A$, 1) 120 IF A$ = "Y" THEN 30 130 PRINT "Goodbye ";U$ 140 END 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 překladač 04FBC41E 77AB2000 1AE04E33 operační systém interpret
interpretovaný mezikód (bytecode) public class HelloWorld { public static void main(string[] args) { System.out.println( "Hello, world!"); } } překladač myprog.class 13 0 1 0 10 0 8 0 9 0 13 0 8 0 16 0 7 0 2 0 0 0 0 12 0 15 0 6 0 2 0 7 0 9 0 6 0 2 0 8 0 8 0 10 0 4 0 0 2 0 7 0 7 0 1 0 2 0 0 5 0 1 0 8 0 0 8 0 7 0 10 0 1 0 0 0 2 0 8 0 11 0 4 0 9 0 13 0 0 2 0 0 0 0 6 0 7 0 0 0 0 8 0 5 0 0 3 0 17 0 0 0 5 0 20 10 0 04FBC41E 77AB2000 1AE04E33 interpret operační systém Hello, world!
Srovnání Just-In-Time/non-JIT public class HelloWorld { public static void main(string[] args) { System.out.println( "Hello, world!"); } } překladač myprog.class JIT překladač 01010000 01110100 11010111 10010110 00100010 10110001 operační systém #include <iostream> int main(int,char**) { std::cout << "Hello, world!\n"; } překladač myprog.exe 01010000 01110100 11010111 10010110 00100010 10110001 operační systém loader
21 Struktura překladače Jednoduchý překladač: Vstupní kód Lexikální analyzátor Posloupnost tokenů Syntaktický analyzátor Derivační strom Sémantický analyzátor, generátor kódu Cílový kód
Složitější překladač front-end závislý na vstupním jazyku back-end závislý na cílovém jazyku Lexikální analyzátor Posloupnost tokenů Parser Derivační strom Mezikód Generátor kódu Sémantický analyzátor Derivační strom Cílový kód Generátor mezikódu 22
Ještě více složitější překladač Lexikální analyzátor front-end závislý na vstupním jazyku back-end závislý na cílovém jazyku Posloupnost tokenů Optimalizace Parser Mezikód Sémantický analyzátor Optimalizace Derivační strom Derivační strom Derivační strom Mezikód Strojově závislé optimalizace Generátor kódu Mezikód střední úrovně Mezikód nízké úrovně Strojově závislé optimalizace 23 Generátor mezikódu Cílový kód
Překladač pro m vstupních a n výstupních jazyků Frontend 1 Backend 1 Frontend 2 Backend 2 Mezikód (vnitřní reprezentace) Frontend m Backend n
Poznámky Jednotlivé fáze se často spojují dohromady do jednoho průchodu: např. syntaktická + sémantická analýza Formalismy pro popis syntaktické a sémantické analýzy, včetně generování mezikódu: bezkontextová gramatika, atributová překladová bezkontextová gramatika. (viz první seznámení v předmětu BI-AAG)