LEZIONE 2: Sintassi e semantica Informatica 3 Lezione 2

Informatica 3
Informatica 3
LEZIONE 2: Sintassi e semantica
Lezione 2- Modulo 1
• Modulo 1: Introduzione ai concetti di sintassi
e semantica
• Modulo 2: Il concetto di binding
• Modulo 3: Variabili
• Modulo 4: Routine – Convenzioni dei nomi
Introduzione ai concetti di sintassi e
semantica
Politecnico di Milano - Prof. Sara Comai
1
Le componenti di un linguaggio di
programmazione
2
Sintassi di un linguaggio
• Un linguaggio di programmazione è una
notazione formale caratterizzata da due
componenti:
• Sintassi: regole che definiscono le sequenze
valide di simboli
– Frasi come sequenze di parole
– Parole: definite su un alfabeto
– Sintassi: insieme di regole formali che specificano
la composizione di programmi
• Regole lessicali: insieme di caratteri che costituiscono
l’alfabeto del linguaggio
• Per determinare se un programma è valido
– Semantica: insieme di regole che specificano il
“significato” di un programma sintatticamente
valido
– Esempi:
• Caratteri maiuscoli e minuscoli differiscono in C/C++ ma
sono identici in Pascal
• L’operatore “diverso” è: != in C/C++ e <> in Pascal
• Per determinare l’effetto di un programma
– Notazioni formali
– Semantica operazionale: comportamento di un processore
astratto che esegue il programma scritto nel linguaggio di
programmazione
Politecnico di Milano - Prof. Sara Comai
Politecnico di Milano - Prof. Sara Comai
3
Politecnico di Milano - Prof. Sara Comai
4
1
EBNF – regole sintattiche
EBNF=Extended Backus Naur Form
Metalinguaggio con metasimboli ::= < > | * +
• Regole sintattiche:
non
terminale
terminale
EBNF – regole lessicali
• Regole lessicali:
non terminale
definito da
regole lessicali
<programma>
<istruzione>
::= { <istruzione>* }
::= <assegnamento> | <condizione> |
<ciclo>
<assegnamento> ::= <identificatore> = <espr> ;
<condizione>
::= if <espr> { <istruzione> + } |
if <espr> { <istruzione> + }
else { <istruzione> + }
<ciclo>
::= while <espr> { <istruzione> + }
<espr>
::= <identificatore> | <numero> |
( <espr> ) | <espr> <operatore> <espr>
Politecnico di Milano - Prof. Sara Comai
<operatore>
<identificatore>
<ld>
<numero>
<lettera>
<cifra>
5
Diagrammi sintattici
condizione
{
}
assegnamento
ciclo
while
istruzione
}
else
{
istruzione
}
espressione
{
istruzione
}
condizione
ciclo
assegnamento
{
espressione
if
istruzione
istruzione
6
Politecnico di Milano - Prof. Sara Comai
Diagrammi sintattici
programma
::= + | - | * | / | = | /= | < | > | <= | >=
::= <lettera> <ld>*
::= <lettera> | <cifra>
::= <cifra>+
::= a | b | c | . . . | z
::= 0 | 1 | . . . | 9
espressione
espressione
operatore
espressione
identificatore
identificatore
=
espressione
numero
{
Politecnico di Milano - Prof. Sara Comai
7
espressione
}
Politecnico di Milano - Prof. Sara Comai
8
2
Sintassi astratta e concreta
Sintassi concreta e usabilità
• Costrutti in linguaggi diversi possono avere la stessa
struttura concettuale, ma avere regole lessicali
diverse:
while (x!=y)
{
…
}
• <> è più leggibile di !=
• Se il ciclo contiene una singola istruzione le { }
possono essere omesse
while x<>y do
begin
…
end
– Facile commettere errori!!
while (num!=0){
cin >> num;
}
– Stessa sintassi astratta
– Diversa sintassi concreta
Politecnico di Milano - Prof. Sara Comai
while (num!=0)
cin >> num;
while num <> 0 do
…
end
9
Politecnico di Milano - Prof. Sara Comai
10
Il concetto di binding
Informatica 3
• I programmi sono costituiti da entità
– variabili, routine, istruzioni
• Le entità sono caratterizzate da attributi
Lezione 2- Modulo 2
– Variabile: nome, tipo, area di memoria
– Routine: nome, parametri, modalità di passaggio
parametri
Il concetto di binding
• Binding: associa un valore agli attributi
• Per ogni entità le informazioni sulle entità
sono contenute in un descrittore
Politecnico di Milano - Prof. Sara Comai
11
Politecnico di Milano - Prof. Sara Comai
12
3
Binding
Linguaggi e binding
• Binding definito dalla definizione del linguaggio:
• Concetto fondamentale nella definizione della
semantica di un linguaggio
– Esempio: interi Æ insieme di operazioni eseguibili (Fortran,
Ada, C, C++)
– Linguaggi diversi presentano
• Binding definito dall’implementazione del linguaggio:
• Un numero di entità diverse
• Un numero di attributi diversi per ogni entità
• Tempi di binding diversi (es. a tempo di compilazione o
esecuzione)
• Stabilità differenti di binding (fissi o modificabili)
– Esempio: interi Æ rappresentazione in memoria (Fortran,
Ada, C, C++)
• Binding definito a tempo di compilazione:
– Esempio: in Pascal il binding degli interi avviene durante la
compilazione
• Binding definito a tempo di esecuzione:
– Maggior parte dei linguaggi di programmazione
– Esempio alle variabili vengono associati dei valori durante
l’esecuzione
– Binding statico: non può essere modificato
– Binding dinamico: modificabile durante l’esecuzione
Binding dinamico
Politecnico di Milano - Prof. Sara Comai
13
Politecnico di Milano - Prof. Sara Comai
14
Variabili
Informatica 3
• I linguaggi di programmazione possono essere visti come
un’astrazione del comportamento dei computer convenzionali:
– Memoria centrale consiste di celle elementari identificate da un
indirizzo
– Il contenuto di una cella rappresenta un valore (codificato)
– Il valore può essere modificato (nuova codifica) durante
l’esecuzione di un programma
Lezione 2- Modulo 3
Variabili
– Variabile: astrazione del concetto di cella di memoria
– Nome di variabile: astrazione dell’indirizzo della cella di memoria
– Istruzione di assegnamento: astrazione della modifica del valore di
una cella
• Formalmente: variabile = <nome, scope, tipo, l-value, r-value>
Politecnico di Milano - Prof. Sara Comai
15
Politecnico di Milano - Prof. Sara Comai
16
4
Nome e regole di visibilità
Nome e regole di visibilità
• Le regole di binding di una variabile all’interno
del suo scope dipendono dal linguaggio
variabile = <nome, scope, tipo, l-value, r-value>
• Nome: stringa di caratteri che denota la variabile
– Binding statico dello scope
– Solitamente introdotto tramite una dichiarazione
• Lo scope viene definito staticamente, tramite una
dichiarazione implicita o esplicita, senza dover eseguire il
programma
• Maggior parte di linguaggi di programmazione (C/C++)
• Visibilità (o scope): insieme di istruzioni a cui il nome
è “noto”
– Dal punto in cui la variabile viene dichiarata fino ad un punto
“di chiusura” successivo
– Binding dinamico dello scope
Un programma può manipolare le variabili tramite il loro nome
all’interno del loro scope
Una variabile è visibile con il suo nome all’interno del suo scope
Politecnico di Milano - Prof. Sara Comai
• Lo scope viene definito durante l’esecuzione del
programma
• APL, vecchi LISP, SNOBOL4
17
Esempio di binding dinamico dello
scope
variabile = <nome, scope, tipo, l-value, r-value>
Esempio: A Æ C; B Æ C
• Tipo di una variabile:
}
{
/* blocco B */
int x;
– insieme di valori che possono essere associati alla
variabile
•Regole semplici da
implementare
+
•Implementazione meno
efficiente
}
{
/* blocco C */
x = ...;
}
18
Tipo
{
/* blocco A */
int x;
Politecnico di Milano - Prof. Sara Comai
– operazioni per creare, accedere, modificare tali
valori
•Programmi difficili da
leggere
Politecnico di Milano - Prof. Sara Comai
19
Politecnico di Milano - Prof. Sara Comai
20
5
Tipi e binding
Tipizzazione statica e dinamica
• Tipizzazione statica (C/C++, Pascal, ecc.)
• Tipi predefiniti (esempio: int)
– Il nome del tipo viene associato tramite binding alla classe di valori e
all’insieme di operazioni definite dal linguaggio
– I valori e le operazioni vengono associate tramite binding alla
rappresentazione della macchina durante l’implementazione
– Il binding delle variabili al loro tipo avviene a tempo di
compilazione
– Il binding non può essere cambiato durante l’esecuzione
• Permette la verifica del corretto uso delle variabili a tempo di
compilazione
• Dichiarazioni di tipo (esempio: typedef float reale;)
• Tipizzazione dinamica (LISP, APL, Smalltalk, ecc.)
– Definisce il binding tra il nome del tipo e l’implementazione
– Eredita tutte le operazioni del tipo specificato
– Il binding avviene a tempo di esecuzione
– Le variabili sono polimorfiche (il tipo dipende dal valore associato
dinamicamente)
• Tipi di dati astratti
• Non è possibile verificare l’uso corretto delle variabili staticamente
nome_nuovo_tipo ={
struttura dati degli oggetti del nuovo tipo;
operazioni per manipolare gli oggetti del nuovo tipo;
}
• Linguaggi non tipizzati (linguaggi di script, assemblatori)
– Le variabili non sono tipizzate
– Celle di memoria e registri contengono stringhe che possono
essere interpretate come valori di qualsiasi tipo
– Associano il nuovo tipo alle operazioni definite
Politecnico di Milano - Prof. Sara Comai
21
Politecnico di Milano - Prof. Sara Comai
l-value
r-value
variabile = <nome, scope, tipo, l-value, r-value>
variabile = <nome, scope, tipo, l-value, r-value>
• l-value:
• r-value:
– area di memorizzazione associata ad una variabile durante
l’esecuzione
– Valore codificato memorizzato nella locazione associata alla
variabile (l-value)
• Tempo di vita (lifetime o extent):
• Interpretato a seconda del tipo della variabile
– durata di tale binding
• Istruzioni di un programma
– Accedono alle variabili attraverso l-value (left)
– Modificano r-value (right)
• Allocazione della memoria:
– Allocazione di un’area della memoria ad una variabile
– Il tempo di vita di una variabile va dalla sua allocazione alla sua
disallocazione
• x=y;
// x indica una locazione, y un valore
• Binding tra una variabile ed il valore:
• Allocazione statica: prima dell’esecuzione e disallocazione al termine
dell’esecuzione (automaticamente)
• Allocazione dinamica: durante l’esecuzione e disallocazione durante
l’esecuzione (automaticamente o su richiesta)
Politecnico di Milano - Prof. Sara Comai
22
– Dinamico Æ operazione di assegnamento: x=10;
– Statico Æ costanti simboliche: const int MAX = 10;
23
Politecnico di Milano - Prof. Sara Comai
24
6
Inizializzazione di variabili
Reference e variabili senza nome
• Qual è l’r-value di una variabile dopo la sua
creazione?
• Variabili che possono essere accedute tramite l’r-value
di altre variabili
– In alcuni linguaggi il binding deve essere definito quando la
variabile viene creata (ML)
– Altri lo supportano ma non lo richiedono (C/C++)
– reference o puntatore alla variabile
• Possono non avere un nome (ma esiste percorso di
accesso)
• Esempio:
• int i=0;
– Se l’inizializzazione non viene specificata la soluzione
adottata dipende dall’implementazione
• Ignorata: considera la stringa nell’area di memoria come valore
iniziale
• Definita dal sistema: es. int inizializzati a 0
• Valore speciale non definito per inizializzare la variabile che
non permette di usare la variabile finchè non viene assegnato
un valore (verifica di correttezza del programma)
Politecnico di Milano - Prof. Sara Comai
25
Condivisione di oggetti
Accessibili:
•direttamente (x)
•indirettamente (px)
*px = 0;
//r-value di px è 0
int y = *px; //r-value di px è 0
Dereferenziazione:
accesso tramite il
puntatore
Politecnico di Milano - Prof. Sara Comai
26
Routine
Informatica 3
• Routine: unità di decomposizione di un
programma che implementa un’operazione
astratta
Lezione 2- Modulo 4
– Assembler: sottoprogramma
– C: funzione
– Pascal: procedure e funzioni
Routine
Convenzioni dei nomi
Politecnico di Milano - Prof. Sara Comai
int x = 5; //r-value di x è 5
int *px;
px = &x; //r-value di px è 5
• Procedure: non restituiscono valori
• Funzioni: restituiscono valori
27
Politecnico di Milano - Prof. Sara Comai
28
7
Oggetti di una routine
Oggetti di una routine
• La routine definisce lo scope per le dichiarazioni in
essa annidate
Routine = <nome, scope, tipo, l-value, r-value>
– Dichiarazioni locali (visibili solo dalla routine)
– Non locali (visibili da altre unità)
– Globali (visibili da tutte le unità del programma)
– Il nome della routine può essere introdotto tramite
la dichiarazione della routine
• int sum(int n); //prototipo C
– Lo scope va dalla dichiarazione ad un punto di
chiusura (C: fine del file che contiene la
dichiarazione)
• L’attivazione di una routine avviene tramite
l’invocazione o chiamata della routine
Routine = <nome, scope, tipo, l-value, r-value>
• Il tipo della routine è definito dalla sua intestazione
– Signature: tipi dei parametri di input e tipo restituito
• int funzione(int, int, float)
– Una chiamata di una routine è corretta se è conforme al suo
tipo
– Dev’essere nello scope della routine
– Specifica il nome della routine ed i parametri
Politecnico di Milano - Prof. Sara Comai
29
l-value e r-value
Politecnico di Milano - Prof. Sara Comai
30
Dichiarazione e definizione
Routine = <nome, scope, tipo, l-value, r-value>
• Dichiarazione: intestazione della routine
– Definisce lo scope
• l-value: area di memoria che contiene il corpo della
routine
• r-value: corpo della routine correntemente associato
tramite binding
• Definizione: intestazione e corpo della routine
• La distinzione serve per poter avere mutua ricorsione
– Esempio:
int funzA (int x);
float funzB (int y){
…
z=funzA (y);
…
}
– Normalmente è statico, definito a tempo di compilazione
– Alcuni linguaggi supportano un binding dinamico:
• Variabili di tipo routine a cui si può assegnare una routine
• Es. linguaggio C
int sum(int);
int (*ps)(int);
ps=∑
Æ int i = (*ps)(5);
• Routine come “first-class objects”
Politecnico di Milano - Prof. Sara Comai
31
//dichiarazione
//definizione
//chiamata di funzione (visibile!)
Politecnico di Milano - Prof. Sara Comai
32
8
Parametri della routine
Routine generiche
• Esempio:
• Per passaggio informazioni
– Routine per ordinare array di interi
– Oggetti di dati
– Routine (in alcuni linguaggi)
• … int i,j; … swap(i,j);
• … float i,j; … swap(i,j); //caso 2
• Parametri
• Template con tipo generico in C++:
– Formali: parametri che appaiono nella definizione
– Attuali: parametri che appaiono nella chiamata alla
routine
template <class T> void swap(T& a, T& b)
{
T temp = a;
a = b;
b = temp;
}
• Binding
– Secondo il metodo posizionale
Routine: R(F1,F2,…,Fn);
Chiamata: R(A1,A2,…,An);
– Tramite associazione del nome
Routine: R(A:T1; B:T2; C:T3);
Chiamata: R(C=>Z, A=>X, B=>Y);
– Nel caso 1 viene istanziata una routine con interi,
– nel caso 2 una routine con float
• I parametri generici vengono associati tramite binding
ai parametri attuali a tempo di compilazione
33
Politecnico di Milano - Prof. Sara Comai
a=b+c+b();
34
Politecnico di Milano - Prof. Sara Comai
Overloading
int i,j,k;
float a,b,c;
…
i=j+k;
a=b+c;
//caso 1
– Routine per ordinare array di float
Aliasing
Æb variabile
Æb() funzione
Aliasing: contrario di overloading
• Due nomi sono alias se denotano la stessa entità
nello stesso punto del programma
Operatore +
Æ Somma tra interi
a=b()+c+b(i);
Æb() e b(int)
funzioni distinte
Æ Somma tra float
Overloading: la stessa entità viene utilizzata con
significati diversi.
• Il binding per l’entità viene stabilito a tempo di
compilazione in base alle informazioni disponibili
– Esempio: per l’operatore + il binding con la corrispondente
operazioni viene stabilito in base al tipo dei parametri
Politecnico di Milano - Prof. Sara Comai
35
int x;
int *y=&x;
x e *y rappresentano
la stessa variabile
int q1 (int a)
{
return a*= a;
}
int x=2;
void q2 (int &a)
{
a *= a;
}
i e a rappresentano la
stessa variabile
cout << q1(x); cout << x; // stampa 4 e 2
q2(x); cout << x;
Politecnico di Milano - Prof. Sara Comai
// stampa 4
36
9