140 likes | 336 Views
Semantica Operazionale di un frammento di Java: le regole di transizione. estensione (con piccole varianti) di quella in Barbuti, Mancarella, Turini, Elementi di Semantica Operazionale, appunti di Fondamenti di Programmazione. r 0. r 1. r k. Regole di transizione.
E N D
Semantica Operazionale di un frammento di Java: le regole di transizione estensione (con piccole varianti) di quella in Barbuti, Mancarella, Turini, Elementi di Semantica Operazionale, appunti di Fondamenti di Programmazione
r0 r1 rk Regole di transizione • diverse relazioni di transizione, in corrispondenza dei diversi tipi di costrutti del linguaggio • espressioni, comandi, dichiarazioni ecc.
Dichiarazione di classe Class_decl := class Id extends Id { Static_var_decl_list Static_meth_decl_list Inst_var_decl_list Inst_meth_decl_list Costruttore } • assunzioni • c’è sempre extends • ogni classe estende la classe Object • le dichiarazioni di variabili e metodi statici sono “raggruppate” • esiste sempre il costruttore
Semantica informale delle classi • variabili e metodi statici appartengono alla classe • variabili e metodi di istanza appartengono agli oggetti (istanze della classe) • una classe definisce un tipo (nome della classe) • gli oggetti della classe hanno quel tipo • relazioni di sottoclasse ed ereditarietà • gerarchia di tipi, realizzata con extends • la radice della gerarchia è la classe predefinitaObject
Ereditarietà • se cdown è una sottoclasse (estende) cup • variabili e metodi statici dicup(e delle sue superclassi) sono visibili direttamente dacdown • variabili e metodi di istanza di cup(e delle sue superclassi) diventano anhe variabili e metodi di istanza degli oggetti di cdown • Tipo degli oggetti di cupè anche tipo degli oggetti dicdown • a meno di overriding
Overriding • se cdown è una sottoclasse (estende) cup • un metodo di istanza dicup(e delle sue superclassi) può essere ridefinito (stesso nome e tipi) incdown • l’idea è quella di definire un metodo più specializzato, che rimpiazza quello definito in una delle superclassi • l’overriding non “dovrebbe” essere possibile per le variabili e per i metodi statici • ma questo non è sempre garantito dal compilatore • comportamenti complessi e poco prevedibili • assumeremo che non si verifichi mai
Inizializzazioni • Java permette di inizializzare (al valore di una espressione) sia le variabili statiche che quelle di istanza in una dichiarazione • le inizializzazioni delle variabili statiche vengono effettuate la prima volta che si usa una classe • le inizializzazioni delle variabili di istanza vengono effettuate all’atto della creazione di una istanza (oggetto) • per semplicità, decidiamo di non avere inizializzazioni nelle dichiarazioni di variabile all’interno di classi • Le inizializzazioni possono essere affidate al(i) costruttore(i) • eseguito quando si crea un’istanza
Il costruttore • i costruttori sono usati per la creazione di un oggetto: • Inizializzazione dello stato (variabili di istanza) • anche per i costruttori esiste un meccanismo di ereditarietà • se c è una classe che ha come superclassi (nell’ordine) le classi c1, c2,…, cnObject, • all’atto della creazione di una istanza di c • si eseguono (nell’ordine) i costruttori di cn,…,c2,c1,c
Dichiarazione di classe Class_decl := class Id extends Id { Static_var_decl_list Static_meth_decl_list Inst_var_decl_list Inst_meth_decl_list Costruttore } Cenv = Id -> Cdescr Cdescr = Id * Frame * Menv * Frame* Menv • la relazione di transizione Class_decl * Cenv cdecl Cenv
Dichiarazione di classe Cenv = Id -> Cdescr Cdescr = Id * Frame * Menv * Frame* Menv Class_decl * CenvcdeclCenv r(b) = (_,_,_, jb, mb) mb(b) = (_, cb, _) <svdl, newframe()> vdecl j<ivdl, copy(jb)> vdecl ja <smdl, a, memptyenv()> mdecl m<imdl, a, mb> mdecl ma ________________________________________________ <class a extends b {svdl smdl ivdl imdl c}, r> cdecl cbind(r, a, (b, j, m, ja, mbind(ma, a, ([], cb c, a))))
Dichiarazioni di metodi Method_decl := Id (Idlist) Blocco • guardiamo solo la dichiarazione singola • per una lista di dichiarazioni, si ripete a partire dal risultato precedente Menv = Id -> Mdescr Mdescr = Idlist * Blocco * ( Loc | Id ) • la relazione di transizione Method_decl * Id * Menv mdeclMenv
Dichiarazione di metodo Method_decl := Id (Idlist) Blocco <m (idlist) blocco, c, m>mdeclmbind(m, m, (idlist, blocco, c)) • come già osservato, l’eventuale overriding è realizzato automaticamente dambind
Dichiarazioni di variabili Var_decl := Type Id; • come già osservato, le dichiarazioni non hanno inizializzazione • guardiamo solo la dichiarazione singola • per una lista di dichiarazioni, si ripete a partire dal risultato precedente Frame = Id -> Val Val = (Bool | Int | Loc) • la relazione di transizione Var_decl * Frame vdeclFrame
Dichiarazione di variabile Frame = Id -> Val Val = (Bool | Int | Loc) Var_decl * Frame vdeclFrame <t id , j> vdeclbind(j, id, default(t)) • come già osservato, non ci deve essere overriding • idnon deve essere definito inj • in realtà un Frame è una struttura modificabile • update modifica l’argomento • la funzione default genera un valore di tipo t • 0 se t è intero • null se t è il tipo di un oggetto