AVIS

Da Tesine Linguaggi e Traduttori.

Jump to: navigation, search

Contents

Descrizione introduttiva

Questo progetto è stato realizzato mediante i tool JFlex e CUP con l'obiettivo di fornire delle statistiche sulle donazioni del sangue ricavando i dati da un file di input contenente le informazioni anagrafiche sui donatori, sulle loro donazioni e un linguaggio per determinare alcune proprietà.

Proprietà Benemerenze:

Ad ogni donatore è associata una benemerenza, la quale ne indica i meriti. Le benemerenze AVIS sono calcolate in base alla data di iscrizione e al numero di donazioni effettuate, secondo il seguente standard:

benemerenze.png

Proprietà Donazioni Annuali:

I donatori, a seconda del sesso e dello stato di salute attuale, possono effettuare un massimo di donazioni annuali.


Specifiche di Input:

Le statistiche AVIS vengono generate acquisendo in input le informazioni sui donatori, le loro donazioni e il linguaggio di programmazione per modificare le assegnazioni delle benemerenze e delle donazioni annuali. Il testo di ingresso può essere commentato su una riga attraverso il simbolo // oppure su più righe, racchiudendo il testo da commentare tra i simboli /*...*/. Proprio come nei più diffusi linguaggi di programmazione.


MNTMRZ85P05F158D : Maurizio - Mento - M - 05-09-1985 - 21-02-2007 - A - positivo - 6;
MRCPNT85C14L360F : Marco - Pintabona - M - 10-04-1985 - 22-04-2001 - 0 - negativo - 5;
SLVGNN54D51L219J : Giovanna - Salvo - F - 11-04-1954 - 05-02-1991 - AB - positivo - 9;
BLLCML70E18F205L : Carmelo - Bellantoni - M - 18-05-1970 - 03-11-1998 - B - negativo - 4;
BRNPLA82S56L483O : Paola - Bernardi - F - 16-11-1982 - 25-08-2003 - 0 - negativo - 6;

$$

SLVGNN54D51L219J -> 02-05-1991 - 300,
					12-09-1991 - 320,
					07-05-1992 - 350,
					26-01-1995 - 180,
					15-05-1997 - 300,
					18-12-2000 - 210,
					08-06-2002 - 250,
					02-01-2010 - 270,
					20-02-2010 - 230;
					
MRCPNT85C14L360F -> 24-05-2007 - 250,
					14-04-2008 - 310,
					12-05-2008 - 290,
					22-01-2010 - 300,
					07-02-2010 - 280;
					
MNTMRZ85P05F158D -> 12-03-2007 - 380,
					25-02-2008 - 260,
					28-06-2008 - 340,
					25-11-2008 - 260,
					25-01-2010 - 260,
					15-02-2010 - 270;

BLLCML70E18F205L -> 11-05-2000 - 310,
					25-02-2001 - 260,
					28-06-2002 - 340,
					25-11-2003 - 260,
					23-01-2004 - 260,
					04-03-2004 - 260,
					16-02-2007 - 260,
					22-01-2010 - 270;
					
BRNPLA82S56L483O -> 21-02-2003 - 150,
					14-08-2004 - 210,
					12-05-2006 - 190,
					22-01-2008 - 270,
					06-02-2010 - 280;
					
					
$$


anni1=3;
anni2=5;
donazioni1=3;
donazioni2=10;
data="28-02-2010";
colore="rossa";
sessoM="M";
salute=6;
donazioniAnno1=5;


/*
sezione per il calcolo delle donazioni effettuabili in un anno e delle benemerenze
se non sono rispettati i criteri per un donatore, vengono impostati dei valori di default:
- benemerenza = "nessuno";
- donzazioniAnno = 0;
*/

//criteri calcolo benemerenze

if(calcoloAnno(donatore.DataIscrizione,data)>=1 && donatore.donazioni>=1){
	donatore.benemerenza= "bianca";
}	

if(calcoloAnno(donatore.DataIscrizione,data)>=anni1 && donatore.donazioni>=donazioni1){
	donatore.benemerenza= "verde";
}

if(calcoloAnno(donatore.DataIscrizione,data)>=5 && donatore.donazioni>=5){
	donatore.benemerenza= "blu";
}

if(calcoloAnno(donatore.DataIscrizione,data)>=anni2 && donatore.donazioni>=7){
	donatore.benemerenza= colore;
}

if(calcoloAnno(donatore.DataIscrizione,data)>=7 && donatore.donazioni>=donazioni2){
	donatore.benemerenza= "verde";
}

//criteri calcolo donazioni anno

if (donatore.statoSalute>=salute){
	if(donatore.sesso==sessoM){
		donatore.donazioniAnno=donazioniAnno1;
	}
	else{	
		donatore.donazioniAnno=4;
		
	}
	
}
else{
	if(donatore.sesso=="F"){
		donatore.donazioniAnno=3;
	}
	else{	
		donatore.donazioniAnno=4;
		
	}
}


Il file è composto da tre sezioni:

  • LISTA DONATORI
  • LISTA DONAZIONI PER DONATORI
  • LINGUAGGIO

separate dai caratteri $$

Lista donatori

Ogni donatore è caratterizzato da:

  • Codice Fiscale: costituito da 16 cifre alfanumeriche nella seguente sequenza: 6 lettere - 2 numeri – 1 lettera – 2 numeri – 1 lettera – 3 numeri – 1 lettera.
  • Nome
  • Cognome
  • Sesso: il quale può assumere i valori "M" o "F"
  • Data di Nascita
  • Data di Iscrizione
  • Gruppo Sanguigno: indica il gruppo sanguigno tra i possibili valori "A","B","AB","0"
  • Fattore Rhesus: può assumere i valori "positivo" o "negativo"
  • Stato di salute: indica lo stato di salute attuale del donatore espresso su una scala da 1 a 10

Tutti gli elementi sopra descritti sono separati dal carattere - Ogni elemento della lista è terminato dal carattere ; Tutte le date sono definite nel formato dd-mm-yyyy

Lista donazioni

La lista delle donazioni è caratterizzata da:

  • Codice Fiscale del donatore
  • Insieme di donazioni

Queste informazioni sono separate dal carattere -> e terminate dal carattere ;

L'utente deve aver effettuato almeno una donazione.

L'insieme delle donazioni è a sua volta composto da:

  • Data donazione
  • Quantità donata

separate dal carattere - e terminate dal carattere ,

Linguaggio

Il linguaggio permette di definire le regole per il calcolo delle benemerenze e delle donazioni annuali.

E' consentito inserire delle variabili. Queste possono essere espresse in formato alfanumerico e possono assumere valori numerici o stringhe (indicate tra ""). Esse sono costituite da:

  • Nome variabile
  • Valore

separati dal carattere = e terminati dal carattere ;

E' stato gestito il controllo di visibilità delle variabili in scope diversi. In particolare una variabile è visibile solo all'interno del proprio scope o di scope interni annidati. E' possibile ridefinire la variabile purché all'interno dello stesso scope di definizione.

I costrutti if-else sono like-C, è possibile avere costrutti annidati. Nelle condizioni è possibile utilizzare operatori relazionali (<,>,<=,>=,==) e gli operatori booleani (&&,||,!) secondo i corretti criteri di precedenza.

if!(donatore.donazioni<=7 || donatore.donazioni==donazioni2){
	donatore.benemerenza= "verde";
}

La condizione da verificare può avere come operatore sinistro:

  • donatore.donazioni: attributo del donatore che indica il totale delle donazioni effettuate
  • donatore.statoSalute: attributo del donatore che indica lo stato di salute corrente
  • calcoloAnno(donatore.DataIscrizione,data)

La funzione predefinita calcoloAnno permette di calcolare gli anni trascorsi tra una data variabile e la data di iscrizione del donatore.

L'operatore di destra può essere direttamente un valore oppure il nome di una variabile.


Nelle istruzioni da eseguire all'interno dei costrutti è possibile dichiarare delle variabili ed effettuare delle assegnazioni. Un'assegnazione ha come operatore sinistro:

  • donatore.donazioniAnno: per impostare il numero di donazioni massime effettuabili nell'anno attuale
  • donatore.benemerenze: permette di impostare il grado di benemerenza del donatore

L'operatore destro può essere un valore o una variabile.

Parte destra e parte sinistra di un'assegnazione sono separati dal carattere = e sono terminati dal carattere ;


Logica

La classe Gestore è il cuore del progetto. Essa è caratterizzata dalle seguenti strutture dati:

  • Hashtable hashdonatori: hashtable avente per chiave il Codice Fiscale e per valore un oggetto Donatore, il quale contiene l'anagrafica del donatore e le relative donazioni effettuate
  • Hashtable hashSymbol: hashtable utilizzata per implementare una symbol-table per gestire l'uso di variabili nel linguaggio. La chiave è il nome della variabile, il valore è un oggetto Simbolo contenente il tipo,il valore e il livello di visibilità
  • Statistiche statistiche: oggetto contenente 4 hashtable per effettuare le seguenti statistiche: Numero donatori in base al Sesso; Numero donatori in base al Gruppo Sanguigno/Fattore Rhesus; Numero di donatori in base alle Benemerenze; Quantità di sangue donata in base al Gruppo Sanguigno/Fattore Rhesus
  • Calcolo calcolo: consente di elaborare il costrutto IF-ELSE per ogni singolo donatore

In Gestore vi sono inoltre i metodi che permettono di generare il file di output in html.

Semantica

Lista donatori

I principali elementi della prima sezione sono:

  • listadonatori: lista piena di donatori
  • donatore: elemento della listadonatori, quando riconosciuto esegue un'azione semantica che inserisce i dati nell'oggetto Donatore il quale viene a sua volta inserito nell'hashdonatori e vengono calcolate le statistiche riguardanti il Sesso e il Gruppo/Rhesus

Lista donazioni

Nella seconda sezione gli elementi rilevanti sono:

  • listadonazioni: lista piena di elementi donazione
  • donazione: elemento della listadonazioni
  • elencodonaz: lista piena di donazioni, quando riconosciuta, inserisce una singola donazione nell'hashtable del corrispondente donatore attraverso la chiave CodiceFiscale

Al fine di propagare l'informazione relativa al CodiceFiscale, è stato necessario utilizzare un marker (NT0)

NT0 ::= {: 
RESULT = (String)((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top-4)).value; 
:};

grazie al quale è possibile estrarre dallo STACK il valore del CodiceFiscale in posizione [top-4].

Linguaggio

Gli elementi principali della terza sezione sono:

  • variabilipv: lista piena o vuota di variabili
  • variabili: elemento della lista variabilipv, quando riconosciuto esegue un'azione semantica che controlla se la variabile è già presente nell'hashsymbol. Se non lo è, la inserisce. Altrimenti prima di inserirla controlla che sia stata definita nello stesso scope, in caso contrario lancia un errore
  • calcolo: è un insieme di costrutti IF-ELSE e variabilipv tra loro annidati. Quando riconosciuto, aggiunge il costrutto in una lista
  • istruzione: può essere formata da un insieme di statement o di costrutti IF-ELSE annidati
  • ramoif: è costituito da un singolo blocco IF-ELSE. Incrementa e decrementa un contatore globale rispettivamente all'inizio e alla fine di uno scope. Alla chiusura dello scope provvede oltretutto ad eliminare la variabile dalla symboltable.
  • condizione: è costituita da un singolo statement oppure da una coppia di essi in AND o OR. Essa può anche essere negata mediante simbolo !
  • statement: gestisce tutti i casi delle singole condizioni previste dal linguaggio
  • expr: gestisce i casi di assegnazione previsti

Controlli

Lo scanner identifica errori relativi al formato di tutte le date e dei codici fiscali presenti nelle prime due sezioni.

Nella sezione DONATORI, il parser provvede a controllare le seguenti casistiche:

  • Il sesso può essere M o F
  • Il Gruppo Sanguigno può essere A,B,AB,0
  • Il Fattore Rhesus può assumere i valori "positivo" o "negativo"
  • Lo stato di salute può assumere valori compresi tra 1 e 10

Nella sezione LINGUAGGIO, il parser effettua i seguenti controlli:

  • Variabili usate ma non dichiarate precedentemente oppure dichiarate in scope non accessibili
  • Tipo atteso differente da quello della variabile
  • Formato data non corretto
  • Attributo Sesso non corretto

Nel caso in cui non vengano rispettati i precedenti criteri di controllo, viene richiamata la funzione report_fatal_error(...) la quale provvede a fornire un opportuno messaggio di errore e a terminare l'esecuzione del programma.

Presentazione

L'output generato fornisce un file html conenente grafici realizzati mediante API di (Google Chart) il quale attraverso una richiesta HTTP GET con i parametri forniti sull'URL, genera i grafici desiderati.

grafico.png

Viene inoltre generata una tabella con le informazioni complessive relative ai singoli donatori. Per ogni donatore viene inoltre visualizzato il numero di donazioni possibili effettuabili nell'anno corrente, calcolati secondo i criteri specificati in precedenza.

tabella.png

Compilazione e Sorgenti

Download avis.zip

La compilazione dell'applicativo avviene mediante i seguenti comandi:

jflex scanner.jflex ; java java_cup.Main parser.cup ; javac *.java ; java Main test.txt

NB: In caso di malfunzionamenti del tool JFlex e/o CUP, verificare che l'ambiente di sviluppo sia opportunamente configurato:

Personal tools