Sei sulla pagina 1di 42

Linguaggi di Programmazione

Compilatori e Interpreti
Grammatiche

Fondamenti di Programmazione
CdL Ingegneria Informatica e dell'Informazione
Lezione 2
Linguaggi di programmazione

Linguaggio macchina:
 sequenze di 0 ed 1
 rigoroso
 essenziale

Linguaggio assembly:
 simbolico (es. set_a)
 semplice traduzione aggiuntiva (assembler)

Però: dipende dal processore
 Il programmatore deve conoscere in dettaglio le
caratteristiche della macchina che usa
 Impossibile trasferire programmi da una macchina
ad un'altra
Linguaggi di programmazione

Linguaggio di programmazione ad alto livello
 Indipendente dal processore utilizzato
 È più semplice comprenderne la struttura
 Meno errori

Gerarchia di linguaggi: da basso livello ad
alto livello
set_a,2
set_b,3 print 2+3
sum_ab
out_a
Linguaggi di programmazione

Efficienza del programma

Programmazione Programmazione
a basso livello ad alto livello

Facilità e velocità di programmazione


Linguaggi di alto livello

Ad es. C, FORTRAN,C++,JAVA ...altri



Linguaggi sintatticamente complessi facili da
usare dagli umani: la traduzione in linguaggio
macchina viene fatta “dietro le scene”

Chi effettua la traduzione?
– Il compilatore

5
Compilatori
Traduttore da linguaggio di alto livello a
linguaggio macchina (o assembly)
Linguaggi “evoluti”
Indipendenti dalla macchina

file.c file.o

File sorgente Compilatore File oggetto


6
Compilatori e interpreti
Compilatore:
Programma che traduce un programma in un
linguaggio ad alto livello in un programma in
linguaggio assembly o macchina
Interprete:
Programma che traduce ed esegue una dopo
l'altra le istruzioni che compongono il
programma sorgente
Confronto
Interprete: Compilatore:
-efficienza +efficienza
+flessibilità -flessibilità
+semplicità
...
+memoria ridotta
Compilatori e interpreti
Java:
Il compilatore traduce il codice in byte-code
Linguaggio della macchina virtuale Java
Un interprete traduce ed esegue le istruzioni
in byte-code
Come viene fatta la
traduzione?


Linguaggi di programmazione

Sintassi e semantica

Grammatiche libere

Grammatiche e compilatori
Linguaggi di programmazione
Istruzioni primitive che il calcolatore è in
grado di eseguire e regole per
combinare tra di loro le istruzioni
primitive


Sintassi: forma in cui l’istruzione
primitiva è espressa

Semantica: significato dell’istruzione
stessa
Grammatica (un esempio)

G=(V,N,P,S)
V={il,lo,la,cane,mela,gatto,mangia,graffia,,}
N={frase,soggetto,verbo,complemento,articolo,nome}
P: frase::=soggetto verbo complemento
soggetto::=articolo nome
articolo::=il | la | lo
nome::= cane | mela | gatto
verbo::= mangia | graffia
complemento::= articolo nome | articolo nome ,
complemento
S=frase
Albero di derivazione
frase

soggetto verbo complemento

articolo nome graffia articolo nome , complemento

gatto il cane articolo nome


il
la mela
LP, grammatiche e
compilatori
Un linguaggio di programmazione L è generato
dalla sua grammatica (libera, non ambigua)
Il vocabolario è costituito da identificatori e parole
chiave
Un compilatore conosce la grammatica del
linguaggio e da una sequenza di simboli
terminali può verificare se la frase appartiene
al linguaggio
• Risalendo al simbolo iniziale mediante le
regole della grammatica
Struttura di un compilatore
file.c

File sorgente
Lista token AST AST aumentato

Analisi Analisi Analisi Generazione


lessicale sintattica semantica Forma intermedia
Forma intermedia

Ottimizzazione
Tabella
dei simboli file.o

File oggetto
Fasi della compilazione
Analisi lessicale
I simboli che costituiscono le istruzioni vengono letti
(scansione) da sx verso dx allo scopo di raggrupparli in
token.
La scansione utilizza grammatiche regolari
Esempio:
x=1+pippo++;
restituirà 7 token.
Struttura di un compilatore
file.c

File sorgente
Lista token AST AST aumentato

Analisi Analisi Analisi Generazione


lessicale sintattica semantica Forma intermedia
Forma intermedia

Ottimizzazione
Tabella
dei simboli file.o

File oggetto
Fasi della compilazione
Analisi sintattica
L'analizzatore sintattico (parser) cerca di
costruire l'albero sintattico per la lista di token.
In caso di fallimento, l'istruzione non è corretta e
la compilazione viene abortita (messaggi di
errore).
Struttura di un compilatore
file.c

File sorgente
Lista token AST AST aumentato

Analisi Analisi Analisi Generazione


lessicale sintattica semantica Forma intermedia
Forma intermedia

Ottimizzazione
Tabella
dei simboli file.o

File oggetto
Fasi della compilazione
Analisi semantica (sintattica contestuale)
Effettua controlli relativi ai vincoli contestuali del
linguaggio:
Dichiarazioni delle variabili
Tipi e compatibilità
Numero di paramatri delle funzioni...
Queste informazioni arricchiscono la tabella dei simboli.
In caso di errore:
Struttura di un compilatore
file.c

File sorgente
Lista token AST AST aumentato

Analisi Analisi Analisi Generazione


lessicale sintattica semantica Forma intermedia
Forma intermedia

Ottimizzazione
Tabella
dei simboli file.o

File oggetto
Fasi della compilazione
Generazione della forma intermedia
Produce una prima generazione di codice
attraverso una visita dell'albero di
derivazione aumentato (non ancora
codice oggetto)
Fasi della compilazione
Ottimizzazione del codice
Rimozione del codice inutile
Espansione in-line delle funzioni
Ottimizzazione dei cicli
Variabili da memorizzare nei registri...
Struttura di un compilatore
file.c

File sorgente
Lista token AST AST aumentato

Analisi Analisi Analisi Generazione


lessicale sintattica semantica Forma intermedia
Forma intermedia

Ottimizzazione
Tabella
dei simboli file.o

File oggetto
Nota
Un compilatore è un programma
In quale linguaggio è scritto?
Molti compilatori per il linguaggio C sono
scritti in C!
Si può scrivere un compilatore in linguaggio
macchina per un LP A,
poi un compilatore scritto in LP A per un LP B,
poi un compilatore in LP B per un LP C...
Un esempio

set_a,2
print 2+3 set_b,3
sum_ab
out_a

file.c file.o

File sorgente Compilatore File oggetto


Un esempio più complesso
A=2; 1 A=2
B=3; 2 B=3
print A+B; 3 goto SUM
A=5; 4 A=5 sostituisce con
B=8; 5 B=8 l'indirizzo della prima
print A+B; 6 goto SUM istruzione di SUM
4 return
8 SUM:
9 set_a,A
10 set_b,B
11 sum_ab
torna all'indirizzo 12 out_a
dell'istruzione da cui 13 return
È stato eseguito il salto
Dal sorgente all'eseguibile

Compilatore Linker
file.c file.o file.exe

File sorgente File oggetto File eseguibile


Linker

Uno o più files oggetto devono essere collegati
alle librerie

Librerie: insieme di file oggetto preparati dal
produttore del compilatore con le istruzioni per
l’esecuzione di compiti comuni
 Librerie matematiche
 Librerie grafiche
 Servizi di I/O

L’operazione di link può essere esplicita o
implicita

29
Dal sorgente all'eseguibile
Esecuzione
E se riuscite ad eliminare tutti gli errori di
compilazione...

...ci potranno sempre essere gli errori a tempo di


esecuzione :-(
Fondamenti

Un programma può generare una
divisione per zero?

Un programma può andare in loop?
E' possibile controllare in modo
automatico?
– Il problema della fermata
– Espressività dei linguaggi di
programmazione
Il problema della fermata
Problema: verificare se un programma
terminerà o andrà in ciclo
NB. per qualunque programma e input

Fissiamo un linguaggio L
P: un programma in L
x: un input
P(x): il risultato di una computazione
Il problema della fermata
? Esiste un programma H che termina
sempre e che risponde:
H(P,x)=SI, se P(x) termina
H(P,x)=NO, se P(x) va in ciclo

Si dimostra per assurdo che non esiste


Autoreferenzialità e negazione
Il problema della fermata
Se H esiste, esiste un programma K con input un programma P:

K(P)=SI, se H(P,P)=NO

K(P)=va in ciclo, se H(P,P)=SI
Poichè:

H(P,P)=NO, se P(P) va in ciclo, allora

K(P)=SI, se P(P) va in ciclo

H(P,P)=SI, se P(P) termina, allora

K(P)=va in ciclo, se P(P) termina
Esegui K su se stesso!
Il problema della fermata
Indecidibilità del problema della fermata
NB. non dipende dalla scelta di L, ogni LP
dotato di costrutti per la forma
condizionale e iterzione (o ricorsione)

Altri:
Verificare se due programmi calcolano la
stessa funzione
Espressività dei LP
LP sono tutti equivalenti?
Turing completezza: ogni LP calcola lo
stesso insieme di funzioni, cioè quelle
calcolate dalle macchine di Turing
Tipi di LP

I linguaggi possono essere suddivisi sulla base del
modello astratto di programmazione:

Linguaggi di programmazione

Imperativi Dichiarativi

Procedurali Ad Oggetti Paralleli Funzionali Logici Relazionali


(C,Pascal, (C++, Java) (Occam) (Lisp) (Prolog) (SQL)
Fortran)
Tipi di LP


Linguaggi imperativi:
 Il modello computazionale è basato sui
cambiamenti di stato della memoria della
macchina
 È centrale il concetto di assegnamento di un
valore ad una locazione di memoria
 Il compito del programmatore è costruire una
sequenza di assegnamenti che producano lo
stato finale (in modo tale che questo rappresenti
la soluzione del problema)
Tipi di LP


Linguaggi dichiarativi:
 Il modello computazionale è basato sui concetti di
funzione e relazione
 Il programmatore non ragiona in termini di
assegnazioni di valori, ma di relazioni fra entità
e di valori di funzione

NB. tutti i linguaggi di programmazione sono equivalenti


(Turing completi)

Ogni programma può essere scritto in un qualunque LP


Tipi di LP


Scelta del linguaggio di programmazione:
sulla base dell’ambito del problema da
risolvere:

Calcolo Scientifico: Fortran,C

Intelligenza Artificiale: Python,C,C++,Prolog,Lisp

Sistemi device driven: Assembler,C

Applicazioni gestionali: SQL,C

Applicazioni client visuali: JavaScript,C++,Java

Applicazioni Web: JavaScript,PHP,Perl,ASP,Java

Applicazioni distribuite: Java,C,C++
Linguaggi basati su C oltre a
Java
Objective-C: per OSX e dispositivi basati su iOS
C#: per integrare Internet e il web nelle applicazioni
PHP: linguaggio di scripting orientato agli oggetti utilizzato da
molti siti web

Python: linguaggio di scripting orientato agli oggetti per


sistemi

JavaScript: linguaggio di scripting per aggiungere


dinamicità alle pagine web

Swift: linguaggio di programmazione di Apple